Skip to main content
Agent Identity

IETF · January 2020

OAuth 2.0 Token Exchange

RFC 8693

M. Jones, A. Nadalin, B. Campbell (ed.), J. Bradley, C. Mortimore

RFCStableAuthorizationFoundationField guide

OAuth 2.0 Token Exchange (RFC 8693) is RFC, January 2020. This, plus RFC 9068 JWT access tokens, is the backbone of 'the agent acts for the user at an API'. Multi-agent call chains that stay in OAuth-land are token exchanges with act, not new protocols.

At a glance

Problem
A service that already has a token needs a different token: new audience, narrower scope, or an actor acting on behalf of a subject. Token Exchange is the standard grant for that conversion.
Identity / authn / authz
Authorization (and identity preservation) across hops. The act claim records who is acting; subject_token names who they act for.

Actors

  • Client / actor (the agent or service calling exchange)
  • Authorization server
  • Subject (user or upstream service)
  • Downstream resource

How Token Exchange works

Animated sequence · RFC 8693

RFC 8693 — How does an actor get a new pass without becoming the user?

act grows down the chain

Token exchange mints a new pass for a new audience or a narrower scope. The client presents a subject_token; the AS returns a new token with an act claim appended. subject_token is who the call is for; actor_token is who is holding it. Attenuate — never expand. Nested act is not a new user.

Alice (RO)sends
Agent 1 (actor)
Authorization servergets
Agent 2 (actor)
API B (RS)

Now · 1/10· Discover· OAuth 2.1You are here

Alice (RO)→Authorization server·Authenticates at the AS (ordinary user-delegated grant)

Alice authenticates at the authorization server. Agent 1 is the client, not the user.

Why Do not start at the exchange. Alice is still the resource owner. The authorization-code + PKCE hops are the OAuth 2.1 sequence; we show login and consent so subject_token has a pedigree.

Alice shows ID. The messenger is not Alice.

  • resource owner from the spec
  • authentication from the spec

Solid = from the spec

Step 1 of 10: user to as. Authenticates at the AS (ordinary user-delegated grant) OAuth 2.1
Speed
ShareLinkedInX

RFC 8693 does not by itself define cross-domain trust — identity chaining profiles it with RFC 7523. Never expand scopes at a hop. Nested act is not WIMSE re-bind. Present subject_token; receive a new token with act appended.

In one board · hops

act grows down the chain

Alice

Bearer / DPoP pass →

API A

User token at API A

Alice's access token. sub is Alice. No act. The pass names who it is for, not who is holding it.

act: —
subject_tokenact

RFC 8693 does not by itself define cross-domain trust — identity chaining profiles it with RFC 7523. Contrast with WIMSE.

Hop list

Sequence above; this list is the same hops for reading and search. Each row is one message.

  1. 1

    Alice (RO)→Authorization serverOAuth 2.1Authenticates at the AS (ordinary user-delegated grant)

  2. 2

    Alice (RO)→Authorization serverOAuth 2.1Consents to Agent 1 calling APIs on her behalf

  3. 3

    Authorization server→Agent 1 (actor)OAuth 2.1Issues Alice's access token. sub is Alice. No act yet

  4. 4

    Agent 1 (actor)→Authorization serverRFC 8693Presents subject_token at the token endpoint (token exchange)

  5. 5

    Authorization server→Agent 1 (actor)RFC 8693Returns a new token with act appended. sub is still Alice

  6. 6

    Agent 1 (actor)→Agent 2 (actor)RFC 8693Hands the attenuated token to Agent 2 for the next hop

  7. 7

    Agent 2 (actor)→Authorization serverRFC 8693Presents that token as subject_token; actor_token is Agent 2

  8. 8

    Authorization server→Agent 2 (actor)RFC 8693Returns a new token: act nests Agent 2 wrapping Agent 1. sub is still Alice

  9. 9

    Agent 2 (actor)→API B (RS)RFC 8693Presents the audience-restricted token at API B. Authorization header, not query

  10. 10

    API B (RS)→Agent 2 (actor)RFC 8693Validates aud, exp, and act; responds

01

The gap for agents

