Agent Identity and On-Behalf-Of (OBO) Delegation: Who Is Really Calling Your Tools?
.png)
Built for Speed: ~10ms Latency, Even Under Load
Blazingly fast way to build, track and deploy your models!
- Handles 350+ RPS on just 1 vCPU — no tuning needed
- Production-ready with full enterprise support
Why an agent needs its own identity
Give an autonomous agent access to your tools and you immediately face a question your IAM was never designed for: when the agent reads a Zendesk ticket or queries a database, who did that? There are three usual answers, and all three are wrong.
- It uses the user’s token. The downstream system cannot tell an agent was involved at all — every action looks like the human did it directly.
- It uses a shared service account. Now you cannot tell which user’s data was touched; thirty people’s requests collapse into one principal.
- It impersonates the user. The agent’s role in the decision is hidden, which is exactly what an auditor will ask about first.
In each case the audit trail is incomplete, authorization is coarse, and policy cannot tell a human action from an autonomous one. Agent identity fixes this by making the agent a first-class principal — one that can act as itself or on behalf of a user. For the broader picture, see what AI agent identity is and AI agent governance.
What “on behalf of” actually means
On-behalf-of delegation is a token that carries two subjects. Built on the RFC 8693 token-exchange pattern, the resulting token sets sub to the user and act to the agent — “this user, as acted for by this agent.” The permissions on that token (scp) are the intersection of what the user may do and what the agent is allowed to do, so an agent can never widen a user’s reach.
For a chain of agents, the act claims nest: a data agent acting for a research agent acting for a user. Every hop is recorded, so the full delegation path is visible in the audit log rather than flattened into one actor.

The two headers on every request
In TrueFoundry, an agent’s identity is created when you register it — each registered agent has exactly one identity, and it can be TrueFoundry-backed (the Gateway issues and signs the token) or identity-provider-backed by Okta or Microsoft Entra. The identity means the same thing either way; only the issuer differs.

Every request to the Gateway then carries two bearer tokens:
Authorization: Bearer <USER_TOKEN>
x-tfy-agent-authorization: Bearer <AGENT_TOKEN>The Authorization header is the user’s SSO token and passes through unchanged from end to end. The x-tfy-agent-authorization header is the agent acting right now, and each agent replaces it with its own identity before calling the next hop. If the agent header is absent, the request is just an ordinary user call, authorized on the user’s permissions alone. The same header pair works across all three surfaces — the LLM Gateway (/api/llm/chat/completions), the MCP Gateway (/mcp/<server>/server) and the Agent Gateway (/agent/<agent-name>).
Who can act for whom: collaborators
Delegation is not open-ended. It is bounded by the collaborators on the agent’s Access Control step, which carry two roles:
- Agent Manager — can edit the agent and its configuration.
- Agent Access — can invoke the agent and can be acted for by it. A user without this grant cannot be the subject of a delegated call, even if they could reach the target directly themselves.

Collaborators can be a user, a team, or a virtual account — so non-human workloads can delegate too. This is the rung that stops an agent from quietly acting for anyone in the org: delegation only works for identities that explicitly granted it.
Reaching the target is a separate grant
Being allowed to act for a user is one permission. Being allowed to reach a given tool is another — and both must hold. On an MCP server’s collaborators list, agents appear alongside users and teams, with their own roles: MCP Server User (call tools) and MCP Server Manager (administer).

