Skip to main content
When a single agent calls one tool, identity is simple: the user is in front of the screen, and the tool runs as that user. That model breaks the moment agents start calling other agents and MCP servers on their own. A planning agent calls a research agent, which calls a retrieval agent, which calls three MCP servers. By the third hop, two questions have no clear answer: who is this call really for, and who is allowed to make it. Agent Identity and Governance answers both. It gives every agent a verifiable identity, lets you define who each agent can act for and who is allowed to call it, and carries the original user’s identity across every hop using standard OAuth token exchange — so the MCP server at the end of the chain still enforces the right permissions for the right person.
This page describes the identity and governance model for the MCP Gateway and the Agent Gateway. It builds on concepts you should know first: MCP Gateway authentication, Identity Providers, and Virtual Accounts. Some capabilities described here are rolling out incrementally — talk to your TrueFoundry contact for current availability.

The governance problems

As soon as teams build agents that call other agents and tools on their own, a cluster of governance problems appears that a normal API gateway cannot solve. They are introduced once here and referenced throughout the page.
Teams build agents on whatever they like — LangGraph, CrewAI, Bedrock, a homegrown HTTP service, or a copilot embedded in a SaaS product. Nothing forces them to declare those agents anywhere, so security has no inventory of what exists, who owns it, or what it can reach.Example: A growth team ships a CrewAI agent that queries the Salesforce MCP server with a shared API key. It works, but no central system knows the agent exists — so it can’t be discovered, audited, rate-limited, or shut off.What’s needed is a chokepoint: an agent cannot reach any MCP server or any other agent unless it presents a registered identity. That turns registration into enforcement and gives you an organization-wide inventory of every agent, regardless of the framework it was built on.
When a request reaches an MCP server or an agent, the receiver needs to know whether the caller is a human, a service, or another agent — and which agent. Without a verifiable agent identity you cannot apply policy, attribute usage, or stop an unapproved agent from calling a sensitive tool.
Access to an MCP server is usually decided by the user’s permissions alone. But one user can drive many agents, and they shouldn’t all get the same reach.Example: Jane uses both a support copilot and an engineering agent. On the Jira MCP server you want the support copilot to read issues only, while the engineering agent may read and write — even though both act on Jane’s behalf. With user-only policy, the server just sees “Jane” in both cases and grants Jane’s full permissions regardless of which agent is driving.What’s needed is policy keyed on the (agent, user, tool) combination, so different agents acting for the same user get different, scoped-down access.
The user authenticates to the first agent, but that agent calls a second agent, which calls an MCP server. Unless identity is deliberately carried forward, the MCP server sees nothing (and fails) or a shared service account (and over-grants). Per-user permissions, audit trails, and data isolation all collapse.Example: A planner agent calls a research agent that reads Confluence for Jane. By the second hop “Jane” is gone, so the research agent reads with a service account that can see everyone’s pages — not just Jane’s.
The simplest way to make calls work is to forward one powerful token everywhere — and the fastest way to a breach. A token minted for “Jane, in the planner agent” should not be replayable by a downstream agent against an unrelated MCP server. Tokens must be scoped down at every hop to exactly the audience and permissions required.
When something goes wrong, you need to answer “which agent did this, on whose behalf, through which chain?” and revoke a single agent instantly — without taking everything else down.Example: A retrieval agent starts pulling data it shouldn’t. You want to revoke just that agent’s identity and see every call it made across every chain — not grep through five frameworks’ logs to reconstruct what happened.

Core concepts

Four ideas underpin the whole model. The rest of this page builds on them.
ConceptWhat it is
Agent IdentityA first-class, verifiable identity for an agent — the credential an agent presents so the Gateway knows which agent is calling.
Caller and calleeEvery governed call has a caller (a user, a service/virtual account, or an agent) and a callee (an MCP server or another agent). Policy is defined per callee: who may call it, and for whom.
Acting on behalf of (delegation)An agent rarely acts for itself. It acts on behalf of a user. The model keeps the user identity and the agent identity distinct, and checks that the agent is authorized to act for that user.
Token exchangeAt each hop, the Gateway exchanges the incoming token for a new token scoped to the next callee — preserving the user identity, recording the acting agent, and narrowing audience and scope.

The entities that can make a call

