{"slug": "bedrock-knowledge-base-acls-on-agentcore-gateway-dont-let-the-llm-pick-the-user", "title": "Bedrock Knowledge Base ACLs on AgentCore Gateway: Don’t Let the LLM Pick the User", "summary": "AWS published a November 12, 2026 post detailing how to stop Bedrock Managed Knowledge Base search tools reached through Model Context Protocol (MCP) on AgentCore Gateway from leaking documents across tenants, after finding that the userContext field becomes model-writable when exposed as a tool parameter. The fix stacks deterministic identity injection, Cedar policy in AgentCore, and a knowledge base resource policy: a Cognito access token carries a verified email claim, a JWT authorizer validates it at the gateway, and an interceptor Lambda always overwrites arguments.userContext on tools/call, with the resource policy allowing only the gateway execution role to call bedrock:Retrieve. AWS warns that Managed Knowledge Base does not authenticate end users and trusts the userContext passed to it, so the calling application, not the model, must set identity.", "body_md": "**AWS's [November 12, 2026 post](https://aws.amazon.com/blogs/machine-learning/fine-grained-access-control-for-amazon-bedrock-managed-knowledge-base-tools/?ref=explainx) tackles a failure mode every enterprise RAG agent will hit: when search tools ride **Model Context Protocol (MCP)** through [AgentCore Gateway](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/gateway.html?ref=explainx), 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.**\n\nThe 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.\n\nAgents that act on your behalf need rules. [See how explainx helps secure your agents →](https://explainx.ai/agentbeam?src=blog_note)\n\n## TL;DR\n\n| Layer | Mechanism | \n|---|---|\n| Identity | **Cognito** access token with**email claim** (pre token generation Lambda) | \n| Gateway auth | **JWT authorizer** on AgentCore Gateway | \n| Primary | **Request interceptor** overwrites`userContext.userId` with verified email | \n| Secondary | **Policy in AgentCore** denies mismatch between injected ID and JWT email tag | \n| Resource | **Knowledge base resource policy** allows only gateway execution role`bedrock:Retrieve` | \n| Retrieval | **ACL awareness** filters chunks per ingested document ACLs | \n\n## Threat model: why MCP changes RAG security\n\nClassic 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:\n\n- User says **\"search as [user-b@example.com](mailto:user-b@example.com)\"**\n- Model hallucinates the wrong mailbox\n- **Indirect injection** in retrieved text steers identity fields\n\n[Managed Knowledge Base](https://docs.aws.amazon.com/bedrock/latest/userguide/knowledge-bases.html?ref=explainx) **does not authenticate end users**. It **trusts** the `userContext` you pass. Gateway docs explicitly warn the **calling application** must set it — not the model.\n\nAWS'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.\n\nZero-trust access gates representing verified identity injected before Bedrock Knowledge Base ACL search\n\nKnowledge base library cards illustrating per-user document ACL metadata for Managed Knowledge Base search\n\n## Architecture flow\n\nThe post's numbered flow:\n\n1. User signs in; **pre token generation** adds verified**email** to access token.\n2. Strands agent on **AgentCore runtime** forwards token in`Authorization` on MCP calls —**no ACL logic in agent code** .\n3. Gateway **JWT authorizer** validates signature, expiry, client ID.\n4. **Interceptor Lambda** on`tools/call` decodes email and**always overwrites**`arguments.userContext` .\n5. **Policy in AgentCore** Cedar rule permits retrieve only when injected user matches JWT email tag.\n6. Connector target calls **`Retrieve`** or**` AgenticRetrieveStream`** with gateway IAM role.\n7. **KB resource policy** rejects principals other than that role.\n8. **ACL awareness** returns only permitted chunks.\n\nTwo MCP tools ship from the connector: **Retrieve** (hybrid search) and **AgenticRetrieveStream** (multi-subquery agentic retrieval). Both support the same `userContext` override pattern.\n\n## Code patterns worth copying\n\n**Expose `userContext` in parameterOverrides** even though clients should not set it — the interceptor needs a schema slot:\n\n- `path: $.userContext`\n- description notes gateway sets identity\n\n**Interceptor fail-closed behavior** (from AWS sample logic):\n\n- Reject non-object JSON-RPC bodies (no batch arrays).\n- Ignore non-`tools/call` methods (pass through).\n- Deny when token lacks email claim.\n- **Always overwrite** client-supplied`userContext` .\n\n**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.\n\n## Identity provider edge cases\n\nAWS documents alternatives if you cannot customize access tokens:\n\n- **GetUser** (needs broad`aws.cognito.signin.user.admin` scope)\n- **userInfo** endpoint (needs`openid` ; breaks some admin auth flows)\n- **ID token in separate header** (interceptor must fully validate JWT fields and match`sub` to access token)\n\nFor **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.\n\nSample pool disables self-sign-up and makes email **immutable** for exact ACL matching — enterprise realistic, consumer SaaS harder.\n\n## Comparison to earlier AWS RAG posts\n\nexplainx.ai covered [agentic retrieval CDK blueprints](https://explainx.ai/blog/bedrock-managed-knowledge-base-agentic-retrieval-agentcore-gateway-cdk-guide-2026) and [Web Answer GA](https://explainx.ai/blog/amazon-bedrock-agentcore-web-answer-ga-single-tool-call-cited-answers-gateway-setup-guide-2026). November 12 is the **authorization chapter**: same gateway surface, explicit **defense in depth** for **shared assistants**.\n\nPair with [Agent Registry push sync](https://explainx.ai/blog/aws-agent-registry-push-sync-cloudtrail-eventbridge-2026) when your problem is **stale tool schemas**, not **horizontal privilege escalation**.\n\n## Deploy path\n\nPrerequisites: 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.\n\nVerification script expectations: user A sees dept A plan plus shared notice; user B sees dept B plan plus notice; cross-department plans stay invisible.\n\n## Builder checklist\n\n1. **Never** let prompts mention`userContext` — remove it from tool descriptions clients could echo.\n2. Add **Policy in AgentCore** even when you trust your interceptor — matches[China NDRC lifecycle safety thinking](https://explainx.ai/blog/china-ndrc-ai-safety-standards-full-lifecycle-wang-ruomeng-bloomberg-what-is-confirmed-2026) at a micro scale: independent guardrails.\n3. **Resource policy** the KB if any principal in the account has stray`bedrock:Retrieve` .\n4. Log **tool names and replacement flags** , not bearer tokens — AWS sample logging guidance.\n5. Re-run ACL ingestion when HR changes department IDs in metadata files.\n\n## Metadata ACL example (S3 per document)\n\nAWS 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.\n\nIngestion 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.\"\n\n## AgenticRetrieveStream versus Retrieve\n\n| API | When to use | ACL note | \n|---|---|---|\n| **Retrieve** | Single-hop Q&A | Sets `userContext` once | \n| **AgenticRetrieveStream** | Multi-subquery research | Same override; higher token burn | \n\nDisable `generateResponse` in the sample when the **Strands agent** should write the final narrative — prevents **double answer composition** and makes citations auditable in agent traces.\n\n## Cedar policy mental model\n\nThink 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.\n\n## Testing matrix before production\n\n| Test | Expected | \n|---|---|\n| User A queries dept B plan | Zero chunks | \n| User B queries dept B plan | Chunks returned | \n| Remove interceptor | Policy should still deny spoofed ID if policy attached | \n| Call KB directly with admin principal | Resource policy should deny unless break-glass role documented | \n\nAdd **red-team prompts** that instruct the model to ignore ACL — success means **interceptor still wins**.\n\n## Multi-tenant SaaS variant\n\nIf 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.\n\n## Performance considerations\n\nInterceptor 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.\n\n## Comparison to OpenSearch fine-grained access\n\nTeams 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**.\n\n## Training developers on the threat model\n\nRun a 30-minute internal workshop:\n\n1. Demonstrate **prompt injection** attempting to set`userContext` in the client payload.\n2. Show interceptor logs replacing the field.\n3. Show Policy deny when JWT email differs.\n4. Show resource policy block on direct SDK call.\n\nEngineers who see the failure modes once stop trying to \"fix\" ACL issues in **system prompts** alone.\n\n## Incident response\n\nIf ACL leakage is suspected:\n\n1. Pull **CloudTrail** for`bedrock:Retrieve` outside gateway role.\n2. Compare **interceptor logs** (tool name, replaced flag) to**Policy deny metrics** .\n3. Rotate **Cognito app clients** if JWT theft suspected.\n4. Re-ingest documents whose metadata ACLs were wrong.\n\n## FAQ deep dives\n\n**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.\n\n**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.\n\n**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.\n\n**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.\n\n## Shared assistant product implications\n\nEnterprises 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**.\n\n## Cost of getting ACL ingestion wrong\n\nRe-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.\n\nRecord **ingestion job IDs** in change tickets so security can trace which ACL version was live when an incident occurred.\n\n## Related on explainx.ai\n\n*Cedar policy snippets, model IDs, and Cognito plan requirements reflect the November 12, 2026 AWS blog and sample repository.*", "url": "https://wpnews.pro/news/bedrock-knowledge-base-acls-on-agentcore-gateway-dont-let-the-llm-pick-the-user", "canonical_source": "https://explainx.ai/blog/aws-bedrock-kb-acl-agentcore-gateway-interceptor-2026?utm_source=rss&utm_medium=feed&utm_campaign=blog", "published_at": "2026-11-12 00:00:00+00:00", "updated_at": "2026-11-12 16:54:01.282329+00:00", "lang": "en", "topics": ["ai-agents", "ai-safety", "agent-protocols", "large-language-models", "ai-infrastructure"], "entities": ["AWS", "Amazon Bedrock", "AgentCore Gateway", "Managed Knowledge Base", "Model Context Protocol", "Cognito", "Cedar", "Strands"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/bedrock-knowledge-base-acls-on-agentcore-gateway-dont-let-the-llm-pick-the-user", "markdown": "https://wpnews.pro/news/bedrock-knowledge-base-acls-on-agentcore-gateway-dont-let-the-llm-pick-the-user.md", "text": "https://wpnews.pro/news/bedrock-knowledge-base-acls-on-agentcore-gateway-dont-let-the-llm-pick-the-user.txt", "jsonld": "https://wpnews.pro/news/bedrock-knowledge-base-acls-on-agentcore-gateway-dont-let-the-llm-pick-the-user.jsonld"}}