-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Token exchange is a new grant type defined by the IETF providing support for impersonation and delegation scenarios, such as the following:
Illustration by Scott Brady
In a nutshell, the grant type involves the following steps:
Exchanging a token
This uses a new grant type of urn:ietf:params:oauth:grant-type:token-exchange
and allows the requester to identify and authenticate themselves. Here, API1 is swapping the token it received for access to API2.
The subject token is the token sent by the client application, delegated by the user. Since this token was delegated using OAuth, the subject token type is urn:ietf:params:oauth:token-type:access_token
(an access token).
POST /token
Host: auth.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:token-exchange
&client_id=api1
&client_secret=secret
&scope=api2
&subject_token=accVkjcJyb4BWCxGsndESCJQbdFMogUC5PbRDqceLTC
&subject_token_type=urn:ietf:params:oauth:token-type:access_token
Token exchange response
The token response for token exchange is then slightly different than what you are used to:
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-cache, no-store
{
"access_token": "lt6QCYJ58k44GRoCwwBPcFDPzYzHdGClhM9qCuh39DIL",
"issued_token_type": "urn:ietf:params:oauth:token-type:access_token",
"token_type": "Bearer",
"expires_in": 60
}
The issued_token_type
tells API1 (now acting as a client application) that it has sent back an access token. This allows API1 to understand how to use the token it has just received. In this case, it’s an access token that it can use to access a protected resource (API2).
The access token
The initial token was delegated by user, to the client application app, and you’re still acting on their behalf. But, by using the act
claim set, you can show that api1
is the current actor. At the very least, this would be valuable for audit trials.
{
"iss": "https://auth.example.com",
"sub": "123xyz_user",
"client_id": "app",
"aud": "api2",
"scope": "api2",
"act": {
"client_id": "api1"
},
"exp": 1443904177,
"nbf": 1443904077
}
In addition to the act
claim type, the Authorized Actor claim type (may_act
) allows you to explicitly state who is allowed to act on someone’s behalf. For instance, if you wanted to explicitly state that api1
is authorized to act on app
’s behalf, then the original access token API1 receives, may look like:
{
"iss": "https://auth.example.com",
"sub": "123xyz_user",
"client_id": "app",
"aud": "api1",
"scope": "api1",
"may_act": {
"client_id": "api1"
},
"exp": 1443904177,
"nbf": 1443904077
}
Now, when validating a token exchange request, the authorization server can check that the subject token has this may_act and that it includes the ID of the token exchange requester.
Use Cases
Token Exchange is great for API-to-API delegation, stuff like customer service acting on behalf of a customer, and preserving clear audit trails across services, as well as checking that zero trust checkbox on your compliance terms thoroughly.
I would love to see token exchange being implemented in oauth2-server, and subsequently in Laravel Passport. I have quite a bit of experience working with OAuth in PHP and would like to contribute to this, if there's any interest in implementing that grant type.