PingOne Platform APIs

Token exchange grant type

Token exchange enables an application to present a subject token and optionally an actor token and receive an access token for a custom resource. The application must be configured with a grantTypes value of token_exchange, and an tokenEndpointAuthMethod value of CLIENT_SECRET_BASIC, CLIENT_SECRET_POST, PRIVATE_KEY_JWT, or CLIENT_SECRET_JWT. Learn more in Applications OIDC settings data model.

Step 1: Send a request to the POST /{{envID}}/as/token endpoint based on the application’s token endpoint authentication method. Learn more in Token (token_exchange).

curl --location --request POST '{{authPath}}/{{envID}}/as/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic e3thcHBJRH19Ont7YXBwU2VjcmV0fX0=' \
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:token-exchange' \
--data-urlencode 'subject_token={{subjectToken}}' \
--data-urlencode 'subject_token_type=urn:ietf:params:oauth:token-type:access_token' \
--data-urlencode 'requested_token_type=urn:ietf:params:oauth:token-type:access_token' \
--data-urlencode 'scope={{requestedScopes}}'

The request requires the following parameters in the request URL:

  • grant_type=urn:ietf:params:oauth:grant-type:token-exchange

  • subject_token={{subjectToken}}

  • subject_token_type={{type}}, where {{type}} is either urn:ietf:params:oauth:token-type:access_token or urn:ietf:params:oauth:token-type:id_token

  • Optional: actor_token={{actorToken}}

    • Required with actor_token: actor_token_type={{type}}, where type is either urn:ietf:params:oauth:token-type:access_token or urn:ietf:params:oauth:token-type:id_token

    subject_token and actor_token must be issued by the same PingOne environment.
  • Optional: requested_token_type=urn:ietf:params:oauth:token-type:access_token

  • scope={{requestedScopes}}

Step 2: PingOne validates the subject_token and the actor_token, if provided. Based on the scope parameter value found in the token request and the scopes configured in the application, PingOne returns an access token in the token response; for example:

{
"access_token": "eyJ…", # the access token as a result of the token exchange token request
"token_type": "Bearer",
"expires_in": 3600,
"scope": "exampleScope",
"issued_token_type": "urn:ietf:params:oauth:token-type:access_token"
}