Every governed call is attributed to one of three caller types. This is the same identity vocabulary used across TrueFoundry’s Identity and Access Management.
Caller typeRepresentsToken it presents
UserA human, resolved to a TrueFoundry user (directly or via an Identity Provider JWT).TrueFoundry PAT, or an IdP-issued JWT.
Virtual AccountA service or application with no human behind it.A Virtual Account token, or an IdP JWT that resolves to one.
Agent IdentityA registered agent acting in an automated chain.An Agent Identity token (TrueFoundry-backed or IdP-backed).
The new entity is the Agent Identity. The other two already exist in the platform; agent identity slots in alongside them so that the same access-control engine can reason about all three.

Two registrations: identity and agent

Agents involve two distinct registrations. They answer different questions, and most agents need both.
Diagram showing an agent with an Agent Identity badge listing name, type, and credential on the left, and an Agent Registration document listing who can call, act on behalf of, tools allowed, and url to proxy on the right
Agent IdentityAgent registration
AnswersWho is this agent?What may this agent do, and how is it reached?
Required forEvery agent in your organizationAgents that act on behalf of users and/or expose a proxyable URL
DefinesThe credential the agent presents and how it’s validatedWho may call the agent, whom it may act on behalf of, and (if proxyable) the URL to proxy
Managed underAccess > Agent IdentitiesAgent Registry (extends Remote Agents)
Spec typeagent-identityremote-agent
Agent Identity is the mandatory baseline. Every agent that touches the MCP Gateway or the Agent Gateway must present a registered agent identity. An agent that presents no identity — or one that isn’t registered here — cannot reach any MCP server or any other agent.
Registration is the enforcement point. Because nothing can act without a registered identity, you get an organization-wide inventory of every agent — no matter which framework or platform it was built on — and nothing acts anonymously. This is what closes the shadow-agent gap.
Agent registration adds authorization and routing. Once an agent has an identity, you register the agent itself to declare who may call it, whom it may act on behalf of, and — if it exposes a URL — where the Agent Gateway should proxy it. Agents embedded in third-party software that expose no callable URL still get a registration to carry this policy; they simply omit the proxy URL (see The Agent Gateway). Why two and not one? Identity is authentication — proving which agent is calling — and is universal. The agent registration is authorization and routing — what the agent may do and how it’s reached — and varies by deployment. Splitting them lets one identity be reused across registrations, and lets an agent be governed at the MCP Gateway even when it can never be proxied. The next two sections define each spec in turn.

Agent Identity

An Agent Identity is a registered, verifiable identity for an agent. It exists so that when an agent calls the MCP Gateway or the Agent Gateway, the Gateway can answer “which agent is this?” with cryptographic certainty rather than a guess based on a shared API key. You register agent identities under Access > Agent Identities in the TrueFoundry UI.
New Agent Identity form showing Name, Identity backing type (TrueFoundry Backed or Identity Provider Backed), expiration date, auto rotation, notification, sync to secret manager, tags, and owning team fields

How an agent gets its identity

An agent identity can be backed two ways. The choice determines where the agent’s token comes from and how it is validated.
TrueFoundry issues and signs the token. This is the simplest option for agents you build and run yourself, and for getting started.
  • TrueFoundry mints a token bound to this agent identity.
  • The agent presents that token to the Gateway, which validates it directly.
  • The token can be auto-rotated, expired on a schedule, and synced to your secret manager so the agent can read it at runtime.
Use this when the agent has no existing identity from your IdP, or when you want TrueFoundry to own the credential lifecycle.
An AI agent is, at bottom, an executable piece of software that runs somewhere — a Kubernetes pod, a container, a VM. Every one of those execution environments already has a way to identify the workloads running on it. Rather than minting and distributing a separate static credential for the agent, you can derive its identity from where it runs. This is workload identity, and SPIFFE (with its reference implementation SPIRE) is the open standard for it.SPIFFE fits agents naturally: the agent doesn’t hold a long-lived secret at all. Instead, the platform attests the running workload and issues it a short-lived, automatically rotated credential.
1

The platform attests the workload

SPIRE performs node attestation (proving which machine or node the workload runs on, using evidence like a Kubernetes projected service account token, an AWS instance identity document, or GCP instance metadata) and workload attestation (proving which process is calling, using selectors like the Kubernetes service account, namespace, or container image digest). Only a workload that matches a registered policy gets an identity.
2

SPIRE issues an SVID

