Token Exchange
Swap one token for another that is made for the next service
- Who's involved
- Two services, auth server
- Best for
- Passing identity between services
- Difficulty
- Advanced
1Overview
How it works
Token Exchange lets a service trade a token it already holds for a new token suited to a different job. The most common case is a chain of services. A user calls Service A, and Service A needs to call Service B for that same user.
- The token you hold is the
subject_token. - The API you want to reach is the
audience. - The new token can be narrower (fewer scopes) but should never be broader.
2Use cases
When would you use this?
A chain of services
A web API receives a user's token, then trades it for one the orders service accepts, still for the same user.
Acting on someone's behalf
A support tool temporarily acts as a customer to look at their account, with the action recorded.
Crossing trust boundaries
A token from your company login is swapped for one a partner's cloud accepts.
Not the right fit? Just passing a token along? If the next service accepts the same token and scope, forwarding it may be simpler. Exchange when the audience or permissions must change.
3Interactive
Try it step by step
See it step by step
Step 1 of 5
Service A holds a user's token
The token was issued for Service A only. The Orders API would reject it, because it is not the intended audience.
4Practical advice
Do this, avoid that
Good practices
- Authenticate the calling service โ The exchange request is a client request like any other
- Ask for a specific
audienceโ Name the one API the new token is for - Request only the scopes you need โ Narrow them at every hop
- Keep exchanged tokens short-lived โ Exchange again instead of storing them
Common mistakes
- Passing the user's token straight through โ It is issued for another audience and widens exposure
- Exchanging with no policy โ Decide which clients may reach which audiences
- Expecting more access โ The new token cannot exceed what the original allowed
- Losing track of the user โ Keep the original
subso audit logs show who the call is for
5Code
Code example
Show the code
// Token Exchange (RFC 8693), from Service A
async function tokenForOrdersApi(subjectToken) {
const res = await fetch('https://auth.provider.com/oauth/token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: 'Basic ' + btoa(CLIENT_ID + ':' + CLIENT_SECRET),
},
body: new URLSearchParams({
grant_type: 'urn:ietf:params:oauth:grant-type:token-exchange',
subject_token: subjectToken,
subject_token_type: 'urn:ietf:params:oauth:token-type:access_token',
audience: 'https://orders.example.com',
scope: 'orders.read',
}),
});
if (!res.ok) throw new Error('Exchange refused');
return res.json(); // { access_token, issued_token_type, token_type, expires_in }
}