OAuth token exchange gives an agent or intermediary service a controlled way to obtain a token for the next resource without forwarding the token it received. The difficult part is not the HTTP request. It is defining who remains the subject, which workload is the actor, what authority survives the exchange, and which resource may accept the result. A weak design turns token exchange into a credential-minting shortcut; a strong design makes each delegated hop narrower and more attributable.
This guide assumes readers know the authorization-code and client-credentials flows covered in Edilec's OAuth security architecture guide. Here the focus is the service-to-service hop after initial authorization. The objective is a chain an investigator can reconstruct: the initiating principal, the actor that requested exchange, the policy used, the exact target and the protected operation that ultimately succeeded or failed.
Start OAuth token exchange with delegation semantics
RFC 8693 distinguishes delegation from impersonation. Under delegation, the acting principal retains its identity while representing the subject; under impersonation, the receiver may see the subject without the actor as a distinct principal. Agents, workflow engines and API intermediaries usually need delegation because accountability depends on preserving both. A user asking an expense agent to submit a claim is not the same event as the user submitting it directly.
Write a one-sentence semantic contract for each exchange before selecting claims: service A acts for subject B to call resource C for purpose D. Name whether B is a human, workload or tenant. Name whether A chooses the action or merely transports an already approved command. If the receiving API cannot explain how it authorizes both parties, stop. Token structure cannot repair an undefined authority model.
| Design element | Question to settle | Unsafe shortcut | Required evidence |
|---|---|---|---|
| Subject | Whose authority or data context is represented? | Treat the calling service as the user | Stable subject and tenant identifiers |
| Actor | Which workload is performing the delegated action? | Hide every intermediary behind one client ID | Workload identity and release or instance context |
| Target | Which API must accept the result? | Issue a token valid across internal services | Canonical resource or audience |
| Permission | Which operations survive the exchange? | Copy all inbound scopes | Mapped, reduced scopes and object policy |
| Lifetime | How long may this hop continue? | Outlive the initiating session by default | Issued, expiry and revocation context |
Define subject token and actor token roles
In the RFC 8693 request, subjecttoken is required and represents the party on whose behalf the request is made. actortoken is optional and represents the acting party. When an actor token is supplied, its token type is also required. Do not infer these roles from which credential arrived first. The authorization server must validate each presented token under the rules for its declared type and then decide whether that actor may receive delegated authority from that subject.
The issued JWT can use the act claim to represent an actor and potentially a delegation chain, but a nested chain is not permission by itself. Set a maximum depth, define which intermediaries are trusted to extend the chain, and reject loops or unknown issuers. Keep operational trace identifiers outside identity semantics. A trace ID helps join records; it must never become proof that an actor is authorized.
Narrow audience, scope, object and lifetime together
RFC 8707 lets an OAuth client identify the protected resource to which access is requested. RFC 8693 offers resource and audience parameters for the target of an exchanged token. Prefer one canonical resource per exchange. A token accepted by several unrelated APIs creates a replay path and prevents the authorization server from selecting resource-specific claims, encryption, lifetime and policy.
Scope reduction is necessary but insufficient. invoices.write may still cover every customer invoice. The resource server should combine token claims with current object policy, tenant membership, transaction limits, separation-of-duties rules and approval evidence. Bound the exchanged token's expiry to the shortest relevant constraint: upstream authority, workflow deadline, actor credential or local maximum. An exchange does not automatically revoke the input token or link later renewals, so propagate important revocation events deliberately.
Make the authorization server enforce exchange policy
Authenticate the exchanging client. RFC 8693 warns that omitting client authentication can let anyone holding a compromised token leverage the security token service. Policy should evaluate client, subject issuer, actor issuer, requested target, requested scope, tenant, delegation depth and credential assurance. Use allowlisted mappings rather than accepting arbitrary combinations. A payroll agent eligible for payroll-read exchange should not be able to substitute a payments audience or a different subject-token issuer.
Return stable OAuth errors without leaking sensitive policy internals. Distinguish malformed input, invalid credentials, disallowed target and temporarily unavailable dependencies in protected logs, while clients receive actionable but bounded responses. Cache exchange results only when the entire policy input is stable and the cache key includes subject, actor, target, scope and relevant context. Never let a cache entry cross tenants or survive a revocation boundary.
| Failure test | Expected decision | Operator signal | Recovery rule |
|---|---|---|---|
| Actor omitted where required | Deny exchange | Missing-actor policy reason | Fix caller identity, never infer |
| Audience changed to sibling API | Deny as invalid target | Requested and permitted targets | Request a separate mapped exchange |
| Scope broader than inbound authority | Deny or reduce explicitly | Requested versus issued scopes | Caller handles reduced result |
| Upstream subject disabled | Deny and invalidate active chain | Subject status source and event time | Require fresh authority |
| Token service timeout | No downstream call | Correlation ID and dependency state | Retry only the exchange request safely |
Keep final authorization at the resource server
The receiving API validates issuer, signature, audience, expiry, not-before time and token type, then interprets subject, actor and scope according to a documented profile. RFC 9700 consolidates current OAuth security practice, including sender-constrained tokens where feasible and avoidance of patterns vulnerable to token replay. An internal network or trusted gateway does not replace validation at the component that owns the protected record.
Treat delegated identity as one input to authorization, not a precomputed allow decision. The resource server should log its own policy version and authoritative outcome. Edilec's secure API access control guide explains why object and action checks belong server-side. This division also permits the token service to remain general while domain services enforce business invariants they actually understand.
Use the six-stage Edilec OAuth exchange path
Implement one complete path before supporting arbitrary chains. Capture the initiating authorization, authenticate the actor, evaluate target-specific policy, mint a narrow token, authorize the operation and reconcile the result. Test every stage with a denial. The accompanying Edilec diagram places those six stages in operational order so architecture, IAM and API teams can assign one owner and one evidence record to each boundary.
For agent integrations, the MCP authorization specification is a useful reminder that a client must not pass its MCP access token through to an upstream service. Apply the same resource isolation to agent tools: validate the token intended for the tool server, then exchange or mint a separate credential for a downstream API. Prompts and tool arguments can describe intent, but they cannot carry authority.
Roll out exchanges through a governed service catalog
Register each permitted exchange as a versioned relationship, not a generic token-service capability. The catalog entry should identify the subject-token issuer, actor client, target resource, maximum scopes, token profile, owner, approved environments and expiry review. Generate authorization-server policy from reviewed entries where feasible. Discovery should let service teams request a relationship without letting them self-approve new audiences. This makes a growing delegation graph inspectable and gives incident responders a reliable way to disable one edge without stopping unrelated service calls.
Before production, compare exchanged-token claims with the receiving API's validator configuration and threat model. Run a canary transaction under a dedicated test subject, then inspect authorization-server, gateway and resource records as one trace. Establish alerts for unusual exchange volume, repeated invalid targets, novel actor-subject pairs and tokens used at the wrong resource. Review unused relationships and remove them. A narrow exchange that remains enabled after its workflow is retired becomes standing privilege by another name.
Key takeaways
- Choose delegation when the receiver must distinguish the initiating subject from the acting service or agent.
- Issue one target-specific token per resource and reduce scope, lifetime and object authority at every hop.
- Authenticate exchange clients and allowlist valid subject, actor, issuer and audience combinations.
- Keep domain authorization at the resource server and record both policy decision and authoritative outcome.
- Test revocation, invalid targets, reduced scopes, nested actors and token-service outages before production.
Frequently asked questions
Is OAuth token exchange the same as an on-behalf-of flow?
On-behalf-of is a common product or architecture label; RFC 8693 is the interoperable token-exchange protocol. A platform can implement an on-behalf-of behavior with different proprietary semantics. Verify whether it preserves an actor, narrows the target, authenticates the exchange client and produces a token profile the resource server can validate.
Why not forward the user's access token?
The original token may have the wrong audience, excessive scopes, a longer lifetime and no identity for the intermediary. Forwarding also exposes it to more services. A resource-specific exchange limits replay value and lets policy decide whether this actor may exercise this subject's authority now.
Can token exchange work without a human user?
Yes. A workload can be the subject and another workload the actor, provided the deployment defines those semantics and policy. Do not fabricate a human subject for scheduled work. Preserve the workload owner, purpose, tenant and initiating job so service-to-service delegation remains attributable.
Conclusion
OAuth token exchange is valuable when it makes delegation smaller and clearer. The authorization server converts an authenticated subject-and-actor relationship into a short-lived credential for one resource; the resource server still decides whether the requested operation is permitted. That separation avoids both broad token forwarding and a centralized token service that pretends to understand every domain rule.
Begin with one consequential service chain and prove who requested, who acted, what target was named, what authority was reduced and what system confirmed the result. Connect those records to Edilec's audit log design guide. Once operators can reconstruct a failed and successful exchange without inspecting secrets, the pattern is ready to extend.