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.Shadow agents: no central registry or enforcement
Shadow agents: no central registry or enforcement
No way to identify the caller
No way to identify the caller
One-size-fits-all MCP policies
One-size-fits-all MCP policies
Lost identity across hops
Lost identity across hops
Over-broad tokens
Over-broad tokens
No unified audit or kill switch
No unified audit or kill switch
Core concepts
Four ideas underpin the whole model. The rest of this page builds on them.| Concept | What it is |
|---|---|
| Agent Identity | A first-class, verifiable identity for an agent — the credential an agent presents so the Gateway knows which agent is calling. |
| Caller and callee | Every 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 exchange | At 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 type | Represents | Token it presents |
|---|---|---|
| User | A human, resolved to a TrueFoundry user (directly or via an Identity Provider JWT). | TrueFoundry PAT, or an IdP-issued JWT. |
| Virtual Account | A service or application with no human behind it. | A Virtual Account token, or an IdP JWT that resolves to one. |
| Agent Identity | A registered agent acting in an automated chain. | An Agent Identity token (TrueFoundry-backed or IdP-backed). |
Two registrations: identity and agent
Agents involve two distinct registrations. They answer different questions, and most agents need both.
| Agent Identity | Agent registration | |
|---|---|---|
| Answers | Who is this agent? | What may this agent do, and how is it reached? |
| Required for | Every agent in your organization | Agents that act on behalf of users and/or expose a proxyable URL |
| Defines | The credential the agent presents and how it’s validated | Who may call the agent, whom it may act on behalf of, and (if proxyable) the URL to proxy |
| Managed under | Access > Agent Identities | Agent Registry (extends Remote Agents) |
Spec type | agent-identity | remote-agent |
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.
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-backed
- Identity Provider-backed
- 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.
Workload identity with SPIFFE and SPIRE
Workload identity with SPIFFE and SPIRE
The platform attests the workload
SPIRE issues an SVID
spiffe://acme.com/ns/agents/sa/research-agent. SVIDs come in three forms:| SVID type | Format | Notes |
|---|---|---|
| X.509-SVID | X.509 certificate (SPIFFE ID in the SAN) | Used for mTLS; authenticates a channel. |
| JWT-SVID | Signed JWT | Bearer token for HTTP/Authorization headers; the practical fit for gateway calls today. |
| WIT-SVID | Key-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. |
TrueFoundry validates it as an Identity Provider
Per-agent vs. per-instance identity, and sender-constrained tokens
Per-agent vs. per-instance identity, and sender-constrained tokens
- 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.Agent identity field reference
Agent identity field reference
| Field | Required | Description |
|---|---|---|
type | Yes | Always agent-identity. |
name | Yes | Unique, human-readable name. Used in policies, traces, and audit logs. |
description | No | Short description of the agent’s purpose. |
owned_by_team | Yes | The team that owns and can manage this identity. |
identity.type | Yes | truefoundry-backed (TrueFoundry issues the token) or idp-backed (your IdP issues it). |
identity.expiration_date | No | Expiry for a TrueFoundry-backed token. Omit for a non-expiring token governed by rotation. |
identity.auto_rotation | No | Rotate the token automatically before expiry. Recommended for production. |
identity.notification | No | Notify owners ahead of expiry or rotation events. |
identity.sync_to_secret_manager | No | Store the token in a connected secret store so the runtime can read it directly. |
identity.provider | IdP only | The configured Identity Provider that validates the agent’s JWT. |
identity.subject_claim / identity.subject | IdP only | The JWT claim and value that resolve the token to this agent identity. |
identity.spiffe | No | Bind the identity to a SPIFFE workload identity (trust_domain, spiffe_id, svid_type). See the Workload identity with SPIFFE and SPIRE section. |
tags | No | Key-value pairs to categorize the identity. |
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.| Setting | Description |
|---|---|
| Associated agent identity | The agent identity this agent presents when it, in turn, calls other agents or MCP servers downstream. |
| Who can call this agent | The callers permitted to invoke it: users, virtual accounts, and other agents (by their agent identity). |
| On whose behalf the agent can act | The 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 proxy | The 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
Agent field reference
Agent field reference
| Field | Required | Description |
|---|---|---|
type | Yes | remote-agent for an agent registration. |
name | Yes | Unique name for the agent in the registry. |
description | Yes | Short description of the agent’s purpose. |
owned_by_team | Yes | The team that owns and can manage the registration. |
identity | Yes | The agent identity this agent presents on its own downstream calls. |
callers | Yes | Who may invoke this agent: users, teams, virtual_accounts, and agents (by identity). |
act_on_behalf_of | No | The users and teams this agent may act on behalf of, enforced before any delegated token is minted. Required if the agent acts for users. |
url | No | The endpoint the Gateway proxies to. Omit for agents that can’t be proxied (governance-only). |
framework | url only | a2a or custom. See Supported Frameworks. |
agent_card_path | A2A only | Path to the agent card JSON (default /.well-known/agent-card.json). |
auth.type | No | Outbound auth to the remote endpoint: token_exchange (mint a scoped delegated token), token_passthrough, or header. |
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 asubject_token and returns a new token for a target audience and scope.

