Agentic AI delegation patterns
Agents may need to delegate on behalf of users. It's important to have least-privilege delegation, and we show patterns to achieve this.
Agents delegate on behalf of their users. The permissions granted to the agent for delegation represent an isolation boundary which must be considered along with the isolation boundary of the agent runtime.
It is common for a multi-tenant application to call services it owns and passes the user's authentication token for delegation with each service call. An agent may invoke tools it has never seen before, or hand off to a marketplace agent. Passing your user's authentication token may result in wider permissions than what you intended.
Foundational isolation concepts
I will assume that you're familiar with foundational tenant isolation strategies on AWS . Implementing user authentication using JSON Web Tokens (JWT) to pass tenant metadata (context), attribute-based access control (ABAC) with tenant-scoped IAM policies, and the use of a Token Vending Machine (TVM) mechanism upstream to vend tenant-scoped credentials in exchange for a user authentication token.
This can be implemented within agent code, but is commonly implemented at an API layer as applications scale. This separates multi-tenant security from business logic, delivering tenant context and credentials to the agent alongside the request, and provides a shared layer where caching can mitigate latency introduced by the TVM mechanism.

Figure 1: The isolation boundary encapsulates the agent's business logic and the tenant resources it accesses. The TVM sits at the ingress — validating the JWT and vending a tenant-scoped credential before the request reaches the agent.
The permissions of the credentials used to access resources on-behalf-of a tenant describe the strength of isolation:
- Enforced isolation restricts the credential to one tenant, so an isolation failure affects one tenant. Credential usage can be audited using AWS CloudTrail .
- Filtered isolation uses a credential scoped for multiple tenants combined with filtering in the application, for example a SQL clause "WHERE tenant_id=tenant001". An isolation failure can affect multiple tenants.
Use enforced isolation when achievable and required. Some data services support enforced isolation directly via IAM condition keys: credentials can be restricted to one tenant on a shared resource.
Use filtered isolation when enforced isolation isn't supported by the resource type and the use case can tolerate the wider blast radius. For example, tenants within the same company with shared data ownership.
Confused-deputy risk on tenant ID
Picture a financial services agent. The user prompt: "Summarise our latest deals." The agent calls a tool. The tool returns deals — for the wrong tenant. Buried in the agent code, someone read tenant_id from a metadata field on the request body instead of from the validated JWT. The deal pipeline of one bank is now in the chat window of another.this is a weak example, the idea is to pass the tenant context in a secure and reliable way. JWT is probably the safest, but not sure the only way and depends on where the agent lives and if oauth based auth is even feasible.
This is the confused-deputy risk: a less-privileged input (the user's prompt) influences a more-privileged decision (which tenant's resources the agent accesses). Tenant ID must come from a validated proof of authentication (JWT).
Use transitive session tags when using ABAC to make the tenant_id tag immutable if the credentials are used to role-chain IAM sessions.
When AssumeRoleWithWebIdentity is not the right pattern
The AssumeRoleWithWebIdentity+ JWT tag claim pattern is sometimes promoted as a simpler alternative to a TVM because it natively extracts JWT claims for use in IAM policy. It has a structural caveat: per the AWS Security Token Service (AWS STS) API documentation , this API does not require AWS credentials to call. The JWT signature and trust policy aud/sub conditions are the only gate, so a leaked JWT becomes a direct credential-mint vector from any machine.
For agents running on AWS infrastructure, default to AssumeRole + Tags via a TVM so that the agent's IAM execution role becomes a defense layer. Reserve AssumeRoleWithWebIdentity for clients with no AWS credentials, such as mobile apps, browser single-page applications (SPAs), and customer-premises bring-your-own (BYO) agents. Pair it with strict aud/iss trust policy conditions, short JWT time-to-live (TTL) values, and disciplined non-logging.
Multi-tenant agent delegation patterns
Delegation adds different patterns for TVM implementation., but isolating multi-tenant agents is still a simple pattern. Each compute runtime, agent or tool, has its own isolation boundary with a tenant-scoped IAM policy. But now we introduce the isolation boundary of the credential used for delegation.
You can only pass the user JWT for delegation if you implicitly trust the runtime which will use it. If you call outside your trust boundary, you must create a tenant-scoped delegation credential. This untrusted boundary has its own implementation of the TVM mechanism, the only difference being what type of delegation credential is passed.