The attested workload receives a SPIFFE Verifiable Identity Document (SVID) carrying its SPIFFE ID, for example spiffe://acme.com/ns/agents/sa/research-agent. SVIDs come in three forms:
SVID typeFormatNotes
X.509-SVIDX.509 certificate (SPIFFE ID in the SAN)Used for mTLS; authenticates a channel.
JWT-SVIDSigned JWTBearer token for HTTP/Authorization headers; the practical fit for gateway calls today.
WIT-SVIDKey-bound JWT (WIMSE Workload Identity Token)Emerging IETF WIMSE profile; requires proof-of-possession, so it resists replay through intermediaries like gateways and agent orchestrators.
SVIDs are short-lived (often an hour or less) and rotated by the SPIRE agent before they expire, so the agent never experiences a credential-expiry event.
3

TrueFoundry validates it as an Identity Provider

SPIRE can expose an OIDC-compliant endpoint. Register it as a TrueFoundry Identity Provider (issuer, audiences, JWKS URI) and map the SPIFFE ID claim to an agent identity. The agent then presents its JWT-SVID to the Gateway exactly like any other IdP token — and the same token exchange (ID-JAG / OBO) flows apply on the outbound side.
A common Kubernetes pattern: SPIRE trusts the cluster’s projected service account tokens, exchanges them for SPIFFE credentials, and the agent reads its JWT-SVID from the SPIFFE Workload API at runtime. No secret is ever written to a config file or image.
Two refinements matter once agents run in production:
  • Per-agent vs. per-instance. The agent identity you register is the stable, per-agent principal — what you govern: ownership, policy, inventory, audit. At runtime, each running instance can additionally receive a short-lived, attested credential (a SPIFFE SVID, for example) bound to that stable identity. The per-agent identity gives you policy and inventory; the per-instance credential gives you attestation and a surgical kill switch — revoke one rogue instance without invalidating the whole fleet. This directly addresses the kill-switch problem.
  • Sender-constrained tokens. A bearer token can be replayed by anyone who steals it — a real risk for agents that can be prompt-injected or memory-exfiltrated. Where the target supports it, bind the token to the sender with mTLS (RFC 8705) or DPoP (RFC 9449), or use a key-bound WIT-SVID, so a stolen token is useless without the private key. Where it doesn’t, terminate at the Gateway, which holds the stronger credential boundary on the agent’s behalf.

Agent identity spec

The form maps to a YAML spec you can apply directly (the Apply using YAML option on the form). The example below shows both backing types and the delegation policy.
type: agent-identity
name: research-agent
description: Identity for the research agent used across the org
owned_by_team: data-platform
identity:
  type: truefoundry-backed
  expiration_date: "2026-12-31"        # optional; omit for a non-expiring token
  auto_rotation:
    enabled: true
    rotate_before: 7d                  # rotate this long before expiry
  notification:
    enabled: true
  sync_to_secret_manager:
    enabled: true
    secret_store: tfy-secret-store     # a connected secret store
    path: agents/research-agent/token
tags:
  owner: data-platform
  env: production
FieldRequiredDescription
typeYesAlways agent-identity.
nameYesUnique, human-readable name. Used in policies, traces, and audit logs.
descriptionNoShort description of the agent’s purpose.
owned_by_teamYesThe team that owns and can manage this identity.
identity.typeYestruefoundry-backed (TrueFoundry issues the token) or idp-backed (your IdP issues it).
identity.expiration_dateNoExpiry for a TrueFoundry-backed token. Omit for a non-expiring token governed by rotation.
identity.auto_rotationNoRotate the token automatically before expiry. Recommended for production.
identity.notificationNoNotify owners ahead of expiry or rotation events.
identity.sync_to_secret_managerNoStore the token in a connected secret store so the runtime can read it directly.
identity.providerIdP onlyThe configured Identity Provider that validates the agent’s JWT.
identity.subject_claim / identity.subjectIdP onlyThe JWT claim and value that resolve the token to this agent identity.
identity.spiffeNoBind the identity to a SPIFFE workload identity (trust_domain, spiffe_id, svid_type). See the Workload identity with SPIFFE and SPIRE section.
tagsNoKey-value pairs to categorize the identity.
An agent identity carries no authorization policy — it only establishes who the agent is. What an agent may do (whom it can act for, who can call it) is defined on its agent registration, below.

Agent registration

The agent registration is the governance and routing record for an agent. Where the agent identity says who the agent is, the registration says what it may do and how it’s reached. It extends the existing Remote Agent registration.
SettingDescription
Associated agent identityThe agent identity this agent presents when it, in turn, calls other agents or MCP servers downstream.
Who can call this agentThe callers permitted to invoke it: users, virtual accounts, and other agents (by their agent identity).
On whose behalf the agent can actThe users and teams this agent may act for when it makes downstream calls. This is the delegation allow-list, enforced at both the Agent Gateway and the MCP Gateway.
URL to proxyThe endpoint the Gateway forwards requests to. Omit it for agents that can’t be proxied (a governance-only registration — see The Agent Gateway).

