The problem token exchange solves
When the printer asks for the photos in album 42, the photo API checks the printer's token and then needs the image files, which live in the storage service at https://storage.photos.example. Service-to-service access followed that second request and found that forwarding the printer's token, calling with the photo API's own client credentials, and naming you in a header each lose something. It settled on a different approach: the photo API asks the authorization server for a new token, made for the storage service, in exchange for the token it received.
That approach is token exchange, and the storage service sets what it has to deliver. Storage should hand over your files only when the request really concerns you, so it needs a token addressed to it, about user-2048, carrying no more access than you gave the printer, and issued by an authority it already trusts. The photo API cannot produce that token. The authorization server can.
A grant at the token endpoint
Token exchange is an extension grant, like the device authorization and assertion grants. The photo API sends a token request to the same token endpoint the printer uses, and names the grant with a URN, shown here before form encoding:
grant_type=urn:ietf:params:oauth:grant-type:token-exchange
Each grant brings something different to the token endpoint:
| Grant | What the client brings |
|---|---|
| Authorization code | A code returned through your browser, and the PKCE verifier for that attempt. |
| Refresh token | A refresh token from an earlier token response. |
| JWT or SAML assertion | A signed statement from an issuer the server already trusts. |
| Token exchange | A security token the client holds, and a description of where the new token will be used. |
The token being exchanged is called the subject token, because it represents the party the new token will be about, here you. The request can also say where the new token will be used and what it should allow there. The response is an ordinary token response with one addition: a field saying what kind of token was issued.
What an exchange can change
JWT and SAML assertion grants turned one kind of signed statement into an access token. Token exchange generalizes that. The input can be an access token, a refresh token, a JWT, a SAML assertion, or an ID token from OpenID Connect, issued by this authorization server or by another one it trusts. The output does not have to be an access token either, which is why the response names its type.
When the output is an access token, it can differ from the input in several ways at once. It can be addressed to a different audience, carry less scope, live for less time, and record who is acting for whom. Each of those is a decision the authorization server makes for every exchange.
The specification defines the request and the response, and deliberately says little about how to make those decisions. Which tokens a server accepts, which clients may exchange them, and what the new tokens contain are left to each deployment. Much of the care in token exchange lives there. An exchange that works as intended never adds access you did not give. It turns the printer's token into something narrower: usable at a different service, about the same person, with no more access and for less time.