Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for RFC8693 - token exchange #1315

Open
Radiergummi opened this issue Nov 21, 2022 · 3 comments
Open

Add support for RFC8693 - token exchange #1315

Radiergummi opened this issue Nov 21, 2022 · 3 comments

Comments

@Radiergummi
Copy link

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
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.

@marcriemer
Copy link

I'm currently working on the OpenID implementation, which can be helpful to get this done.

@Radiergummi
Copy link
Author

In the mean time, I've actually implemented the grant type in our production authorisation server, and it's pretty straight forward.
What I'm unsure about is how to generalise the conditions to issue a token - the exchange grant is meant to be flexible and tightly integrated with application logic; but that could be worked out, I think.

@Sephster
Copy link
Member

Definitely interested in an implementation. The problem I have just now is trying to get a new main version out which is unfortunately taking up most of my time but would welcome a PR. I just can't promise it will get merged in too quickly unfortunately as it will definitely miss v9.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants