Delegation Done Right: Token Exchange and the On-Behalf-Of Pattern
Part of the series The Authentication and Authorization Challenges of Agentic AI. Builds on Agent Identity: Why Your AI Agent Needs to Be a First-Class Principal.
Once an agent exists as its own principal, it still has to prove something to every resource it touches: that it’s acting for a specific user, with a specific scope, right now — not simply presenting whatever credential happened to be lying around. This is the delegation gap, and it’s worth taking seriously because the shortcuts here are the ones that turn into breach postmortems.
The scenario, and the three ways teams get it wrong
An agent needs to read a user’s calendar to schedule a meeting, or pull a customer record from an internal CRM API on the user’s behalf. There’s a real permission decision buried in that sentence — the agent should be able to do this specific thing, for this specific user, and nothing broader — but three common shortcuts throw that precision away:
Storing the user’s actual long-lived credential. The agent (or something upstream of it) captures the user’s password, session cookie, or long-lived refresh token and holds onto it to make future calls without bothering the user again. This is the worst version: a static, high-value secret now sits in whatever storage the agent uses, with the agent’s own security posture as the only thing standing between that secret and a much bigger blast radius than “one user’s one session” was ever supposed to have.
Token pass-through. The agent receives a token — its own, or the user’s — and forwards it verbatim to a downstream API without exchanging it for anything narrower. This looks harmless because nothing was stored, but it means every downstream service the agent talks to is now trusting a token that was minted for a different audience, often with broader scope than the specific call requires, and with no record that an agent — as opposed to the original client — was actually the one presenting it.
Constant re-authentication. The opposite failure: prompting the user to log in again for every new downstream call the agent needs to make. This “solves” the credential problem by making delegation impossible in practice — nobody re-authenticates ten times to let an agent finish a task, so teams either abandon the feature or, more often, quietly fall back to one of the first two shortcuts.
The pattern: token exchange
OAuth 2.0 Token Exchange (RFC 8693) exists specifically for this shape of problem: a client holds one token and needs a different token — narrower in scope, meant for a different audience, or reflecting a different relationship between the parties — without looping the user back through a browser redirect.
The mechanics, at a level of detail worth actually understanding rather than treating as a black box: the agent’s backend presents a subject_token (identifying whose authority is being exercised — typically the user) to a token endpoint, along with its own credentials identifying the agent making the request. The response is a new access token, scoped to the specific downstream resource, whose claims can carry both the subject (sub, the user) and the actor (act, the agent) as distinct fields — exactly the data model discussed in the previous post. Critically, that new token is typically short-lived and audience-restricted to the one resource server it was requested for, which means a downstream service compromise doesn’t hand an attacker a credential usable anywhere else in the system.

The related building block here is the JWT Bearer grant defined in RFC 7523, part of the broader assertion framework in RFC 7521: it defines how an assertion — a signed JWT vouching for who’s involved — gets redeemed for an access token at an authorization server. Token exchange and JWT bearer assertions solve adjacent problems and are frequently combined: one mints or exchanges the token, the other defines the format and validation rules for the assertion doing the vouching.
The practical effect of doing this correctly: the agent never holds the user’s actual long-lived credential for the downstream service. It holds its own, narrower-scoped, short-lived token, re-requested each time it’s needed, exchanged fresh against the specific resource being called. If that token leaks, the blast radius is one scope, against one resource, for a limited window — not the user’s entire account.
Scoping down at every hop, not just the first one
The mistake that survives even after teams adopt token exchange for the first hop: treating the exchanged token as good enough for everything downstream, rather than re-scoping at every subsequent hop. If an agent’s task involves calling API A, which then needs to call API B on the same user’s behalf, the token presented to B should be exchanged again — narrowed further if B needs less than A was granted, and carrying an extended actor chain if more than one delegate is now involved.
This matters because scope tends to only grow if nobody actively narrows it. An agent that was granted read access to a calendar for the purpose of checking availability shouldn’t be handing that same token to a scheduling sub-service that only needs to write a single event — if it does, and that sub-service is compromised, the attacker inherits read access to the whole calendar rather than write access to one event.
Design guidance
Never let an agent (or the process hosting it) become a durable store of long-lived third-party credentials. If a refresh token, API key, or session credential for an external service needs to persist anywhere, it should live in infrastructure specifically designed to store and rotate secrets — not in the agent’s own working memory, prompt context, or conversation history, where it risks being logged, surfaced in a response, or retained far longer than the specific task required it.
Treat “the agent forwards its own token everywhere” as an anti-pattern, not a convenience. Every hop across a trust boundary — agent to internal API, internal API to another internal service, agent to a completely different agent — is an opportunity, and arguably an obligation, to exchange for a token scoped to that specific hop rather than reusing one minted for a different purpose.
Default to short token lifetimes for delegated access, and make re-exchange cheap. The friction that makes teams reach for long-lived tokens in the first place usually comes from treating token exchange as an expensive, rare operation. If it’s cheap and fast to re-exchange a token before each call, there’s little reason to hold onto a long-lived one “just in case.”
Preserve the actor chain, don’t collapse it. When there’s more than one hop of delegation — user to agent, agent to sub-agent, sub-agent to API — resist the temptation to flatten the chain down to just the original user’s identity for convenience. The nested actor structure is what lets you answer, after the fact, exactly which link in the chain did what; collapsing it trades a debugging and audit capability for a marginally simpler token.
Getting delegation right doesn’t require exotic infrastructure — RFC 8693 and RFC 7523 are stable, widely implemented standards, and most modern authorization servers support token exchange as a first-class grant type. The gap is almost always in application design: reaching for the credential-hoarding shortcut because it’s faster to build, or forwarding a token because re-exchanging it “shouldn’t matter.” It does matter, and it’s the difference between an agent that can be scoped and audited, and one that’s effectively holding a skeleton key.
Next in the series: Human-in-the-Loop, Automated: Asynchronous Authorization for High-Stakes Agent Actions, which covers what happens when even a correctly scoped, correctly delegated token isn’t enough — because the action is sensitive enough that a human needs to approve it specifically.