AWS shows how to stop an LLM agent from reading other people's documents: the gateway injects userContext
When a corporate agent queries a shared knowledge base, "on whose behalf to search" is often passed as a tool argument, and the LLM makes up the value. One prompt injection, and an employee in department A gets department B's plan. AWS recommends not trusting the model: the AgentCore gateway overwrites userContext from a verified JWT, and the knowledge base filters documents by ACL.
AI-processed from AWS Machine Learning Blog; edited by Hamidun News
Imagine an internal assistant used by the whole company. An employee in department A asks: "Compare my department's plan with the general notice and show me the lagging initiatives." The agent formulates its own search queries and digs through documents until it has gathered enough information. An employee in department B asks the same question. If the search is not tied to a specific person, one department's business plan can easily end up in another department's answer. In a multi-tenant SaaS, the same thing happens with customer companies, and the cost of a mistake there is higher.
The AWS Machine Learning Blog has published a walkthrough of how to close this hole in a setup combining Amazon Bedrock Managed Knowledge Base and AgentCore Gateway.
Why agents are harder than a regular application
In a classic application, the code itself knows who is logged in and searches with that user's permissions. In an agent, the LLM calls the tool, and it also chooses the arguments. If a search tool has a parameter for "on whose behalf to search," the model will fill it in. A user saying "search as user-b," a model error, or an indirect prompt injection in a retrieved document is enough for the agent to search under someone else's identity.
Managed Knowledge Base has an ACL awareness mode. When data is ingested, the knowledge base records document permissions, and at search time it returns only what the user from userContext.userId (their email) is allowed to see. But the knowledge base does not authenticate users itself; it trusts whatever it receives. And when it is published as an MCP tool through AgentCore Gateway, userContext becomes an ordinary argument built by the model. Neither the gateway nor the knowledge base checks that the value belongs to the person who is logged in.
Four layers: two primary and two safety nets
The principle is simple: the LLM does not decide who the user is. Trusted code decides that, based on data verified by the identity provider. A request flows like this:
- The user signs in through Amazon Cognito and receives a JWT. A pre token generation Lambda trigger adds an email claim to the token.
- The agent forwards the token in the Authorization header, and the gateway's authorizer verifies the signature, expiry, and client ID.
- The request interceptor, a Lambda on the gateway, extracts the email from the verified token and overwrites userContext in every tools/call invocation. Whatever the client or the model sends, the knowledge base receives the real user's email. Batches and invalid request bodies are rejected on a fail-closed basis.
- Policy in AgentCore uses a Cedar policy to check that userContext.userId matches the email from the JWT. If it does not, the request is rejected.
- The knowledge base's resource-based policy denies search to everyone except the gateway's execution role.
The first two layers (the interceptor and the ACL) are the primary defense. For requests through the gateway they are sufficient, provided no one else can access the knowledge base directly. The Cedar policy and the resource-based policy are there in case of a bug in the interceptor or a stray principal with bedrock:Retrieve permission in the same account. The agent itself, built on Strands Agents, contains no access logic: it simply passes the token along.
Pitfalls
- S3 ACLs are defined by a global file per prefix or a metafile per document. A document without an ACL simply will not make it into the index.
- Permission changes take effect only after the next sync: S3 has no real-time check.
- ACL mistakes do not throw exceptions; documents quietly vanish from the results. Verify this with tests.
- A request without userContext will not return documents from an ACL-enabled source, but documents from a source without ACLs will be visible to everyone.
- Customizing the access token in Cognito requires the Essentials or Plus plan. On Lite, the email will not appear in the token.
- For the interceptor to be able to write userContext, it must be exposed in the tool schema via parameterOverrides, even if clients never set it.
What to do about it
The takeaway is broader than a single AWS product. Any parameter that determines identity or permissions should not be an argument filled in by the model. Inject it at the gateway or tool-server level from a verified token, and add an independent check on top. If you are building a multi-tenant agent, check whether you are handing the model a tenant_id or user_id.
A ready-made CDK example is in the sample-managed-knowledge-base-patterns repository, in the agentcore-access-control directory. A caveat: this is a design for the AWS stack, and on other platforms you will have to reproduce it yourself.
- Nov 12, 2026Jensen Huang steps down as Nvidia CEO: company loses $1.4 trillion in two weeks
- Nov 12, 2026AWS shows how 100% retrieval precision can hide an AI agent's failure
- Nov 12, 2026AWS connects three AI agents across two accounts using A2A
- Nov 12, 2026AWS Quick Gets Six Agents for Product Managers: From Customer Complaints to a Spec
Key Questions Answered
Why agents are harder than a regular application?
In a classic application, the code itself knows who is logged in and searches with that user's permissions. In an agent, the LLM calls the tool, and it also chooses the arguments. If a search tool has a parameter for "on whose behalf to search," the model will fill it in. A user saying "search as user-b," a model error, or an indirect prompt injection in a retrieved document is enough for the agent to search under someone else's identity. Managed Knowledge Base has an ACL awareness mode.
What are the key details on Four layers: two primary and two safety nets?
The principle is simple: the LLM does not decide who the user is. Trusted code decides that, based on data verified by the identity provider. A request flows like this: The user signs in through Amazon Cognito and receives a JWT. A pre token generation Lambda trigger adds an email claim to the token. The agent forwards the token in the Authorization header, and the gateway's authorizer verifies the signature, expiry, and client ID.
What are the key details on Pitfalls?
S3 ACLs are defined by a global file per prefix or a metafile per document. A document without an ACL simply will not make it into the index. Permission changes take effect only after the next sync: S3 has no real-time check. ACL mistakes do not throw exceptions; documents quietly vanish from the results. Verify this with tests. A request without userContext will not return documents from an ACL-enabled source, but documents from a source without ACLs will be visible to everyone.
Test Frontier LLMs & Autonomous Agents in One Workspace
Run Claude Opus 5.5, GPT-6, Gemini 3.1, and DeepSeek side-by-side in Nomad AI (nomadnet.ai) — unified model routing, deep research, and multimodal workflows under one subscription.
The AI world, distilled — once a week
Seven stories that actually mattered, hand-picked. No noise, no reposts, no press releases.
Done! Check your inbox for a confirmation.