Live Nov 18 · Cohort 3Nov 18, 19:00 MSK — free hands-on AI agents live workshop · Live Cohort 3 starts Nov 23Join Nov 18 Live →Cohort 3 (Nov 23)
ReleaseInsight · On RadarAWS Machine Learning Blog→ original

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
AWS shows how to stop an LLM agent from reading other people's documents: the gateway injects userContext
Source: AWS Machine Learning Blog. Collage: Hamidun News.
Listen to article
Article Fact Sheet & Key Figures
ParameterDetails
Primary sourceAWS Machine Learning Blog ↗
Editor-in-Chief
Key metric #1A Lambda request interceptor always overwrites userContext using the token
Key metric #2A Cedar policy blocks the request if userId does not match the email in the JWT
ACL mistakes do not raise errorsdocuments silently drop out of the results

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.

Story

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.

ZK
Zhemal Khamidun — CPO at Alpina Digital, product manager of AlpinaGPT. Building AI products since 2019. Hamidun News is a pet project that grew into a production aggregator with 6,000+ readers.
✦ Unified AI Workspace · Nomad

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.

Try Nomad AI →Launch Nomad Agent
What do you think?
Loading comments…