Delegation vs. impersonation
RFC 8693 supports two semantics. The distinction matters for agents, and TrueFoundry uses delegation by default.| Impersonation | Delegation | |
|---|---|---|
| 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 trail | The agent disappears. | Full chain: user + each acting agent. |
| TrueFoundry default | — | Used by default, so every hop is attributable. |
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.
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.
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:- what the user is allowed to do,
- what the agent is allowed to do, and
- what the target (MCP server or agent) is willing to accept.
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.| Capability | Generic (RFC 8693) | Okta — ID-JAG / Cross-App Access | Microsoft Entra — On-Behalf-Of |
|---|---|---|---|
| Underlying standard | Token Exchange (RFC 8693) | RFC 8693 + JWT Bearer (RFC 7523) | RFC 8693 profiled as OBO |
| Number of exchanges | 1 | 2 (get ID-JAG, then redeem it) | 2 (blueprint token, then OBO) |
| Intermediate token | New access token | ID-JAG (urn:ietf:params:oauth:token-type:id-jag) | Federated/exchange token, then resource token |
| Grant to resource | token-exchange | urn:ietf:params:oauth:grant-type:jwt-bearer | jwt-bearer with requested_token_use=on_behalf_of |
| Carries acting agent | act claim | ID-JAG audienced to the resource’s authorization server | act / xms_act_fct actor-facet claims |
| Best for | Internal services that trust the Gateway as STS | Cross-app and cross-vendor access brokered by the enterprise IdP | Microsoft-centric estates with Entra agent identities |
Okta — ID-JAG (Cross-App Access)
Okta — ID-JAG (Cross-App Access)
- 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-jagandaudienceset 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. - 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.
Microsoft Entra — On-Behalf-Of (OBO)
Microsoft Entra — On-Behalf-Of (OBO)
- The client authenticates the user and obtains a user access token audienced to the blueprint.
- 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 theassertion, and its own client assertion.
act, xms_act_fct) identifying the agent. The result is the same composite shape: user as subject, agent as actor.No IdP support? Token passthrough and scoped TrueFoundry tokens
No IdP support? Token passthrough and scoped TrueFoundry tokens
- 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 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.| Setting | Description |
|---|---|
| Which agents can access this server | The agent identities permitted to call this MCP server. |
| Which users/teams can access this server | The users, teams, or virtual accounts permitted (the existing collaborators model). |
| Tool-level scope | Restrict 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. |
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:- 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.
- 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.
- 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 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.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:- 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.
- If the caller is another agent, validate its token and resolve the agent identity. Check the caller agent is allowed to call this agent.
- 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.
- 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 element | What it carries at the gateway |
|---|---|
| principal | The caller — an agent identity, user, or virtual account. |
| action | The operation — mcp:callTool, agent:invoke, etc. |
| resource | The callee — an MCP server, a specific tool, or an agent. |
| context | Everything else — the user being acted for, the actor chain, time, request risk, source IP, environment. |
forbid always overrides permit, so guardrails are easy to express. A few examples of what becomes possible:
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.
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.act_on_behalf_of policy is still enforced — it just comes from a governance-only agent registration rather than a proxied one.| Hop | Subject (sub) | Actor chain (act) | Audience (aud) | Scope |
|---|---|---|---|---|
| Jane → Planner | Jane | — | Planner | (full user context) |
| Planner → Research | Jane | Planner | Research Agent | narrowed to Research |
| Research → Jira MCP | Jane | Research → Planner | Jira MCP Server | issues.read only |
- 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
Least-privilege tokens
Central policy
Lifecycle control
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
suband theactchain 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.
Putting it together
| You want to… | Use |
|---|---|
| Give an agent a verifiable identity | Register an Agent Identity (TrueFoundry-backed or IdP-backed). |
| Let an agent call MCP servers for a user | Grant 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 tools | Apply tool-level scope on the MCP server. |
| Let one agent call another | Register the callee on the Agent Gateway and add the caller agent to its “who can call me” list. |
| Carry the user across many hops | Rely 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 Entra | Use 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.| Standard | Role 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-Of | Microsoft’s agent-aware OBO profile of token exchange. |
| SPIFFE / SPIRE | Attested workload identity (X.509-SVID, JWT-SVID) for deriving an agent’s credential from its runtime. |
| WIMSE / WIT-SVID | Key-bound workload tokens that resist replay through intermediaries. |
| SPICE actor chain | Emerging 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. |
| A2A | Agent-to-agent transport, discovery, and signed agent cards. |
| Cedar | Attribute-based authorization policy evaluated at both gateways. |
FAQ
What if an agent can't pass an agent identity yet?
What if an agent can't pass an agent identity yet?
Delegation or impersonation — which does TrueFoundry use?
Delegation or impersonation — which does TrueFoundry use?
act claim), so every call is attributable. Impersonation hides the agent and is avoided unless a downstream server genuinely cannot understand a composite token.Do I need Okta or Entra to use this?
Do I need Okta or Entra to use this?
What's the difference between this and token passthrough?
What's the difference between this and token passthrough?
How are agents embedded in third-party software governed?
How are agents embedded in third-party software governed?