OAuth Token Exchange for Agents and Microservices: Design the Delegation Chain

Implement OAuth token exchange with explicit subject, actor, audience, scope, lifetime and audit semantics so agents and services can delegate work without forwarding broad user tokens.

Edilec Research Updated 2026-07-13 Cybersecurity

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 elementQuestion to settleUnsafe shortcutRequired evidence
SubjectWhose authority or data context is represented?Treat the calling service as the userStable subject and tenant identifiers
ActorWhich workload is performing the delegated action?Hide every intermediary behind one client IDWorkload identity and release or instance context
TargetWhich API must accept the result?Issue a token valid across internal servicesCanonical resource or audience
PermissionWhich operations survive the exchange?Copy all inbound scopesMapped, reduced scopes and object policy
LifetimeHow long may this hop continue?Outlive the initiating session by defaultIssued, 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 testExpected decisionOperator signalRecovery rule
Actor omitted where requiredDeny exchangeMissing-actor policy reasonFix caller identity, never infer
Audience changed to sibling APIDeny as invalid targetRequested and permitted targetsRequest a separate mapped exchange
Scope broader than inbound authorityDeny or reduce explicitlyRequested versus issued scopesCaller handles reduced result
Upstream subject disabledDeny and invalidate active chainSubject status source and event timeRequire fresh authority
Token service timeoutNo downstream callCorrelation ID and dependency stateRetry 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.

Six-stage Edilec OAuth token exchange diagram from initiating authority through actor authentication, policy, narrow token issuance, resource authorization and outcome evidence.
The Edilec delegation chain keeps subject, actor and resource distinct from the initial request to the authoritative API result.

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.

Continue with related articles