AWS's November 12, 2026 post tackles a failure mode every enterprise RAG agent will hit: when search tools ride Model Context Protocol (MCP) through AgentCore Gateway, the userContext field becomes model-writable — so Department B's business plan can leak into Department A's answer if the LLM or a prompt injection sets the wrong identity.
The fix is not a smarter system prompt. AWS stacks deterministic identity injection, Cedar policy, and resource-based KB denial so trusted code — not the model — decides who searches.
Agents that act on your behalf need rules. See how explainx helps secure your agents →
TL;DR #
| Layer | Mechanism |
|---|---|
| Identity | Cognito access token withemail claim (pre token generation Lambda) |
| Gateway auth | JWT authorizer on AgentCore Gateway |
| Primary | Request interceptor overwritesuserContext.userId with verified email |
| Secondary | Policy in AgentCore denies mismatch between injected ID and JWT email tag |
| Resource | Knowledge base resource policy allows only gateway execution rolebedrock:Retrieve |
| Retrieval | ACL awareness filters chunks per ingested document ACLs |
Threat model: why MCP changes RAG security #
Classic apps bind search scope in application code after authentication. Agentic apps let the model choose tools and arguments. If userContext is exposed as a tool parameter, these attacks share one shape:
- User says "search as user-b@example.com"
- Model hallucinates the wrong mailbox
- Indirect injection in retrieved text steers identity fields
Managed Knowledge Base does not authenticate end users. It trusts the userContext you pass. Gateway docs explicitly warn the calling application must set it — not the model.
AWS's fictional AnyCompany scenario (departments A and B plus company-wide notice) is the same multi-tenant SaaS problem with customer IDs swapped for emails.
Zero-trust access gates representing verified identity injected before Bedrock Knowledge Base ACL search
Knowledge base library cards illustrating per-user document ACL metadata for Managed Knowledge Base search
Architecture flow #
The post's numbered flow:
- User signs in; pre token generation adds verifiedemail to access token.
- Strands agent on AgentCore runtime forwards token in
Authorizationon MCP calls —no ACL logic in agent code . - Gateway JWT authorizer validates signature, expiry, client ID.
- Interceptor Lambda on
tools/calldecodes email andalways overwritesarguments.userContext. - Policy in AgentCore Cedar rule permits retrieve only when injected user matches JWT email tag.
- Connector target calls
Retrieveor**AgenticRetrieveStream** with gateway IAM role. - KB resource policy rejects principals other than that role.
- ACL awareness returns only permitted chunks.
Two MCP tools ship from the connector: Retrieve (hybrid search) and AgenticRetrieveStream (multi-subquery agentic retrieval). Both support the same userContext override pattern.
Code patterns worth copying #
Expose userContext in parameterOverrides even though clients should not set it — the interceptor needs a schema slot:
path: $.userContext- description notes gateway sets identity
**Interceptor fail-closed behavior** (from AWS sample logic):
- Reject non-object JSON-RPC bodies (no batch arrays).
- Ignore non-`tools/call` methods (pass through).
- Deny when token lacks email claim.
- Always overwrite client-supplied
userContext.
Cognito caveat: access tokens lack email by default. Essentials or Plus plan required for access-token customization V2_0. Lite plan tokens without email cause interceptor and policy to deny every call — a deployment footgun AWS calls out explicitly.
Identity provider edge cases #
AWS documents alternatives if you cannot customize access tokens:
- GetUser (needs broad
aws.cognito.signin.user.adminscope) - userInfo endpoint (needs
openid; breaks some admin auth flows) - ID token in separate header (interceptor must fully validate JWT fields and match
subto access token)
For Microsoft Entra ID, optional email claims may be mutable; Microsoft advises against authorization on unverified email. AWS tells you to maintain ACL sync when emails change. Sample pool disables self-sign-up and makes email immutable for exact ACL matching — enterprise realistic, consumer SaaS harder.
Comparison to earlier AWS RAG posts #
explainx.ai covered agentic retrieval CDK blueprints and Web Answer GA. November 12 is the authorization chapter: same gateway surface, explicit defense in depth for shared assistants.
Pair with Agent Registry push sync when your problem is stale tool schemas, not horizontal privilege escalation.
Deploy path #
Prerequisites: Node 22+, uv, CDK from sample-managed-knowledge-base-patterns repo ( agentcore-access-control directory). Stack provisions Cognito users user-a / user-b, three S3 documents with metadata ACLs, gateway, interceptor, policies, CloudFront UI.
Verification script expectations: user A sees dept A plan plus shared notice; user B sees dept B plan plus notice; cross-department plans stay invisible.
Builder checklist #
- Never let prompts mention
userContext— remove it from tool descriptions clients could echo. - Add Policy in AgentCore even when you trust your interceptor — matchesChina NDRC lifecycle safety thinking at a micro scale: independent guardrails.
- Resource policy the KB if any principal in the account has stray
bedrock:Retrieve. - Log tool names and replacement flags , not bearer tokens — AWS sample logging guidance.
- Re-run ACL ingestion when HR changes department IDs in metadata files.
Metadata ACL example (S3 per document) #
AWS shows metadata beside dept-a-plan.txt restricting retrieval to user-a@example.com. At scale you migrate from per-object metadata to prefix-level ACL files when document counts explode — same pattern as enterprise DMS migrations.
Ingestion must re-sync when HR changes departments; otherwise ACL-aware search returns empty for legitimate movers — a usability failure that looks like "RAG is broken."
AgenticRetrieveStream versus Retrieve #
| API | When to use | ACL note |
|---|---|---|
| Retrieve | Single-hop Q&A | Sets userContext once |
| AgenticRetrieveStream | Multi-subquery research | Same override; higher token burn |
Disable generateResponse in the sample when the Strands agent should write the final narrative — prevents double answer composition and makes citations auditable in agent traces.
Cedar policy mental model #
Think of Policy in AgentCore as API gateway authorizer part two: even if application code mis-sets a header, Cedar denies. AWS compares principal email tag to injected userContext.userId string equality — normalize case and Unicode in IdP configs or false denies appear.
Testing matrix before production #
| Test | Expected |
|---|---|
| User A queries dept B plan | Zero chunks |
| User B queries dept B plan | Chunks returned |
| Remove interceptor | Policy should still deny spoofed ID if policy attached |
| Call KB directly with admin principal | Resource policy should deny unless break-glass role documented |
Add red-team prompts that instruct the model to ignore ACL — success means interceptor still wins.
Multi-tenant SaaS variant #
If customers share one assistant but have separate IdPs, you need per-tenant Cognito pools or custom JWT issuers per customer — each gateway instance or issuer-aware authorizer. The sample is single-tenant AnyCompany; do not copy ARNs blindly.
Performance considerations #
Interceptor adds one Lambda hop per tools/call. For high QPS chat, watch concurrency limits and cold starts. Batch agents doing AgenticRetrieveStream may need provisioned concurrency on the interceptor.
Comparison to OpenSearch fine-grained access #
Teams on legacy OpenSearch FGAC will recognize the pattern: trusted identity injection beats hoping the LLM sets X-User-Id. Managed Knowledge Base pushes that responsibility to gateway operators, not prompt engineers.
Training developers on the threat model #
Run a 30-minute internal workshop:
- Demonstrate prompt injection attempting to set
userContextin the client payload. - Show interceptor logs replacing the field.
- Show Policy deny when JWT email differs.
- Show resource policy block on direct SDK call.
Engineers who see the failure modes once stop trying to "fix" ACL issues in system prompts alone.
Incident response #
If ACL leakage is suspected:
- Pull CloudTrail for
bedrock:Retrieveoutside gateway role. - Compare interceptor logs (tool name, replaced flag) toPolicy deny metrics .
- Rotate Cognito app clients if JWT theft suspected.
- Re-ingest documents whose metadata ACLs were wrong.
FAQ deep dives #
Can we skip Policy in AgentCore and rely on the interceptor alone? AWS positions Policy as defense in depth. Single-component systems fail when Lambda deployments roll back or ARNs detach. If your threat model includes malicious insiders with gateway admin, keep Cedar.
Does this pattern work with non-Cognito IdPs? Yes, with engineering: customize JWT authorizer discovery document, map claims to email, and test immutable email assumptions. Entra optional claims require extra verification steps AWS documents candidly.
Will Agentic agents try to exfiltrate via creative tool args? Yes — that is why userContext is overwritten, not merged. Red-team with adversarial prompts weekly during rollout.
How does this relate to IAM Identity Center workforce users? Workforce SSO often yields different token shapes than Cognito native users. Pilot with one IdP before merging subsidiaries.
Shared assistant product implications #
Enterprises want one HR bot for all employees. ACL-aware Managed Knowledge Base plus gateway injection is AWS's answer for shared runtime, partitioned corpora. Product managers should still communicate "the bot sees only what you may access" in UX copy — technical enforcement does not replace expectation management.
Cost of getting ACL ingestion wrong #
Re-ingesting large S3 corpora after metadata fixes incurs Bedrock ingestion charges and downtime windows. Treat document ACL files as version-controlled code with PR review like application IAM roles.
Record ingestion job IDs in change tickets so security can trace which ACL version was live when an incident occurred.
Related on explainx.ai #
Cedar policy snippets, model IDs, and Cognito plan requirements reflect the November 12, 2026 AWS blog and sample repository.