In a YAML manifest the same grants use subject prefixes, so intent is explicit:
collaborators:
- subject: user:jane@acme.com
role_id: mcp-server-user
- subject: agent:research-agent
role_id: mcp-server-userSeparating the two grants is what makes least-privilege real: an agent your user can act through still cannot touch a tool it was never added to. It mirrors the authorization model we cover in what MCP authorization is and fine-grained authorization.
How a multi-hop call is authorized
The clearest way to see the model is to follow one request. Jane asks a planner agent, which delegates to a research agent, which calls a Zendesk MCP server. The user token never changes; the agent token does, and the Gateway checks each hop on its own grants.
Each agent is authorized only on its own grants — it never inherits its caller’s reach. The outbound side is unchanged: the MCP server’s existing auth (OAuth2, a shared API key, or token passthrough) keeps working without reconfiguration. All the Gateway adds is resolving the (user, agent) pair and authorizing it.
Where teams get this wrong
- Treating a shared service account as “agent identity.” A service account represents the agent as itself, but it cannot act for anyone — so you still cannot answer whose data was touched. Delegation is the whole point.
- Assuming reaching a tool implies permission to act for a user. They are separate grants. An agent that is a collaborator on a server still needs an Agent Access grant for the specific user it claims to act for.
- Letting the model read its own identity token. A prompted agent that can disclose its
x-tfy-agent-authorizationtoken can be impersonated. Keep it out of source control and out of anything the model can read. - Flattening the chain. If a multi-agent system collapses to one service account, the nested
actclaims are lost and your audit log cannot reconstruct who did what. Preserve the delegation chain hop by hop.
A worked example
A support-automation team runs a planner agent that fans out to specialist agents, one of which reads tickets from Zendesk. They want three things: the human requester on every action, the specific agent that acted, and no agent able to reach a tool it was not explicitly granted.
- Register each agent so it gets its own identity — TrueFoundry-backed here, since they build and run the agents themselves.
- On each agent’s Access Control, add the support team as Agent Access so the agents may act for those users.
- On the Zendesk MCP server, add only the ticket-reading agent as MCP Server User — the planner never touches Zendesk directly.
- Send requests with the user token in
Authorizationand the agent token inx-tfy-agent-authorization; let each agent swap in its own. - Read the audit log: every Zendesk read shows the requester, the acting agent, and the full delegation chain.
The honest limit: this governs who may act for whom and reach what. It does not replace the MCP server’s own outbound credentials — those stay where they are, which is exactly why adoption does not require re-plumbing your tools.
Gotchas worth knowing
- Agent identity is in Beta — behaviour and configuration can still change, so pin to the documented flow and re-check before a wide rollout.
- Identity-provider-backed agents must also be registered in the IdP (Okta or Entra); TrueFoundry-backed agents need no external registration.
- Denied calls return
403, naming the refused principal and reason — a user missing an Agent Access grant is rejected for delegated calls even when they could reach the target directly. - The permissions on an OBO token are the intersection of user and agent scopes, so tightening either side tightens the delegated call. A forbid policy overrides a permit.
- Delegation and reachability are independent — audit both grants, not just one, when something is unexpectedly denied (or unexpectedly allowed).
The three ways an agent gets its OBO token
Under the two-header model, the question of who performs the token exchange has three answers, set by the agent’s identity type. They trade convenience against where the trust and the secrets live.
In managed credentials, the agent’s OAuth client is registered in the IdP and TrueFoundry stores its credentials as secrets, then performs the exchange with the user’s token as the subject token and caches and refreshes the result. In federated token, the agent does the exchange outside TrueFoundry and sends the finished OBO token, which the gateway validates with jwks_uri, issuer, audience, and an agent_claim (default act.sub) before matching it to the registry — a failed match returns 403. In virtual account, the caller sends two tokens, Authorization: Bearer <virtual-account-token> and X-TFY-User-Token: <user-sso-token>, and the user context is carried by TrueFoundry’s own outbound auth rather than an IdP-issued OBO token; servers that specifically require standard RFC 8693 tokens should use one of the other two modes.
How the gateway authorizes the pair
Resolving the (user, agent) identity is step one, not the whole story. Once the pair is known, the request runs a short evaluation before anything reaches the tool, and every layer can only narrow access:
- Resolve the (user, agent) identity from the two headers.
- RBAC — user: the user must be a collaborator on the MCP server.
- RBAC — agent: the agent must be a collaborator too (its subject is
agent:<agent-name>). - Tool scope: the requested tool must be in the agent’s optional tools list, if one is set.
- Policy: optional Cedar policies run, where a forbid always overrides a permit.
- Forward to the MCP server with its own outbound auth.
This is why delegation is safe by construction: the OBO token’s own scope is already the intersection of user and agent permissions, and then four independent grants each have to agree before the call goes through. Tightening any one — removing the user’s collaborator role, dropping the agent, trimming the tool list, or adding a Cedar forbid — tightens the delegated call. The full audit line records the user, the agent, the identity mode, the delegation chain, the server and tool, the RBAC and Cedar decisions, the scopes used, and the status.
Related reading
- What Is AI Agent Identity? — the concept this builds on
- AI Agent Governance: Five Pillars You Build, Not Write — where identity sits in the stack
- MCP Authentication, Explained — inbound identity and outbound credentials
- What Is MCP Authorization? — the authorization model behind the grants
- TrueFoundry Joins Okta’s Cross App Access Ecosystem — identity-governed agent access with your existing IdP
- Agent Gateway vs LLM Gateway — why the multi-hop path needs its own control point
Conclusion
An agent that borrows a user’s token or hides behind a service account is a gap waiting to be found — by an auditor, or by an attacker. Agent identity closes it by making the agent a principal in its own right, and on-behalf-of delegation lets that principal act for a specific user while carrying both identities forward, hop after hop.
The mechanics are deliberately small: two headers, two kinds of grant, and an authorization check at the gateway. The user token stays constant, the acting agent changes, and every tool call answers both questions at once — which user, and which agent. That is what makes an autonomous system auditable instead of merely functional.
TrueFoundry AI Gateway delivers ~3–4 ms latency, handles 350+ RPS on 1 vCPU, scales horizontally with ease, and is production-ready, while LiteLLM suffers from high latency, struggles beyond moderate RPS, lacks built-in scaling, and is best for light or prototype workloads.














%20(28).webp)

.png)
.png)
.png)















