A Crash Course in OAuth2.0 Token Exchange

Top of the swaps!

James Collerton
3 min readDec 15, 2022
Weirdly hard to find ‘exchange’ related pictures

Audience

This article is aimed at engineers with a solid understanding of HTTP and OAuth2.0. It is worth reading (in order) the other articles I have written on the subject. They can be found in the list here.

In the following sections we will expand on why we need OAuth2.0 Token Exchange, when to use it, and give an overview of its implementation. However, the original RFC can be found here, and should be consulted for comprehensive technical detail.

Argument

To explain token exchange we first need to clarify some terms:

  • Security Tokens: Data denoting security and identity information we can send between systems (think JWT tokens).
  • A Security Token Service (STS): A service capable of exchanging one set of security tokens for another.

All the Token Exchange RFC explains is how to use an authorisation server as a Security Token Service.

So why might we need this? A lot of the time we have a resource server A, which is calling another service C on behalf of user B. We can use token exchange to get the requisite tokens to access C from the tokens we already have representing B.

All of the above manifests itself in a new grant type (referenced in the ‘Authorization Grant’ section of the image below).

How authorization grants fit into the OAuth2.0 flow. For a full explanation of the image look to the article here.

For those of you who need reminding, an authorisation server has two endpoints: /authorise and /token. All we need to implement token exchange is a new call to /token.

We can outline the new flow as below. Within the diagram ‘client’ takes on a slightly different connotation than usual. A client is just anyone who would like to exchange some tokens, including another authorisation server!

Basic sequence for token exchange.

Impersonation vs Delegation

Hopefully this is reasonably straightforward so far. Let’s quickly revisit the example of when we said we might use token exchange:

We have a resource server A, which is calling another service C on behalf of user B.

We can think of the actions of A in two ways:

  • Impersonation: Here server A is pretending to be user B, service C has no idea of its true identity.
  • Delegation: Server A transparently acts on behalf of user B, with service C fully aware of server A’s actions.

In the delegation case the token will include information about server A, as well as user B (a composite token). In the impersonation case we will only have user B information.

We can see how we might represent a JWT composite token below. The act claim can be used to represent who will be acting on a user’s behalf.

{
"aud":"urn:example:abc",
"iss":"https://www.example.co.uk",
"exp":1331913123,
"scope":"some scope",
"sub":"user-b@example.com",
"act":
{
"sub":"resource-server-a@example.com"
}
}

So how do we convey this information to the endpoint? Let’s re-examine /token.

What’s New in the Endpoint

We add the following parameters to the token endpoint:

  • subject_token: This is the token we would like to exchange.
  • subject_token_type: The type of the token, one of the options described here.
  • actor_token: The token of the service which will use the new token.
  • actor_token_type: Same as for subject.

Easy!

Conclusion

In conclusion we have covered the basics of token exchange, how we might use it, and some of the differentiating factors between this and core OAuth2.0.

--

--

James Collerton

Senior Software Engineer at Spotify, Ex-Principal Engineer at the BBC