Agent spec

type: remote-agent
name: research-agent
description: Researches topics and returns summaries
owned_by_team: data-platform
# Identity this agent presents on its own downstream calls
identity: agent-identity:research-agent
# Who is allowed to call this agent
callers:
  users:
    - jane@acme.com
  teams:
    - support
  virtual_accounts:
    - data-pipeline
  agents:
    - agent-identity:planner-agent     # another agent, by its identity
# Whom this agent may act on behalf of when it makes downstream calls
act_on_behalf_of:
  users:
    - jane@acme.com
  teams:
    - support
# Endpoint the Agent Gateway proxies to. Omit for a governance-only
# registration (an embedded agent with no callable URL).
url: https://research-agent.internal.acme.com
framework: a2a                         # a2a | custom (only when url is set)
agent_card_path: /.well-known/agent-card.json
# How the Gateway authenticates to the remote agent endpoint
auth:
  type: token_exchange                 # token_exchange | token_passthrough | header
FieldRequiredDescription
typeYesremote-agent for an agent registration.
nameYesUnique name for the agent in the registry.
descriptionYesShort description of the agent’s purpose.
owned_by_teamYesThe team that owns and can manage the registration.
identityYesThe agent identity this agent presents on its own downstream calls.
callersYesWho may invoke this agent: users, teams, virtual_accounts, and agents (by identity).
act_on_behalf_ofNoThe users and teams this agent may act on behalf of, enforced before any delegated token is minted. Required if the agent acts for users.
urlNoThe endpoint the Gateway proxies to. Omit for agents that can’t be proxied (governance-only).
frameworkurl onlya2a or custom. See Supported Frameworks.
agent_card_pathA2A onlyPath to the agent card JSON (default /.well-known/agent-card.json).
auth.typeNoOutbound auth to the remote endpoint: token_exchange (mint a scoped delegated token), token_passthrough, or header.
The decision logic that uses this registration lives in The Agent Gateway.

Token exchange: the mechanism that carries identity

Everything in this page rests on one mechanism: token exchange. Rather than forwarding the same powerful token everywhere, the Gateway trades the incoming token for a new token at each hop. The new token is scoped to exactly the next callee and records who is acting for whom. Token exchange is defined by RFC 8693. The Gateway (or your IdP, acting as a Security Token Service) takes a subject_token and returns a new token for a target audience and scope.
Diagram of token exchange at a gateway: an incoming credential for user Jane bound for Agent A enters the gateway, which performs a token exchange and emits a smaller token for user Jane with actor Agent A, audience Jira, and scope read. A legend notes the subject is preserved and the scope is narrowed

Delegation vs. impersonation

RFC 8693 supports two semantics. The distinction matters for agents, and TrueFoundry uses delegation by default.
ImpersonationDelegation
Resulting token says”I am the user.""I am acting on behalf of the user.”
Acting party visible downstream?No — indistinguishable from the user.Yes — recorded in an act (actor) claim.
Audit trailThe agent disappears.Full chain: user + each acting agent.
TrueFoundry defaultUsed by default, so every hop is attributable.
With delegation, the issued token is a composite token: its subject (sub) stays the original user, and an act claim names the agent acting for them. Chained calls produce nested act claims — a complete, verifiable record of who touched the request.
{
  "sub": "user-jane@acme.com",
  "aud": "https://mcp.internal/jira",
  "scope": "issues.read issues.write",
  "act": {
    "sub": "agent:research-agent",
    "act": {
      "sub": "agent:planner-agent"
    }
  }
}

Who is allowed to act for whom

Token exchange is only safe if the authorization server refuses exchanges that aren’t permitted. Two claims govern this:
  • may_act — present on the user’s token (or in policy). It declares which actors are allowed to act on behalf of this subject. The Gateway checks this before issuing a delegated token.
  • act — present on the issued token. It records which actor actually performed the exchange.
