The OAuth token exchange flow explained.

OAuth Token Exchange Flow

On this page

OAuth Token Exchange Explained

OAuth 2.0 Token Exchange (RFC8693) is an extension to the OAuth 2.0 framework that adds support for exchanging an existing token for another token. Examples of tokens a client may exchange are access tokens, refresh tokens, ID tokens and SAML assertions. The client can specify details such as the desired scopes or token type of the requested token.

When to Use the Token Exchange Flow

Token exchange is a powerful feature. It basically allows a client to exchange any incoming token for any outgoing one. Use token exchange when

  • you want to transform an existing token (e.g. change format),
  • the current token is too powerful for an upstream call ("downscoping"),
  • the current token is insufficient in terms like scope or audience ("upscoping"),
  • you need to cross trust domains as a result of federation, or
  • you have to implement impersonation or delegation use cases.

Examples of Token Exchange

Microservice Architecture

You can use token exchange to request a new access token with a different scope or audience based on a previous access token. Depending on whether the new scopes or audiences are a subset of the original ones, the process is called "downscoping" and its counterpart is called "upscoping". Changing the scope and audience of a token can be very useful in a microservice architecture where the processing of a request involves internal calls to upstream APIs. In this case, you can utilize token exchange to maintain the principle of least privilege up the call chain where you adapt access tokens to the capabilities and needs of an upstream API, see also Token Sharing Approaches.

Federated Systems

Token exchange also allows you to cross security domains by exchanging a token from one trust domain to a token of a different one. The draft OAuth Identity and Authorization Chaining Across Domains, for example, standardizes an approach where a client can exchange an access token for an authorization grant that is valid in a different trust domain. The client can use that grant to get an access token at the authorization server of that trust domain.

Delegation and Impersonation

Further, you can also implement delegation and impersonation approaches with token exchange where one user (or client) can act on behalf of another. Token exchange allows a client to specify who requests to act (actor) on behalf of whom (subject) by including two tokens in the request representing the corresponding parties.

How Token Exchange Works

Token exchange is a token request where an existing token serves as the authorization grant. This existing token is called the "subject token." Since the token exchange protocol is not limited to OAuth and OpenID Connect tokens namely access tokens, refresh tokens and ID tokens, the specification refers to "security tokens" in general.

Though the specification does not mandate client authentication as part of the token exchange request, we highly recommend doing so. Not enforcing client authentication during a token exchange flow can bare great security risks.

Client Authentication

The client authenticates as part of the token request. There are many ways for a client to authenticate, the most common being client secret. The Curity Identity Server supports the following authentication mechanisms for clients:

  • No authentication (public client)
  • Secret in POST body
  • Secret using Basic Authentication
  • Client Assertion JWT
  • Mutual TLS (mTLS) client certificate
  • Asymmetric Key
  • Symmetric Key
  • Credential Manager
  • JWKS URI

The Security Tokens

The token exchange protocol distinguishes between three sorts of security tokens:

  • Subject token
  • Actor token
  • Requested token

The subject token represents the party on behalf of which the client requests a new token. Typically, the subject remains unchanged. That means that the newly issued token represents the same subject as the incoming subject token. For example, when you up- and downscope an access token, the claims in the resulting access token still relate (where and if applicable) to the same user as the incoming token.

The actor token is an optional token that enables delegation use cases. Delegation implies that a user (or client) acts on behalf of another user. Consequently, the token service needs to know about the subject and the actor. The purpose of the actor token is to represent the party that requests to act on behalf of the subject, the actor. The returned token still reflects the same subject as the subject token but contains a claim that provides information about the actor as well.

The requested token is the token that the authorization server returns as a result of a token exchange request. The requested token can be any security token including an access token or JWT assertion grant. The authorization server issues the new security token according to its policies. It commonly takes requested scopes, token types, resources and audiences into account. At the end, the authorization server returns a newly issued token to the client and informs the client about the corresponding token type.

The Token Exchange Messages

Request Parameters

  • Method: POST
  • Content-Type: application/x-www-form-urlencoded
  • Response Type: application/json
ParameterValueMandatoryDescription
grant_typeurn:ietf:params:oauth:grant-type:token-exchangeyesTells the token endpoint to expect a token exchange request.
subject_tokenThe security token to exchangeyesA security token that represents the party on behalf of whom the client makes the request (e.g. a user). Typically, the subject remains the same in the newly issued token.
subject_token_typeURI of the type of the security token (see list below)yesURI that describes the type of the subject token, e.g. whether the subject token is an access token.
actor_tokenA security token representing the actornoTypically an access or ID token that represents the party that wants to act on behalf of the subject.
actor_token_typeURI of the type of security token (see list below)no*URI that describes the type of the actor token, e.g. whether it is an access or ID token.
* Required if request contains actor_token.
requested_token_typeURI of the type of the requested token (see list below)noURI that identifies the type of the requested token, e.g. whether the client wants the newly issued token to be a valid access token. If unspecified, the authorization server issues a type defined by its policy.
scopeSpace separated string of scopesnoList of the scopes that the client is requesting for the new security token.
resourceURI of the resource servernoThe URI of the target service where the client intends to use the requested security token, e.g., the HTTPS URL of an API. A token exchange request may include multiple resource parameters.
audienceLogical name of the resource servernoA logical name such as a client ID, issuer or resource server identifier that identifies the target service where the client intends to use the requested security token. A token exchange request may include multiple audience parameters.

The following is a non-comprehensive list of token types:

  • urn:ietf:params:oauth:token-type:access_token
  • urn:ietf:params:oauth:token-type:refresh_token
  • urn:ietf:params:oauth:token-type:id_token
  • urn:ietf:params:oauth:token-type:saml1
  • urn:ietf:params:oauth:token-type:saml2
  • urn:ietf:params:oauth:token-type:jwt

Response

  • Response Type: application/json
ParameterValueMandatoryDescription
access_tokenA newly issued security tokenyesThe resulting security token. This security token does not have to be an OAuth access token but can be any security token.
issued_token_typeURI of the type of the issued security token (see list above)yesThe URI that identifies the type of the newly issued security token, e.g. whether it is an access token, ID token or JWT authorization grant.
token_typeBearer or other token type, N_AyesIf the newly issued security token is an access token, this value describes how the access token can be used. Most commonly Bearer token is used. N_A, if the security token is not an access token.
expires_inExpiration in secondsnoThe time to live of the security token in seconds.
scopeSpace separated stringnoIf not present, the newly issued security token has the requested scope. If present, the result includes the issued scope which may differ from the requested scope.
refresh_tokenA newly issued refresh tokennoTypically, token exchange does not include a refresh token but there may be use cases such as offline batch jobs, where refresh tokens are needed.

Conclusion

The token exchange protocol does not assume nor require any security characteristics of the tokens that the authorization server receives or issues. Consequently, it does not provide any guidance on how to establish or apply a trust model either. This means that you need to exercise extra prudence when exchanging tokens to avoid privilege escalation and security flaws. Nevertheless, token exchange is a tool that you do not want to miss in your OAuth toolbox because it provides a powerful way to adapt security tokens.

Join our Newsletter

Get the latest on identity management, API Security and authentication straight to your inbox.

Start Free Trial

Try the Curity Identity Server for Free. Get up and running in 10 minutes.

Start Free Trial