Figure 2: One mechanic, three boundaries. Each boundary's TVM yields a scoped credential plus a delegation credential. For trusted boundaries (1, 2) the delegation credential is the user JWT. The untrusted boundary (3) exchanges the user JWT for a downscoped credential — a rescoped JWT for delegated 3rd-party code, an OAuth token for external APIs. The delegation credential is what tools and 3rd-party code carry when they call back into your internal services on behalf of the user.
Agent runtime - trusted code execution
The agent runtime is a trusted boundary you control. It is responsible for inbound authentication, mapping a user to an agent session, and tenant resources (agent memory, model access, retrieval-augmented generation (RAG)) directly accessed by the agent.
Runtime isolation with session mapping
Session mapping can be used as an additional isolation mechanism if the agent runtime infrastructure supports it. For example, Amazon Bedrock AgentCore Runtime has a dedicated microVM instance per session which can be an isolated runtime for your tenants. Constructing a session ID using isolation dimensions (tenant_id,user_id) will yield a runtime instance per tenant or user respectively.
When using inbound authentication with JWT on AgentCore Runtime with session mapping for isolation, it is only possible to achieve filtered isolation. Similar to theAssumeRoleWithWebIdentity pattern, a valid JWT can manually invoke any session ID, so you need to validate that the JWT is allowed to call that particular session.
This is filtered isolation: the credential and runtime are shared, and the application validates that the caller's JWT matches the requested session before proceeding.
To achieve enforced isolation with session mapping on AgentCore Runtime, the practical approach is an inbound interceptor that enforces session mapping and invokes the agent using IAM credentials with Signature Version 4 (SigV4) signing restricted to the interceptor. The JWT is still used for inbound authentication via the interceptor, and can be passed through to the runtime via an HTTP request header .

Figure 3: Enforced session mapping. The isolation boundary contains the interceptor (ingress) and the runtime. The runtime trusts only the interceptor's IAM identity, so a leaked JWT cannot invoke another tenant's session directly.
Implicitly trusted tools - passing the user JWT for delegation
Agent tools can be isolated using the same TVM pattern with a centralized tools gateway. If we implicitly trust these tools, then the user JWT can be passed for delegation.
On Amazon Bedrock AgentCore Gateway , this is implemented via an interceptor AWS Lambda function configured with JWT-based inbound authorization . The interceptor receives a validated identity object on the request context, derives tenant context, and rewrites the request before forwarding.

Figure 4: The trusted tools isolation boundary contains the AgentCore Gateway (ingress) and the tools themselves. The REQUEST interceptor validates the JWT, derives tenant context, and sets gateway-owned headers — tools downstream trust only what the gateway produced.
A centralized gateway is only safe if the values it sets cannot be overridden by client-supplied values. On AgentCore Gateway, interceptor-supplied headers take precedence , so a client cannot forge x-tenant-id past the interceptor. Whatever gateway you use, the gateway must be the single trust boundary; everything downstream trusts what it produced.
Untrusted tools - delegation without the user JWT
Delegation may be needed outside an implicit trust boundary: you may want to restrict the internal services which a tool can call, delegate to third-party agents or Model Context Protocol (MCP) tools, or even run bring-your-own code. Passing the user JWT here leaks authority; the JWT is an unauthenticated AWS STS credential-mint vector forAssumeRoleWithWebIdentity, and a bearer token for any OAuth-protected API that trusts its issuer. Untrusted callees should never see the user JWT directly, so we need a least-privilege delegation credential.
Rescoping the user JWT
The simplest approach is to reduce the scope of the user JWT. The identity provider remains the same, so you can keep the same isolation mechanism used in the trusted boundary.
This is implemented in OAuth 2.0 Token Exchange (RFC 8693) if your identity provider supports it. If not, as is the case with Amazon Cognito , then a custom security token service can be built using Amazon API Gateway and AWS Lambda to issue a new token with reduced scope.
When rescoping the user JWT, use the scope claim to define permissions, and act to represent the actor acting on behalf of the tenant. Subsequent re-scoping will yield a chain of actors which can be used for audit.
This approach is explained in depth in Implement on-behalf-of token exchange for multi-tenant agents with Amazon Bedrock AgentCore Gateway .
Creating a passport JWT
If you want full control over claim shape and lifetime, then you can run your own issuer and mint a passport JWT which replaces the user JWT for delegation. The approach is the same as rescoping the user JWT, with act and scope defining each isolation boundary, except that the passport JWT can now be used in lieu of the user JWT.
One option is to allow user and passport JWTs to be used interchangeably for authentication and delegation, but this yields two issuer audit trails and increased complexity. Instead, it is common to solely use the passport JWT, with the user JWT only used at ingress for vending the passport JWT as shown below.

Figure 5: The user JWT terminates at ingress. Everything downstream, including delegation, uses passport JWTs minted by your own issuer with rescoping performed for untrusted isolation boundaries.
External OAuth-protected resources
Calling external OAuth-protected resources requires a credential broker that stores tokens keyed on (workload_identity,user_identity). User identity comes from the verified inbound JWT's iss and sub claims. The broker enforces that another user's tokens cannot be retrieved by an agent acting for a different user.
On Amazon Bedrock AgentCore Identity , the Token Vault , enforces the (workload, user) binding. On other platforms, you can build equivalent functionality with AWS Secrets Manager and a custom token broker, but the (workload, user) binding then depends on your code being correct.
MCP tools specifically
MCP is the emerging standard for agent-to-tool integration. Tools may be hosted by third parties — for example, a vendor's MCP server for their API. Treat every MCP tool as untrusted by default. Issue a passport credential or rely on vault-bound OAuth tokens if delegation is required. Never propagate the user JWT itself.
Auditing tenant credentials
To prove your compliance, you need to walk back every credential and every call. The multi-boundary pattern means the answer lives in multiple places which need to be joined to cleanly show an audit trail.
CloudTrail records AssumeRole calls and AWS API access, but reconstructing "which tenant was this agent acting on behalf of at the moment it called this tool" requires combining logs from multiple isolation boundaries, enriched with tenant and session identifiers.
The compliance-shaped question is direct: for tenant X over the last 90 days, show every credential issued on their behalf and every API call made with those credentials. Two levels of audit answer it, depending on how deep you have to go.
Tenant-level — "did anything touch tenant X's data?" Reuse session_id as the role session name when each TVM calls AssumeRole + Tags. If session_id is already a composite of isolation dimensions like tenant_id and user_id, as in the runtime session mapping isolation pattern above, it appears in userIdentity.arn on every CloudTrail event made with that credential, and one query joins every IAM-mediated call back to a tenant. If your session_id doesn't carry tenant identity, prefix it withtenant_idso the join works without cross-referencing another log. Vault-bound OAuth tokens and third-party MCP calls bypass IAM, so emit tenant_id and session_id in those outbound application logs too.
Actor-level — "which agent, sub-agent, or third-party tool was the proximate cause?" This is where the JWT act chain earns its keep, and where you have to build a bridge yourself, because the chain lives in JWTs and CloudTrail cannot see claim contents. Three log streams stitch it together:
- JWT issuance and exchange logs at every STS that mints or exchanges a token, recording jti, parent_jti, sub, tenant_id, and the full act chain. The actor lineage on disk.
- TVM bridge logs at every isolation boundary, recording (jti consumed, role_session_name produced). Without this, an AssumeRole event has no link back to the JWT that authorized it.
- Outbound application logs for vault-bound OAuth and MCP calls, tagged with jti alongside the tenant identifiers. CloudTrail does not see these calls.
Land all of it in one query-able store — CloudTrail for the IAM hops, JWT logs for the actor chain, application logs for everything outside IAM. CloudTrail Lake , an Amazon S3 data lake, or your existing observability platform.
In short: tenant-level audit travels in the role session name, actor-level audit travels in the JWT chain, and the TVM bridge log is what lets you walk between them.
Conclusion
The foundational pattern — validated JWT in, tenant-scoped credential out, audit at every hop — is still the right mechanic. What multi-tenant agents add is the number of hops, and the variety of trust boundaries those hops cross. Apply the pattern at each one:
- Agent runtime — validate the JWT at ingress, mint a tenant-scoped credential via AssumeRole + Tags. Reserve AssumeRoleWithWebIdentity for clients that have no AWS credentials.
- Trusted tools — centralize credential exchange in a gateway interceptor; rely on gateway-set values taking precedence over client-supplied ones.
- Untrusted tools — rescope the user JWT, create passport credentials, or use vault-bound OAuth tokens. Never the user JWT.
As MCP and agent-to-agent interoperability mature, passport credentials and vault-bound tokens become the default credential shapes — not the exception. Building the right isolation pattern for your use-case will keep your customers secure with a clear audit trail.
Next steps
The following resources include a hands-on workshop where you can implement these patterns in a working environment, along with additional blog posts that go deeper on specific aspects of tenant isolation.
- Try the Hands-on multi-tenant agents workshop.
- Discover the implemenation at Implementing tenant isolation using Agents for Amazon Bedrock in a multi-tenant environment .
- Dive deep in an example of Secure shared multi-tenant agent memory namespaces using AgentCore Memory .
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article