In TrueFoundry, the “may act” decision is configuration you define: each agent registration declares the users and teams it may act on behalf of, and each callee declares which agents may call it. The Gateway enforces both before any token is minted.
Authorize on the current actor, audit on the full chain. The nested act claims are an informational history for forensics. Authorization decisions are made on the current actor plus the subject plus policy context — not on the historical chain. Keep the whole chain for audit; decide on the top of it.
On the horizon — verifiable actor chains. In RFC 8693 today, the prior actors in a nested act chain are informational — a downstream service can’t independently verify them cryptographically. The IETF SPICE actor-chain draft profiles a signed commitment per hop so each step is provable, enabling forensic reconstruction of “agent A called B called C” without trusting any single intermediary. As this matures, TrueFoundry’s exchange can emit verifiable chains with no change to how you write policy.

Authority reduction, not amplification

A common worry with delegation is that an agent might request more than the user granted — privilege escalation by the back door. It can’t. A token exchange never grants authority based on what is asked for; it grants the intersection of three independent limits:
  1. what the user is allowed to do,
  2. what the agent is allowed to do, and
  3. what the target (MCP server or agent) is willing to accept.
Requesting a scope is only an input to that decision. If the user lacks the permission, or the agent isn’t permitted to act with it, or the target won’t accept it, the exchange fails. Each hop therefore produces a token that is more constrained than the last — narrower scope, a single audience, and a recorded actor. This cuts both ways, which is the point: an agent may hold a capability the user never had (and the user context still bounds it), and a user may hold a permission the agent should never exercise (and the agent’s allow-list still bounds it). Delegation makes those boundaries explicit instead of silently inherited.

How this maps to your IdP

The same RFC 8693 foundation is profiled differently by each identity provider. TrueFoundry adapts to whichever your agent identity is backed by.
CapabilityGeneric (RFC 8693)Okta — ID-JAG / Cross-App AccessMicrosoft Entra — On-Behalf-Of
Underlying standardToken Exchange (RFC 8693)RFC 8693 + JWT Bearer (RFC 7523)RFC 8693 profiled as OBO
Number of exchanges12 (get ID-JAG, then redeem it)2 (blueprint token, then OBO)
Intermediate tokenNew access tokenID-JAG (urn:ietf:params:oauth:token-type:id-jag)Federated/exchange token, then resource token
Grant to resourcetoken-exchangeurn:ietf:params:oauth:grant-type:jwt-bearerjwt-bearer with requested_token_use=on_behalf_of
Carries acting agentact claimID-JAG audienced to the resource’s authorization serveract / xms_act_fct actor-facet claims
Best forInternal services that trust the Gateway as STSCross-app and cross-vendor access brokered by the enterprise IdPMicrosoft-centric estates with Entra agent identities
Cross-App Access (XAA), built on the Identity Assertion JWT Authorization Grant draft, lets the enterprise IdP broker access between two applications without a per-user consent click. It is a two-step exchange:
  1. The caller presents an identity assertion (an ID token, or a refresh token) to the IdP’s token endpoint with requested_token_type=urn:ietf:params:oauth:token-type:id-jag and audience set to the target resource’s authorization server. The IdP returns an ID-JAG — a short-lived, signed grant that names the user and is audienced to the resource.
  2. The caller redeems the ID-JAG at the resource’s authorization server using grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer. The resource server applies its own policy and returns an access token.
The resource authorization server stays in control — it decides whether to honor the ID-JAG and what scopes to grant. This is the right model when the inbound token is an IdP token and the outbound call needs a token the MCP server’s own authorization server trusts. There is an MCP-specific profile of XAA for exactly this case.
Microsoft Entra Agent ID profiles RFC 8693 as the On-Behalf-Of flow with an agent-aware twist. An agent identity blueprint (the parent registration) holds the credential and declares delegated permissions; agent identities are children of that blueprint.
  1. The client authenticates the user and obtains a user access token audienced to the blueprint.
  2. The agent identity calls Entra’s token endpoint with grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer, requested_token_use=on_behalf_of, the user token as the assertion, and its own client assertion.
Entra validates the audience chain and returns a downstream token whose subject is still the user, with actor-facet claims (act, xms_act_fct) identifying the agent. The result is the same composite shape: user as subject, agent as actor.
If a target MCP server or agent cannot participate in token exchange, TrueFoundry falls back gracefully:
  • TrueFoundry-issued scoped token — when the agent identity is TrueFoundry-backed, the Gateway itself acts as the STS and mints a scoped, delegated token audienced to the next callee. This brings the benefits of exchange even when your IdP isn’t in the path. Prefer this.
  • Token passthrough — forward the validated inbound token unchanged (see Outbound Authentication). A last resort, only when the downstream server validates the same IdP and you accept the broader scope.
The MCP authorization spec prohibits token passthrough: an MCP server must reject any token not minted for its exact audience, precisely to stop a server being used as an open proxy into other systems. Wherever the target enforces this (any OAuth 2.1-compliant MCP server), use a scoped exchanged token — not passthrough.

The MCP Gateway with agent identity

The MCP Gateway already separates inbound authentication (who is calling the Gateway) from outbound authentication (how the Gateway authenticates to the MCP server). Agent identity extends the inbound side: the caller can now be an agent, a user, or both at once, and access control reasons about all of them.

What you configure per MCP server

On each MCP server you grant access to two kinds of principals, and you can scope at the tool level.
SettingDescription
Which agents can access this serverThe agent identities permitted to call this MCP server.
Which users/teams can access this serverThe users, teams, or virtual accounts permitted (the existing collaborators model).
Tool-level scopeRestrict an agent (or user) to a subset of tools — for example, an agent gets only 3 of the server’s 10 tools. Enforced by the Gateway before the call reaches the server.
Tool-level scoping is also how a Virtual MCP Server works — you can curate a tool subset and grant agents access to that instead of the full server.

How the Gateway decides

When a request reaches an MCP server, the Gateway resolves whatever identities are present, then authorizes in a fixed order. The key checks, in plain terms:
  1. If an agent identity is present, the Gateway first checks the agent is allowed to access this MCP server. If a user identity is also present, it additionally checks the agent is allowed to act on behalf of that user. Only then does it mint a delegated token (user as subject, agent as actor) scoped down to this MCP server and the allowed tools.
  2. If only a user identity is present (some agents today have no way to pass an agent identity), the Gateway checks whether the user can access the MCP server and scopes the token accordingly. This keeps existing per-user flows working and gives a clean upgrade path to add agent identity later.
  3. Tool scope is applied as part of minting the token, so the MCP server only ever receives a token good for the tools the caller is allowed to use.

Runtime flow

The sequence below shows an agent calling an MCP server on behalf of a user, with the inbound IdP token exchanged for a scoped downstream token.
The outbound step reuses the existing outbound authentication models. Token exchange (ID-JAG / OBO / TrueFoundry-issued scoped token) is the path used when the MCP server expects a delegated token. Token passthrough, OAuth2, and static credentials remain available for servers that need them.

The Agent Gateway

The Agent Gateway is to agents what the MCP Gateway is to tools: a proxy layer that governs calls into registered agents, using the agent registration you defined earlier. One difference shapes the whole design.
Not every agent can be proxied. Agents embedded inside third-party software (a copilot inside a SaaS product, for example) expose no callable URL — you can only reach them through that product’s own interface. For those, TrueFoundry governs their outbound calls to MCP servers (via the MCP Gateway), not the inbound call to the agent. The Agent Gateway governs agents that do expose a URL: ones you build yourself, or remote agents you register.

How the Gateway decides

When a request hits the Agent Gateway, it first derives the caller entity, then authorizes based on what the caller is. In plain terms:
  1. Derive the caller. A user or virtual account is authorized directly against the callee agent’s “who can call me” list, and its identity is forwarded.
  2. If the caller is another agent, validate its token and resolve the agent identity. Check the caller agent is allowed to call this agent.
  3. If a user identity is also present — either as an OBO/delegated token or as a separate user identity alongside the agent identity — check the caller agent may act on behalf of that user. If yes, the Gateway exchanges the token to a delegated token audienced to the callee agent: user as subject, caller agent as actor, scope narrowed.
  4. The downstream agent then continues the chain. It attaches its own agent identity for the next hop while carrying the user identity forward, so the original user remains the subject all the way down.

Runtime flow

Policies at both gateways

The allow-lists on registrations (who can call, whom to act for, which tools) cover most needs. For finer-grained, attribute-based rules, both gateways can evaluate a policy language on every request — before any token is minted or forwarded. This is where conditions like “only during business hours” or “only for low-risk tools” live, and it’s the same engine at the MCP Gateway and the Agent Gateway. Cedar is the primary supported policy language. Each request is expressed as a principal, action, resource, context (PARC) tuple that maps cleanly onto the identities this page already resolves:
Cedar elementWhat it carries at the gateway
principalThe caller — an agent identity, user, or virtual account.
actionThe operation — mcp:callTool, agent:invoke, etc.
resourceThe callee — an MCP server, a specific tool, or an agent.
contextEverything else — the user being acted for, the actor chain, time, request risk, source IP, environment.
Cedar is default-deny, and forbid always overrides permit, so guardrails are easy to express. A few examples of what becomes possible:
// The support copilot may only READ Jira, even when acting for any user.
permit (
  principal == AgentIdentity::"support-copilot",
  action == Action::"mcp:callTool",
  resource == Tool::"jira/issues.read"
);