A service that already has a token needs a different token: new audience, narrower scope, or an actor acting on behalf of a subject. RFC 8693 is the standard grant. Multi-agent call chains that stay in OAuth-land are token exchanges with act, not new protocols.

This, plus RFC 9068 JWT access tokens, is the backbone of 'the agent acts for the user at an API'. RFC 8693 does not by itself define cross-domain trust — identity chaining profiles 8693 + 7523 for that.

02

Actors and trust boundaries

The AS that performs the exchange must trust the subject_token and optional actor_token issuers. Downstream RSes trust the new token's issuer. Each hop should attenuate, never expand. The actor is a distinct principal; hiding it is how you lose audit and how confused deputies spawn.

03

Mechanics

POST grant_type=urn:ietf:params:oauth:grant-type:token-exchange with subject_token, subject_token_type, optional actor_token / actor_token_type, requested audience/resource/scope, requested_token_type. Token types are URNs (access token, JWT, ID token, SAML, …). Output often a JWT with nested act. may_act on an input token constrains who may act later.

subject_token / actor_tokenfrom spec
Quoted RFC 8693 inputs. Types are URNs. The subject is who they act for; the actor is who is calling.
actfrom spec
Quoted §4.1: nested actor identity. Agent A delegated to B delegated to C becomes nested act objects.
may_actfrom spec
Quoted: who is allowed to act for this subject in a future exchange. Enforce it.
urn:ietf:params:oauth:grant-type:token-exchangefrom spec
Quoted grant_type.

04

Step-by-step flows

Flow 1

On-behalf-of attenuation

  1. 1

    User delegates to Agent A (authorization code). A holds a token with sub=user, client_id=A.

  2. 2

    A calls token exchange: subject_token=user token, actor_token=A's identity if distinct, resource=downstream API, narrower scope.

  3. 3

    AS issues a JWT with sub=user, act=A, aud=downstream, reduced scope.

  4. 4

    A (or Service B) presents that token. Downstream must see both sub and act.

Never expand scope. If crossing domains, do not send this access token to AS B — mint a JWT grant (identity chaining) instead.

05

Identity vs authentication vs authorization

Authorization (and identity preservation) across hops. act records who is acting; subject_token names who they act for. Client authentication of the exchanger is still required.

06

How it composes

  • JWT access tokens

    Structured output so the RS sees sub, client_id, act, aud.

  • Identity chaining

    Profiles this grant plus 7523 for AS A → AS B.

  • Cross-App Access (ID-JAG)

    Exchanges an ID Token for an ID-JAG via 8693, then redeems via 7523.

  • Transaction Tokens

    Txn-Tokens are often requested using token-exchange-shaped parameters at a TTS inside one domain.

  • AAuth

    AAuth may nest RFC 8693 act on auth tokens for sub-agents; that is not this grant.

07

What bites agent implementers

  • Overbroad act

    If hop 2 still has the full user scope, the sub-agent is the user. Attenuate every hop. Log the chain.

  • Using an ID Token as subject_token carelessly

    XAA does this on purpose with IdP policy. Randomly stuffing ID Tokens into 8693 at an API AS is the 'send ID Token to the API' bug in a trench coat.

  • Cross-domain without chaining

    A token minted by AS A is not valid at AS B. Identity chaining exists because people tried anyway.

08

Stability — what you can ship

RFC 8693, January 2020, M. Jones, A. Nadalin, B. Campbell (ed.), J. Bradley, C. Mortimore. Stable. Ship it. https://www.rfc-editor.org/rfc/rfc8693.html

Catalog claims (short form)

subject_token / actor_token
Input tokens. Types are URNs (access token, JWT, ID token, SAML, …).
act
Nested actor identity. Agent A delegated to B delegated to C becomes nested act objects.
may_act
Who is allowed to act for this subject in a future exchange.

Implementer notes

RFC 8693 does not by itself define cross-domain trust. Identity chaining (almost an RFC in 2026) profiles 8693 + 7523 for that. Attenuate scope at every hop; never expand.

Related

Primary sources

  • RFC 8693https://www.rfc-editor.org/rfc/rfc8693.html