fix(gateway/fgac): filter semantic search results by scope + add search tests - #1987
Open
rhbelson wants to merge 2 commits into
Open
fix(gateway/fgac): filter semantic search results by scope + add search tests#1987rhbelson wants to merge 2 commits into
rhbelson wants to merge 2 commits into
Conversation
added 2 commits
August 23, 2026 18:53
…ch tests
The FGAC tutorial documents three access-control patterns, including
pattern 2: 'Semantic search with FGAC (RESPONSE interceptor) - filter
search results so users only see tools they have access to'. But the
RESPONSE interceptor only filtered tools/list shapes (result.tools /
result.structuredContent.tools), and the demo (invoke.py) plus the
README Test Cases table exercised only tools/call and tools/list - no
semantic-search coverage, despite the README promising it.
Changes:
- RESPONSE interceptor Lambda (fgac-interceptors-stack.yaml): also filter
the semantic-search response, whichever shape the gateway emits -
result.tools, result.structuredContent.tools, and a JSON string in
result.content[*].text carrying {"tools": [...]}. Non-JSON text content
passes through untouched. So x_amz_bedrock_agentcore_search results are
now scope-filtered like tools/list.
- invoke.py: add Test 8 (search with getOrder scope -> only getOrder) and
Test 9 (search with full scope -> multiple tools), plus an
extract_search_tools() helper tolerant of all three response shapes.
- README: add rows 8 and 9 to the Test Cases table so the documented tests
match the demo and the promised pattern 2.
…ltering Extracts the inline RESPONSE-interceptor Lambda from the CloudFormation template and exercises lambda_handler against synthetic gateway events — no AWS, no live gateway, no network. Asserts scope-based filtering across all three response shapes (result.tools, structuredContent.tools, and the semantic-search content[*].text JSON payload): a limited scope keeps only the authorized tool, a full scope keeps all, non-JSON text is untouched, and a missing token fails safe. 5/5 pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Fine-Grained Access Control (FGAC) tutorial documents three access-control patterns, including pattern 2:
…but that pattern was neither enforced nor tested:
tools/listresponse shapes (result.tools/result.structuredContent.tools). Semantic-search results (x_amz_bedrock_agentcore_search) were not filtered, so a scoped user could discover tools they cannot access.invoke.py) and the README Test Cases table covered onlytools/call(Tests 1–5) andtools/list(Tests 6–7). There was no semantic-search test, despite the README promising pattern 2.This is the gap reported during Diving Deep with AgentCore Workshop (v2) prep.
Changes
RESPONSE interceptor Lambda (
cloudformation/fine-grain-access-control/fgac-interceptors-stack.yaml): filter the semantic-search response in addition totools/list. It now scope-filters every shape the gateway may emit:result.toolsresult.structuredContent.toolsresult.content[*].textcarrying{"tools": [...]}Non-JSON text content passes through untouched. Handling all three shapes makes the filter robust to the response format the gateway returns for search.
Demo (
scripts/fine-grain-access-control/invoke.py): add Test 8 (search withgetOrderscope → onlygetOrderreturned) and Test 9 (search with full scope → multiple tools), plus anextract_search_tools()helper tolerant of all three response shapes.README (
04-advanced-concepts/fine-grain-access-control/README.md): add rows 8 and 9 to the Test Cases table so the documented tests match the demo and the promised pattern 2.Testing / verification note
Inline Lambda code and
invoke.pywere validated to parse/compile. I was not able to run this against a live FGAC gateway, so the interceptor change is written defensively to cover whichever response shape the gateway emits forx_amz_bedrock_agentcore_search, and is verified by inspection rather than a live run. A maintainer with a standing FGAC gateway should confirm the exact search-response shape and that Tests 8–9 pass end-to-end before merge.