// Any agent may write to Jira only on behalf of the engineering team,
// and only during business hours.
permit (
  principal,
  action == Action::"mcp:callTool",
  resource == Tool::"jira/issues.write"
)
when {
  context.on_behalf_of in Team::"engineering" &&
  context.time.hour >= 9 && context.time.hour < 18
};

// Block destructive tools for any agent more than two hops deep in a chain.
forbid (
  principal,
  action == Action::"mcp:callTool",
  resource in ToolGroup::"destructive"
)
when { context.actor_chain.length > 2 };
The first two policies show the (agent, user, tool) differentiation called out in the governance problems: the same user driving different agents gets different reach. The third shows a chain-depth guardrail that an allow-list alone can’t express.
Policy evaluation composes with, and runs alongside, the existing MCP guardrails (pre- and post-tool checks for content, PII, and the like). Cedar decides whether a call is allowed; guardrails inspect the content of the request and response. If your organization standardizes on a different engine such as OPA/Rego, the same PARC inputs apply.

End-to-end: agent → agent → MCP

This is where the model pays off. A planner agent, acting for user Jane, calls a research agent, which calls a Jira MCP server. Across the chain the subject stays Jane, the actor chain grows, and the audience and scope narrow to exactly the next callee. How the entry agent (the planner) is reached depends on whether it exposes a proxyable URL — so there are two cases. The downstream hops are governed identically in both; only the first hop differs.
End-to-end diagram: User Jane to Agent Gateway to Planner Agent to Agent Gateway to Research Agent to MCP Gateway to Jira MCP. Token cards above each hop show user Jane preserved throughout, with actor and audience claims added and scope narrowing to read by the final hop

Case A — the entry agent is proxied

The planner exposes a URL and is registered on the Agent Gateway, so even Jane’s first call is proxied and governed. Every hop flows through a gateway.

Case B — the entry agent is embedded (not proxyable)

The planner is a copilot inside a third-party product (or the user’s IDE) with no callable URL. Jane interacts with it through that product’s own interface, so the first hop cannot be proxied. The planner still presents its registered agent identity on its outbound calls, so every hop it makes downstream is governed exactly as in Case A.
The only difference between the two cases is the first hop. In Case A the Agent Gateway also governs the inbound call into the planner; in Case B the planner is reached through its host product, and governance starts at the planner’s first outbound call. For embedded agents, the planner’s act_on_behalf_of policy is still enforced — it just comes from a governance-only agent registration rather than a proxied one.
How the token transforms along the governed hops (identical in both cases):
HopSubject (sub)Actor chain (act)Audience (aud)Scope
Jane → PlannerJanePlanner(full user context)
Planner → ResearchJanePlannerResearch Agentnarrowed to Research
Research → Jira MCPJaneResearch → PlannerJira MCP Serverissues.read only
Two properties hold at every hop, and together they are the whole point of the design:
  • The user is never lost. Jira sees that this request is for Jane, so it returns only Jane’s issues and enforces Jane’s permissions.
  • Every actor is recorded and every token is minimal. The actor chain is a complete audit trail, and no token is ever broader than the single next callee needs.

Governance and observability

Because every hop is an explicit, authorized exchange, the Gateway has a full record of each one.

Per-hop attribution

Every call records the subject (user), the acting agent, and the full actor chain — visible in traces.

Least-privilege tokens

Tokens are scoped to a single callee and a minimal tool/scope set, so a leaked token has limited blast radius.

Central policy

“Who can call what” and “who can act for whom” live in one place, enforced at the Gateway before any token is minted.

Lifecycle control

Agent identity tokens support expiry, auto-rotation, notifications, and secret-manager sync from the registration form.

Portable trust across clouds

