An agent needs to call a tool on behalf of a user. The lazy implementation forwards the user's access token to the tool, or uses the agent's own broad service credential. Both are wrong in ways that show up later: the first spreads a widely-scoped user credential across services that should never hold it, the second destroys the link between the action and the principal it was for.
OAuth 2.0 Token Exchange (RFC 8693) is the standard answer. It defines a grant type where a caller presents a token it holds and receives a different token — typically narrower, differently audienced, and carrying explicit information about who is acting for whom. It is the mechanism most agent authorization designs should be built on, and it is under-used relative to how well it fits the problem.
The Flow
An agent holds a token proving something about its context — its own service identity, or a token the user's session produced. To call a downstream tool, it makes an exchange request to the authorization server:
grant_typeis the token-exchange URN.subject_tokenis the token representing the principal the action is for.actor_token(optional) is the token representing the agent doing the acting.audienceorresourcenames the specific downstream service.scoperequests the narrow set of permissions this call needs.
The authorization server validates both tokens, checks that the requested scope is permitted for that principal and that this agent is allowed to act for that principal against that audience, and issues a new access token. The agent presents the new token to the tool. The tool validates it, checks its own audience claim, and authorizes based on the token's scopes and subject.
Two properties emerge for free. The downstream tool never sees the original credential, so a compromised tool cannot replay upward. And the tool's authorization decision is made on a token that names both the principal and the agent, so its own logs carry correct attribution.
Delegation vs Impersonation
RFC 8693 distinguishes two modes and the difference is operationally important.
Delegation produces a token whose sub is the principal and which carries an act claim naming the actor — the agent. Downstream, both identities are visible. Authorization can consider both: "this principal may read the record, and this agent class is permitted to read records on a principal's behalf." Audit records name both.
Impersonation produces a token that simply claims to be the principal, with no indication an agent was involved. Downstream services cannot tell an agent-initiated action from a human one.
For agents, delegation is almost always the correct mode. Impersonation is convenient because downstream services need no changes, and that convenience is exactly the problem: it discards the fact that an autonomous system took the action. That fact is what you need for incident investigation, for compliance narratives about automated decision-making, and for policies that treat agent actions differently from human ones — which most regulated environments require. See how to give an agent an identity.
The act claim nests for multi-hop chains: an orchestrator delegating to a sub-agent produces a token whose actor is the sub-agent, whose own actor is the orchestrator. That nesting is the delegation chain, and it is what makes the chain reconstructable after the fact.
The Two Invariants
Exchange must never widen scope. The issued token's permissions must be a subset of what the presented token already conveyed, intersected with what the agent is permitted to request for that audience. If your exchange endpoint can return a scope the caller did not already hold, you have built a privilege escalation endpoint with an OAuth-shaped interface. This sounds obvious and is violated routinely, usually through a configuration where an agent's client registration grants scopes independent of the subject token — the agent then obtains authority the user never had.
Enforce it as an explicit intersection in the authorization logic, and test it: attempt an exchange requesting a scope the subject token lacks and assert rejection. That test belongs in CI, not in a threat model document.
Every issued token names both identities. sub for the principal, act for the agent. Downstream services should reject agent-originated tokens that lack an actor claim, because a token with no actor is indistinguishable from a human session and will be logged as one.
Constraints Worth Adding
Audience restriction, mandatory. Every exchanged token names exactly one downstream service, and that service validates the claim. Without validation the restriction is decorative.
Short lifetime, scoped to the operation. Minutes, not hours. The token exists to make one call or one bounded sequence.
Delegation depth limit. Count hops in the nested actor chain and refuse beyond a configured depth. Unbounded delegation graphs are how a narrow compromise becomes a broad one — see cascading failures in multi-agent systems.
Purpose or task binding. Include a task identifier in the token so downstream records tie to the originating task. This is what lets you answer "everything that happened as part of task X" across services, and it is nearly free to add.
Actor allow-lists per audience. Not every agent should be able to request tokens for every service, even within the principal's scope. Register which agent classes may act for principals against which audiences. This is the control that prevents a low-value agent from becoming a general-purpose relay — the relay case in the confused deputy problem.
Sender constraint on the exchanged token. Combine with DPoP or mTLS binding so the issued token is useless if intercepted. See agent session hijacking and token replay.
Practical Deployment Notes
Latency is the usual objection and it is mostly unfounded. An exchange is a signature verification plus a mint — low single-digit milliseconds against a local authorization service, against model inference measured in hundreds of milliseconds. Where teams create a real problem is exchanging per tool call inside a loop. Cache the exchanged token for the task's duration and the audience it targets; you keep the narrow scope and pay the exchange once per task per destination.
Downstream services need to validate more than the signature: audience, expiry, scope, and the presence of an actor claim. A service that validates only the signature will happily accept a token minted for a different audience, which defeats the main benefit.
Where a downstream service cannot be changed — a legacy internal API, a third-party SaaS with fixed API-key auth — put the exchange at the proxy. The agent authenticates with an exchanged token to your gateway, and the gateway attaches whatever credential the legacy service requires, out of band. The agent never holds the legacy credential, and the exchange still governs whether the call is permitted. This is the pattern that lets token exchange be adopted incrementally rather than as a big-bang migration. See what is an AI control plane.
Common questions
Is token exchange overkill for a single-agent deployment?
It is worth it as soon as the agent serves more than one principal, because that is when ambient authority starts crossing principals. For a genuinely single-tenant, single-purpose agent driven by fixed configuration, a scoped service credential is defensible. The migration cost later is real though, and the exchange pattern is not much harder to stand up early than a credential store is.
What if the tool is an MCP server?
MCP's authorization model builds on OAuth 2.1, so exchange fits directly: the agent obtains a token audienced to the MCP server with scopes covering the specific tools it needs, and the server authorizes per tool. The important detail is that the scope must be tool-granular rather than server-granular, or you have authenticated precisely and authorized broadly. See scoping MCP tool permissions and MCP OAuth 2.1 and PKCE explained.
How does this interact with user consent?
Consent determines the scope ceiling for a principal's tokens. The user consents once to a set of capabilities for a given agent or application; exchange then mints narrower tokens within that ceiling per call, never exceeding it. Where a task needs authority outside the consented set, the correct behavior is to fail and request consent, not to fall back on the agent's own credential — which is the shortcut that turns a consent model into a formality.
Can the agent's own identity be the subject instead of the user's?
Yes, for autonomous work with no human principal — a scheduled maintenance agent, an indexing job. Then sub is the agent's own service identity and there is no actor claim, because there is no on-behalf-of relationship. What matters is not conflating the two cases: an agent that sometimes acts autonomously and sometimes on behalf of users needs distinct token shapes for each, or its audit trail will attribute user-initiated actions to the service identity.
How Praesidia approaches agent-to-tool authorization
Praesidia issues short-lived, audience-restricted tokens per governed connection, and supports standards-based token exchange for on-behalf-of calls so delegated authority stays scoped to the task. Tokens name both the acting agent and the asserted principal, and agents and MCP servers can be onboarded without hand-provisioned credentials.
Because the proxy holds downstream credentials and attaches them after policy evaluation, tools that cannot speak OAuth still sit behind the same authorization model, and no credential ever enters a model's context. Each exchange and each call is recorded with the delegation chain intact. See authenticate apps, agents, and MCP servers and the Praesidia documentation.