Learn what OAuth 2.0 token exchange is, how it works, and how you can use it to exchange access tokens from different sources to access tokens provided by Authorization Control Plane.
Token exchange in a nutshell
OAuth 2.0 Token Exchange is an extension to the standard OAuth 2.0 protocol. It enables client applications to request and obtain security tokens (such as access tokens) from an authorization server (in this case, ACP) acting as a Security Token Service (STS).
STS is a service responsible for validating tokens provided to it and issuing new tokens in the response, which enables client applications to obtain appropriate security tokens for resources that are within distributed environments. In other words, a client application may request access to resources with an access token from a third-party authorization server, exchange its token to an access token provided by ACP, and then use this token to authenticate the request.
Token exchange in ACP
At the moment, client applications can only exchange access tokens. Exchanging refresh or ID tokens is not supported.
The verification for third-party tokens is done using an OpenID-Connect-based Identity Provider that is configured for a given workspace (authorization server). Currently, the token exchange grant flow is available for Okta, Auth0, and Generic OIDC Connector. ACP does not support token exchange grant flow for SAML-based IDPs.
ACP’s authorizers are also capable of exchanging third party access tokens to ACP tokens when enforcing access control. To learn more, see the Using third-party access tokens for access control article.
Traditional OAuth flow vs. Token exchange
In the traditional OAuth 2.0 setup of ACP, a client application requests access to protected resources using an access token provided by ACP. This client application is registered within ACP and requests tokens only from ACP.
When token exchange is used, the access token source can be different as long as it comes from a trusted third-party OAuth authorization server. There are, in fact, two client applications and two OAuth authorization servers - ACP and a third-party authorization server. Client application A is registered within the third-party authorization server. Client application B is registered within ACP. Once Client A gets a token from the third-party authorization server, it can send a request to the ACP’s OAuth token endpoint using client credentials from the Client B and passing the original token it got from the third-party authorization server. ACP validates the request and mints a token that is used to authenticate the client to access protected resources. In this setup, Client B impersonates Client A.
When to use
Token exchange grant can be used for a variety of reasons, but there are two main and most common use cases it solves:
Migration enablement - it is much easier for you to migrate from a third-party OAuth or OpenID Connect provider to ACP. You can make sure that your migration is going to be successful and the services protected by ACP’s authorizers can consume access tokens provided by your legacy OAuth/OIDC provider.
Partnership enablement - if you are a Cloudentity partner that provides OAuth/OIDC authorization server capabilities, you are able to consume tokens coming from your authorization server and enforce authorization at the API request layer. Additionally, you can take a hybrid approach, where simple client applications that do not need highest level of security are registered within your authorization server, but the client applications that do need the highest level of security or need to be, for example, FAPI or Open Banking compliant, are registered within ACP.
Exchanging tokens in depth
A client application performs OAuth authorization to a third-party OAuth authorization server, also referred to as an Identity Provider.
The server returns a third party access token.
The client application makes a request to ACP’s OAuth token endpoint.
For the diagram simplification, you can see that this is one client application requesting tokens both to the 3rd party authorization server and to the ACP. In fact, one client application cannot be registered within two different authorization servers to get access tokens. When the application requests a token from the 3rd party provider, it uses client credentials coming from the application registered within the 3rd party authorization server. When it requests token exchange to ACP, it uses client credentials from an application that is registered within ACP.
For more details about the request and, for example, it’s parameters, see the token request details section.
ACP validates the token.
ACP checks if the 3rd party access token comes from an Identity Provider that is configured as trusted in ACP.
For JWT tokens, the token contains the
issclaim so it is easier to validate the token. ACP uses the JSON Web Key Set (JWKS) of the 3rd party authorization server to validate the token signature.
For opaque tokens, it is not possible to verify the token without calling the
/userinfoendpoint of the 3rd party authorization server.
If the 3rd party token is an opaque token, ACP calls the 3rd party provider’s
ACP calls every IDP that has the token exchange grant enabled in ACP’s Identities configuration to check if the 3rd party token is still valid.
If your IDP has the
/userinfoendpoint marked in the ACP Identities configuration and the 3rd party token is a JSON Web Token, ACP calls the configured
ACP maps the claims from the incoming 3rd party token to claims that are configured in ACP.
If the validation is successful, ACP returns an access token minted by ACP.
If the validation is not successful, ACP returns
Invalid token requestin the response body.
Token request details
Below, you can see an example of the request to the OAuth token endpoint using the token exchange grant type.
curl -v https://test.us.authz.stage.cloudentity.io/test/default/oauth2/token -d "grant_type=urn:ietf:params:oauth:grant-type:token-exchange&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET&subject_token=$AT"
When token exchange grant is used, the request to the OAuth token endpoint
must contain the
grant_type request body parameter with the
Additionally, the request body must contain the following parameters:
client_id- client identifier of the client application registered within ACP for the purpose of the token exchange.
client_secret- client secret of the client application registered within ACP for the purpose of the token exchange.
subject_token- third party authorization server’s access token to be exchanged for the ACP’s access token.
subject_tokencannot be an ACP’s access token. The token must come from a third party provider.
Contrary to the OAuth 2.0 Token Exchange specification, ACP’s implementation for the token exchange grant does not support the
resourcerequest body parameter. It’s logic is covered by the
scopeparameter holds a list of space-delimited and case-sensitive strings that allow the client application to specify the desired scope of the requested token. Scopes are unique within different authorization servers.
If there is a client application that requests a
custom-scopefrom the ACME service, you do not need to explicitly provide the
aud(audience) parameter in your request. The ACME service is automatically added to your token audience parameter as the
custom-scopeis unique to the ACME service.
Token exchange and extensions limitations
When the token exchange grant type is used, some of the features that you would get with a standard OAuth authorization for client apps that request tokens from ACP are not available:
When using the token exchange grant type, it is not possible to use ACP’s Extensions (post authentication scripts).
amr(authentication method reference) can be set only through a static field in your IDP configuration. It is not possible to modify or map the
amrclaim using Extensions.