Minting an agent identity is no longer the hard part — every major platform can do it. Microsoft Entra Agent ID roots agents in Entra tenant objects, AWS Bedrock AgentCore issues first-party workload identities, and Google Cloud issues SPIFFE-based principals. The genuinely unsolved industry problem is portable trust: each hyperscaler’s trust model stops at its own perimeter. An AWS workload token isn’t valid against a Google resource, and dropping a static cross-cloud key back into an agent throws away the secretless posture that made the model safe in the first place. This is exactly the gap a neutral gateway closes. Because TrueFoundry sits in front of MCP servers and agents rather than inside any one cloud’s identity plane, it can act as the broker that:
  • accepts whatever identity each agent already has — an Entra agent identity, an AWS workload identity, a Google/SPIFFE principal, or a TrueFoundry-issued token;
  • validates it through a configured Identity Provider and resolves it to a single agent identity;
  • performs the token exchange to mint a token the next callee trusts, preserving sub and the act chain across the trust-domain boundary; and
  • keeps the policy and audit schema in one place, independent of any single vendor’s logs — so your trust anchor survives a cloud migration.
The practical pattern is a “portable trust sandwich”: vendor-neutral workload identity (SPIFFE or OIDC federation) at the bottom, RFC 8693 token exchange preserving subject and actor in the middle, sender-constrained tokens on top, and a gateway minting just-in-time downstream credentials wherever a system can’t consume those semantics directly.

Putting it together

You want to…Use
Give an agent a verifiable identityRegister an Agent Identity (TrueFoundry-backed or IdP-backed).
Let an agent call MCP servers for a userGrant the agent access on the MCP server, allow it to act for the user, and let the Gateway exchange the token.
Restrict an agent to specific toolsApply tool-level scope on the MCP server.
Let one agent call anotherRegister the callee on the Agent Gateway and add the caller agent to its “who can call me” list.
Carry the user across many hopsRely on delegation — the subject stays the user, the actor chain grows.
Express attribute-based rules (time, risk, chain depth)Write Cedar policies evaluated at both gateways.
Integrate with Okta or EntraUse an IdP-backed identity; TrueFoundry uses ID-JAG or OBO accordingly.

Standards this builds on

The model is an assembly of open standards rather than a proprietary scheme, which is what lets it span IdPs, clouds, and frameworks.
StandardRole here
OAuth 2.0 Token Exchange (RFC 8693)The core delegation mechanism — subject_token, actor_token, and the act / may_act claims.
JWT Profile for OAuth (RFC 7523)JWT bearer grant used to redeem an ID-JAG at the resource’s authorization server.
Identity Assertion JWT Authorization Grant (ID-JAG / XAA)Okta’s cross-app access profile for brokering access through the enterprise IdP.
Entra On-Behalf-OfMicrosoft’s agent-aware OBO profile of token exchange.
SPIFFE / SPIREAttested workload identity (X.509-SVID, JWT-SVID) for deriving an agent’s credential from its runtime.
WIMSE / WIT-SVIDKey-bound workload tokens that resist replay through intermediaries.
SPICE actor chainEmerging draft for cryptographically verifiable actor chains across domains.
mTLS (RFC 8705) · DPoP (RFC 9449)Sender-constrained tokens so a stolen token can’t be replayed.
A2AAgent-to-agent transport, discovery, and signed agent cards.
CedarAttribute-based authorization policy evaluated at both gateways.

FAQ

If a user identity is present, the Gateway can treat the request as a plain user call: as long as the user is allowed to access the MCP server or agent, it proceeds and the token is scoped to the user — with no agent-level attribution. This is a transitional path for agents that can’t yet present an identity. Once the agent starts presenting a registered agent identity, the agent-level checks and actor attribution turn on automatically, with no change to the downstream server. You can require an agent identity (and disable the user-only fallback) where you want strict enforcement.
Delegation, by default. The downstream service always sees both the user (as subject) and the acting agent (in the act claim), so every call is attributable. Impersonation hides the agent and is avoided unless a downstream server genuinely cannot understand a composite token.
No. With a TrueFoundry-backed agent identity, the Gateway acts as the Security Token Service and mints scoped, delegated tokens itself. Okta (ID-JAG) and Entra (OBO) are used when you want your IdP to broker cross-application access centrally.
Token passthrough forwards the same token unchanged — simple, but the token isn’t scoped down and carries no actor chain. Token exchange mints a new token per hop, scoped to the next callee and recording the acting agent. The MCP authorization spec actually prohibits passthrough (a server must reject tokens not minted for its exact audience), so prefer exchange everywhere; reserve passthrough for trusted internal servers that validate the same IdP and don’t enforce audience.
You usually can’t proxy the inbound call to them, since they have no callable URL. Instead, govern their outbound calls to MCP servers through the MCP Gateway. The agent presents its agent identity (and the user identity, if available) to the MCP Gateway, and all the access checks and scoping in this page apply.