RFC 8693
OAuth 2.0 Token Exchange
๐ RFC 8693: OAuth 2.0 Token Exchange ๐ฆ
okay bestie, title block first, because the paperwork matters ๐
This one is RFC 8693, a Standards Track document from the IETF (ISSN 2070-1721), dated January 2020. The main author is M. Jones, with A. Nadalin from Microsoft, B. Campbell, Ed. from Ping Identity, J. Bradley from Yubico, and C. Mortimore from Visa. Nothing is marked as obsoleting or updating anything else, so it's a clean new arrival ๐ธ
Now the vibe โจ
Abstract
okay so the whole point is this: it defines a protocol that's HTTP- and JSON-based, for a Security Token Service (STS). An STS is basically a service that takes security tokens you hand it and gives you new ones back. The protocol spells out how you ask an OAuth 2.0 authorization server for those tokens, including tokens that use impersonation and delegation ๐ฅ
Status of This Memo
this part is the official-y stuff ๐ It's an Internet Standards Track document. It's a product of the IETF, it reflects consensus from the IETF community, got public review, and was approved by the IESG. If you want more on what Internet Standards are, check Section 2 of RFC 7841. For the current status, errata, or feedback, head to https://www.rfc-editor.org/info/rfc8693.
Copyright Notice
copyright is IETF Trust and the document authors, 2020, all rights reserved ๐ This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) as of publication. Read those carefully, because they spell out your rights. Code pulled out of this document has to include the Simplified BSD License text, as described in Section 4.e of the Trust Legal Provisions, and comes with no warranty, same as that license says ๐
Table of Contents
1. Introduction
1.1. Delegation vs. Impersonation Semantics
1.2. Requirements Notation and Conventions
1.3. Terminology
2. Token Exchange Request and Response
2.1. Request
2.1.1. Relationship between Resource, Audience, and Scope
2.2. Response
2.2.1. Successful Response
2.2.2. Error Response
2.3. Example Token Exchange
3. Token Type Identifiers
4. JSON Web Token Claims and Introspection Response Parameters
4.1. "act" (Actor) Claim
4.2. "scope" (Scopes) Claim
4.3. "client_id" (Client Identifier) Claim
4.4. "may_act" (Authorized Actor) Claim
5. Security Considerations
6. Privacy Considerations
7. IANA Considerations
7.1. OAuth URI Registration
7.2. OAuth Parameters Registration
7.3. OAuth Access Token Type Registration
7.4. JSON Web Token Claims Registration
7.5. OAuth Token Introspection Response Registration
8. References
8.1. Normative References
8.2. Informative References
Appendix A. Additional Token Exchange Examples
A.1. Impersonation Token Exchange Example
A.1.1. Token Exchange Request
A.1.2. Subject Token Claims
A.1.3. Token Exchange Response
A.1.4. Issued Token Claims
A.2. Delegation Token Exchange Example
A.2.1. Token Exchange Request
A.2.2. Subject Token Claims
A.2.3. Actor Token Claims
A.2.4. Token Exchange Response
A.2.5. Issued Token Claims
Acknowledgements
Authors' Addresses
1. Introduction โจ
1.1. Delegation vs. Impersonation Semantics
(This section is in the next part, bestie, so stay tuned ๐ง)
okay so the Introduction is where the setup happens ๐ A security token is basically a bundle of info that helps identity and security stuff get shared across different environments or security domains. Examples include JSON Web Tokens (JWTs) [JWT] and SAML 2.0 assertions [OASIS.saml-core-2.0-os]. They're usually signed for integrity and sometimes encrypted for confidentiality. Tokens also get called "assertions" sometimes, like in [RFC7521] ๐
An STS is a service that can validate tokens you give it and issue brand-new ones back, so clients can get the access credentials they need across heterogeneous environments or security domains ๐ Web Service clients used WS-Trust [WS-Trust] to talk to an STS. That one runs on XML and SOAP, but modern web dev has moved toward RESTful patterns and JSON, which is so much more relatable ๐
The OAuth 2.0 Authorization Framework [RFC6749] and OAuth 2.0 Bearer Tokens [RFC6750] became the popular standards for letting third-party apps access HTTP and RESTful resources. The usual OAuth 2.0 flow trades some proof of resource owner authorization for an access token, which has been super useful in practice. BUT its inputs and outputs are kinda too limited to fully cover a security token exchange framework ๐ซถ
This spec extends OAuth 2.0 so clients can request and get security tokens from authorization servers acting as an STS. Like OAuth 2.0, it's all about developer simplicity: you only need an HTTP client and a JSON parser, which basically every modern dev environment has โจ The STS protocol here isn't itself RESTful (an STS doesn't really fit a REST approach, ngl), but it uses communication patterns and data formats that RESTful devs will recognise ๐ฆ
The spec adds a new grant type for token exchange requests, plus the parameters that go with them at the token endpoint. A token exchange response is a normal OAuth 2.0 token endpoint response with a few extra parameters for giving the client more info ๐
The party making the exchange request is the client here. That doesn't mean it has to be a traditional OAuth client, though. A resource server, for example, can be the client during token exchange. It might trade an access token it got in a protected resource request for a new token suited to a backend service call. The new token could be a more narrowly scoped access token for the downstream service, or a totally different kind of token altogether ๐
The scope here is a basic request-and-response protocol for STS-style token exchange over OAuth 2.0 ๐ธ A few new JWT claims are defined so delegation semantics can be expressed. But the syntax, semantics, and security characteristics of the tokens themselves (both the ones sent to the authorization server and the ones the client gets back) are explicitly out of scope ๐ โโ๏ธ No requirements are placed on the trust model where an implementation gets deployed. More profiles might nail down details like whether tokens need signing or encryption, or whether proof-of-possession tokens are required or issued. Those are often policy calls for each deployment, so they'll be configured or implemented to fit โญ
The security tokens obtained can be used in a bunch of contexts, and those specifics are also outside this spec ๐
1.1. Delegation vs. Impersonation Semantics โจ
okay so bestie, one super common thing an STS (remember from last section!) gets used for is letting a resource server A call a backend service C on behalf of the user B who asked for it. ๐ฆ Depending on the local site policy and authorization infrastructure, it might be nice for A to use its own credentials to reach C and just add a little note saying A is acting for B ("delegation"). Or A could get a limited access credential to C that still says B is the one authorized ("impersonation"). Both are useful in other multi-party setups too, periodt ๐
When principal A impersonates principal B, A gets all the rights B has within some defined rights context and is indistinguishable from B in that context. ๐ So whenever anyone receiving the token is concerned, they're literally dealing with B. Some members of the identity system might know impersonation is happening, but that's not required. For all intents and purposes, when A is impersonating B, A is B inside the rights the token authorizes. A's ability to impersonate B could be limited in scope or time, or even be one-time-use, either through the token's contents or through an out-of-band mechanism. ๐ซถ
Delegation semantics are different from impersonation, even though they're super closely related ๐ธ With delegation, principal A still has its own identity, separate from B. And it's explicitly understood that while B may have delegated some of its rights to A, any actions taken are being taken by A representing B. Kinda like A is an agent for B ๐ง
Delegation and impersonation don't cover every situation ๐ When a principal is acting directly on its own behalf, neither one is in play. They are, however, the more common semantics for token exchange, so this spec gives them more direct treatment โจ
Delegation semantics are usually expressed in a token by including info about both the primary subject of the token and the actor to whom that subject has delegated some of its rights. These are sometimes called composite tokens ๐ because they're composed of info about multiple subjects. Typically, in the request, the subject_token represents the identity of the party on whose behalf the token is being requested, while the actor_token represents the identity of the party to whom the access rights of the issued token are being delegated. A composite token issued by the authorization server will contain info about both parties. Whether and when one gets issued is at the discretion of the authorization server and applicable policy and configuration ๐
The specifics of representing a composite token, and even whether or not one will be issued, depend on the details of the implementation and the kind of token. Representations of composite tokens that aren't JWTs are beyond the scope of this specification. The actor_token request parameter does provide a way to give info about the desired actor, and the JWT act claim can provide a representation of a chain of delegation. ๐
1.2. Requirements Notation and Conventions
okay, quick caps-lock check ๐ The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document get interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they show up in all capitals, just like here ๐
1.3. Terminology
This spec borrows a bunch of terms ๐ From OAuth 2.0 [RFC6749] we get "access token type", "authorization server", "client", "client identifier", "resource server", "token endpoint", "token request", and "token response". From JSON Web Token (JWT) [JWT] we get "Base64url Encoding", "Claim", and "JWT Claims Set". Know these and you're set ๐ง
2. Token Exchange Request and Response โจ
2.1. Request
okay so a client asks for a security token by sending a token request to the authorization server's token endpoint, using the extension grant type mechanism defined in Section 4.5 of [RFC6749] ๐ฆ
Client authentication to the authorization server is done with the normal mechanisms OAuth 2.0 provides. Section 2.3.1 of [RFC6749] defines password-based authentication of the client, but client authentication is extensible, so other mechanisms are possible. For example, [RFC7523] defines client authentication using bearer JSON Web Tokens (JWTs) [JWT]. The supported methods of client authentication, and whether to allow unauthenticated or unidentified clients, are deployment decisions that are at the discretion of the authorization server.
โ ๏ธ heads up, this part is serious: omitting client authentication lets a compromised token get leveraged via an STS into other tokens, by anyone who has that compromised token. That's why client authentication gives the STS extra authorization checks on which entities are allowed to impersonate or receive delegations from other entities. ๐ญ
The client makes a token exchange request to the token endpoint with an extension grant type, using the HTTP POST method. The following parameters go in the HTTP request entity-body, using the application/x-www-form-urlencoded format with a character encoding of UTF-8 as described in Appendix B of [RFC6749] ๐
grant_type REQUIRED. The value urn:ietf:params:oauth:grant-type:token-exchange indicates that a token exchange is being performed.
resource OPTIONAL. A URI that indicates the target service or resource where the client intends to use the requested security token. This lets the authorization server apply policy as appropriate for the target, such as deciding the type and content of the token to be issued, or if and how the token is to be encrypted. In many cases, a client won't know the logical organization of the systems it talks to, and will only know a URI for the service where it plans to use the token. The resource parameter lets the client tell the authorization server where it intends to use the issued token by giving the location, typically as an https URL, in the token exchange request, in the same form that will be used to access that resource. The authorization server will typically be able to map from a resource URI value to an appropriate policy. The value of the resource parameter MUST be an absolute URI, as specified by Section 4.3 of [RFC3986], that MAY include a query component and MUST NOT include a fragment component. Multiple resource parameters may be used to indicate that the issued token is intended to be used at multiple resources listed. See [OAUTH-RESOURCE] for additional background and uses of the resource parameter ๐
audience OPTIONAL. The logical name of the target service where the client intends to use the requested security token. This serves a purpose similar to the resource parameter, but with the client giving a logical name for the target service. Interpreting the name requires that the value be something both the client and the authorization server understand. An OAuth client identifier, a SAML entity identifier [OASIS.saml-core-2.0-os], and an OpenID Connect Issuer Identifier [OpenID.Core] are examples of things that might be used as audience parameter values. However, audience values used with a given authorization server must be unique within that server, so they're properly interpreted as the intended type of value. Multiple audience parameters may be used to indicate that the issued token is intended to be used at multiple audiences listed. The audience and resource parameters may be used together to indicate multiple target services with a mix of logical names and resource URIs ๐ง
scope OPTIONAL. A list of space-delimited, case-sensitive strings, as defined in Section 3.3 of [RFC6749], that lets the client specify the desired scope of the requested security token in the context of the service or resource where the token will be used. The values and associated semantics of scope are service specific, and are expected to be described in the relevant service documentation ๐
requested_token_type OPTIONAL. An identifier, as described in Section 3, for the type of the requested security token. If the requested type is unspecified, the issued token type is at the discretion of the authorization server, and may be dictated by knowledge of the requirements of the service or resource indicated by the resource or audience parameter ๐
subject_token REQUIRED. A security token that represents the identity of the party on whose behalf the request is being made. Typically, the subject of this token will be the subject of the security token issued in response to the request ๐
subject_token_type REQUIRED. An identifier, as described in Section 3, that indicates the type of the security token in the subject_token parameter ๐ซถ
actor_token OPTIONAL. A security token that represents the identity of the acting party. Typically, this will be the party that is authorized to use the requested security token and act on behalf of the subject ๐ฆ
actor_token_type An identifier, as described in Section 3, that indicates the type of the security token in the actor_token parameter. This is REQUIRED when the actor_token parameter is present in the request, but MUST NOT be included otherwise ๐
When processing the request, the authorization server MUST perform the appropriate validation procedures for the indicated token type and, if the actor token is present, also perform the appropriate validation procedures for its indicated token type. The validity criteria and details of any particular token are beyond the scope of this document, and are specific to the respective type of token and its content ๐
Unless there are one-time-use or other semantics specific to the token type, performing a token exchange has no impact on the validity of the subject token or actor token ๐ธ The exchange is a one-time event and doesn't create a tight linkage between the input and output tokens. So, for example, while the expiration time of the output token may be influenced by that of the input token, renewing or extending the input token is not expected to be reflected in the output token's properties. It may still be appropriate or desirable to propagate token-revocation events. However, doing so is not a general property of the STS protocol, and would be specific to a particular implementation, token type, or deployment โจ
2.1.1. Relationship between Resource, Audience, and Scope
Okay bestie, so when a client asks for a token, it can say where it plans to use that token with the "audience" and "resource" parameters ๐ฏ. It can also say what the token is allowed to do with the "scope" parameter โจ. The semantics are that the client wants a token with the requested scope that works at all the requested target services ๐ซถ. So the access rights end up being the Cartesian product of all the scopes at all the target services ๐งฎ. Yes, it's a whole mouthful, but it's basically "every combo, all at once" energy ๐ .
Not every token request is going to get approved ๐. An authorization server might be unwilling or unable to fulfill one. The chances of a request getting rejected are way higher when the client is asking for very broad access ๐ญ. So unless you already know how the systems in a deployment are related, clients should be picky about how much access they ask for, especially how many target services they're hitting at once ๐ธ. If the authorization server thinks a client asked for too many target services at the same time, it can use the invalid_target error code, which is defined in Section 2.2.2, to let the client know ๐ซ.
2.2. Response
The authorization server replies to a token exchange request with a normal OAuth 2.0 response from the token endpoint, as specified in Section 5 of [RFC6749] ๐. The following subsections have more details and explanation โจ.
2.2.1. Successful Response
If the request is valid and meets all of the authorization server's policies and other criteria, the server builds a successful token response ๐. It does this by adding the following parameters to the entity-body of the HTTP response, using the application/json media type as specified by [RFC8259], with an HTTP 200 status code ๐ฆ. The parameters get serialized into a JavaScript Object Notation (JSON) structure, with each parameter sitting at the top level ๐ง. Parameter names and string values are JSON strings, and numerical values are JSON numbers ๐ข. The order of the parameters doesn't matter and can change ๐.
access_token
REQUIRED. This is the security token the authorization server issued in response to the token exchange request ๐. The "access_token" parameter from Section 5.1 of [RFC6749] is reused here to carry the requested token. That lets this token exchange protocol use the existing OAuth 2.0 request and response constructs that are defined for the token endpoint ๐ซถ. The name "access_token" is kept for historical reasons, so the issued token doesn't actually need to be an OAuth access token ๐.
issued_token_type
REQUIRED. An identifier, as described in Section 3, for the representation of the issued security token ๐ท๏ธ.
token_type
REQUIRED. This is a case-insensitive value that says how to use the access token that was issued, as specified in Section 7.1 of [RFC6749] ๐งพ. It tells the client how to use the access token to get into protected resources ๐ช. For example, a value of Bearer, as specified in [RFC6750], means the issued security token is a bearer token. The client can just present it as is, with no extra proof of eligibility beyond what's inside the token itself ๐. Note that this parameter means something different from issued_token_type. That one declares the representation of the issued security token. "Token type" usually means the structural or syntactical representation of the security token, and that's how it's used in every *_token_type parameter in this specification ๐ค. If the issued token isn't an access token or can't be used as one, then the token_type value N_A is used to say that an OAuth 2.0 token_type identifier doesn't apply in that context ๐
โโ๏ธ.
expires_in
RECOMMENDED. This is the validity lifetime, in seconds, of the token the authorization server issued โณ. A lot of the time the client won't have the time or ability to look inside the token, so this parameter gives a consistent indication of how long the token can be expected to be valid, no matter what kind of token it is ๐ฐ๏ธ. For example, the value 1800 means the token will expire thirty minutes after the response was generated ๐ซ.
scope
OPTIONAL if the scope of the issued security token is identical to the scope the client requested. Otherwise, it is REQUIRED ๐ฏ.
refresh_token
OPTIONAL. A refresh token usually won't be issued when the exchange swaps one temporary credential (the subject_token) for a different temporary credential (the issued token) to use in some other context ๐. A refresh token can be issued when the client of the token exchange needs to keep accessing a resource even after the original credential stops being valid ๐. Think user-not-present or offline scenarios, where there's no longer a user with an active session with the client ๐ด. Profiles or deployments of this specification should clearly document the conditions under which a client should expect a refresh token in response to "urn:ietf:params:oauth:grant-type:token-exchange" grant type requests ๐.
2.2.2. Error Response
If the request itself isn't valid, or if either the "subject_token" or the "actor_token" is invalid for any reason or unacceptable based on policy, the authorization server MUST construct an error response, as specified in Section 5.2 of [RFC6749] ๐จ. The value of the "error" parameter MUST be the invalid_request error code ๐.
If the authorization server is unwilling or unable to issue a token for any target service indicated by the "resource" or "audience" parameters, the invalid_target error code SHOULD be used in the error response ๐.
The authorization server MAY include more information about the reasons for the error using the "error_description", as discussed in Section 5.2 of [RFC6749] ๐.
Other error codes may also be used, as appropriate ๐ธ.
2.3. Example Token Exchange
This example shows a hypothetical token exchange where an OAuth resource server takes on the role of the client during the exchange ๐ญ. It trades an access token it got in a protected resource request for a new token, which it'll use to call a backend service ๐. The extra line breaks and indentation in the examples are just for display ๐ .
Figure 1 shows the resource server getting a protected resource request with an OAuth access token in the Authorization header, as specified in Section 2.1 of [RFC6750] ๐.
GET /resource HTTP/1.1
Host: frontend.example.com
Authorization: Bearer accVkjcJyb4BWCxGsndESCJQbdFMogUC5PbRDqceLTC
Figure 1: Protected Resource Request
In Figure 2, the resource server becomes the client for the token exchange ๐ฌ. The access token from the request in Figure 1 gets sent to the authorization server using a request as specified in Section 2.1 โ๏ธ. The subject_token parameter carries the access token, and the subject_token_type parameter says it's an OAuth 2.0 access token ๐๏ธ. The resource server, acting as the client, uses its identifier and secret to authenticate to the authorization server with the HTTP Basic authentication scheme ๐. The "resource" parameter points to where the backend service is, <https://backend.example.com/api>, which is where the issued token will be used ๐.
POST /as/token.oauth2 HTTP/1.1
Host: as.example.com
Authorization: Basic cnMwODpsb25nLXNlY3VyZS1yYW5kb20tc2VjcmV0
Content-Type: application/x-www-form-urlencoded
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange
&resource=https%3A%2F%2Fbackend.example.com%2Fapi
&subject_token=accVkjcJyb4BWCxGsndESCJQbdFMogUC5PbRDqceLTC
&subject_token_type=
urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Aaccess_token
Figure 2: Token Exchange Request
The authorization server checks the client credentials and the "subject_token" in the token exchange request ๐. From the "resource" parameter, it can figure out which policy to apply to the request, and then it issues a token that's good for <https://backend.example.com> ๐ง . The "access_token" parameter in the response shown in Figure 3 holds the new token ๐. It's a bearer OAuth access token that's valid for one minute โฑ๏ธ. The token happens to be a JWT, but its structure and format are opaque to the client, so issued_token_type only says it's an access token ๐คซ.
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-cache, no-store
{
"access_token":"eyJhbGciOiJFUzI1NiIsImtpZCI6IjllciJ9.eyJhdWQiOiJo
dHRwczovL2JhY2tlbmQuZXhhbXBsZS5jb20iLCJpc3MiOiJodHRwczovL2FzLmV
4YW1wbGUuY29tIiwiZXhwIjoxNDQxOTE3NTkzLCJpYXQiOjE0NDE5MTc1MzMsIn
N1YiI6ImJkY0BleGFtcGxlLmNvbSIsInNjb3BlIjoiYXBpIn0.40y3ZgQedw6rx
f59WlwHDD9jryFOr0_Wh3CGozQBihNBhnXEQgU85AI9x3KmsPottVMLPIWvmDCM
y5-kdXjwhw",
"issued_token_type":
"urn:ietf:params:oauth:token-type:access_token",
"token_type":"Bearer",
"expires_in":60
}
Figure 3: Token Exchange Response
The resource server can then use the new access token to make a request to the backend server, as shown in Figure 4 ๐.
GET /api HTTP/1.1
Host: backend.example.com
Authorization: Bearer eyJhbGciOiJFUzI1NiIsImtpZCI6IjllciJ9.eyJhdWQ
iOiJodHRwczovL2JhY2tlbmQuZXhhbXBsZS5jb20iLCJpc3MiOiJodHRwczovL2
FzLmV4YW1wbGUuY29tIiwiZXhwIjoxNDQxOTE3NTkzLCJpYXQiOjE0NDE5MTc1M
zMsInN1YiI6ImJkY0BleGFtcGxlLmNvbSIsInNjb3BlIjoiYXBpIn0.40y3ZgQe
dw6rxf59WlwHDD9jryFOr0_Wh3CGozQBihNBhnXEQgU85AI9x3KmsPottVMLPIW
vmDCMy5-kdXjwhw
Figure 4: Backend Protected Resource Request
More examples are in Appendix A ๐โจ.
3. Token Type Identifiers โจ
okay bestie, so a few params in this spec need a little label that says what kind of token you're dealing with ๐. Those are requested_token_type, subject_token_type, and actor_token_type in the request, plus the issued_token_type member in the response ๐
. And these labels are URIs ๐ฆ. Token exchange can handle tokens from other parties AND tokens from the authorization server itself ๐ซถ. For the outside tokens, the label tells the authorization server what syntax it's looking at (like JWT or SAML 2.0) so it can actually parse it ๐ง. For its own tokens, the label says what it issued that token for, like "access_token" or "refresh_token" ๐ธ.
The following token type identifiers are defined by this specification, and other URIs MAY be used to indicate other token types ๐.
urn:ietf:params:oauth:token-type:access_tokenmeans the token is an OAuth 2.0 access token issued by the given authorization server ๐ฅ.urn:ietf:params:oauth:token-type:refresh_tokenmeans the token is an OAuth 2.0 refresh token issued by the given authorization server ๐.urn:ietf:params:oauth:token-type:id_tokenmeans the token is an ID Token as defined in Section 2 of [OpenID.Core] ๐ช.urn:ietf:params:oauth:token-type:saml1means the token is a base64url-encoded SAML 1.1 [OASIS.saml-core-1.1] assertion ๐.urn:ietf:params:oauth:token-type:saml2means the token is a base64url-encoded SAML 2.0 [OASIS.saml-core-2.0-os] assertion ๐.
The value urn:ietf:params:oauth:token-type:jwt, which is defined in Section 9 of [JWT], means the token is a JWT ๐ฆ.
Now the distinction between an access token and a JWT is kind of subtle, so listen up ๐โจ. An access token represents a delegated authorization decision, whereas a JWT is a token format ๐
. An access token can be formatted as a JWT but doesn't have to be. And a JWT might totally be an access token, but not every JWT is one ๐. The whole point of urn:ietf:params:oauth:token-type:access_token is to say "this is a typical OAuth access token from the authorization server in question, opaque to the client, and usable the same way as any other access token from that server" ๐. (It could be a JWT under the hood, but the client isn't and doesn't need to be aware of that ๐คซ.) Meanwhile, urn:ietf:params:oauth:token-type:jwt is for saying specifically that a JWT is being requested or sent ๐ง. That might happen in a cross-domain situation where the JWT is used as an authorization grant to get an access token from a different authorization server, which is what [RFC7523] makes possible ๐ธ.
Note that for tokens that are binary in nature, the URI used to convey them needs to be tied to the semantics of a base64 or other encoding that's suitable for use with HTTP and OAuth ๐.
4. JSON Web Token Claims and Introspection Response Parameters ๐
It's really useful to have defined ways to express delegation inside a token, as well as ways to express permission to delegate or impersonate ๐ซถ. The token exchange protocol here works with any type of token, but this section defines claims for those semantics specifically for JWTs and for OAuth 2.0 Token Introspection [RFC7662] responses โจ. Similar definitions for other token types are possible, but they're out of scope for this spec ๐.
Quick note: the claims that aren't defined here but show up in examples and descriptions, like "iss", "sub", and "exp", are defined by [JWT] ๐.
4.1. "act" (Actor) Claim
The "act" (actor) claim is how a JWT says "delegation happened, and here's who the acting party is" ๐. Its value is a JSON object, and the members of that object are claims that identify the actor ๐ . The claims inside "act" identify the actor and might give extra info about them. For example, you might need both "iss" and "sub" together to uniquely identify an actor ๐ฅ.
However, claims inside the "act" claim are only about who the actor is ๐ซฃ. They aren't relevant to whether the containing JWT is valid the way top-level claims are. So non-identity claims (like "exp", "nbf", and "aud") don't mean anything inside "act", and they're not used there ๐ โโ๏ธ.
Figure 5 shows the "act" (actor) claim inside a JWT Claims Set ๐ฆ. The token's own claims are about user@example.com, and the "act" claim says admin@example.com is the current actor ๐.
{
"aud":"https://consumer.example.com",
"iss":"https://issuer.example.com",
"exp":1443904177,
"nbf":1443904077,
"sub":"user@example.com",
"act":
{
"sub":"admin@example.com"
}
}
Figure 5: Actor Claim
You can chain delegation by nesting one "act" claim inside another ๐ง. The outermost "act" is the current actor, and nested "act" claims are prior actors ๐ธ. The least recent actor is the most deeply nested ๐. The nested ones act like a history trail, connecting the original request and subject through every delegation step before the current actor โจ. So the current actor is considered to include the whole authorization and delegation history, which is why the nested structure makes total sense ๐ค.
Okay, this next part is super important ๐จ. For applying access control policy, the consumer of a token MUST only consider the token's top-level claims and the party identified as the current actor by the "act" claim ๐. Prior actors from any nested "act" claims are informational only, and they are not to be considered in access control decisions ๐ โโ๏ธ.
Figure 6 shows nested "act" (actor) claims inside a JWT Claims Set ๐. The token's claims are about user@example.com, while the "act" claim says the system <https://service16.example.com> is the current actor and <https://service77.example.com> was a prior actor ๐ซถ. A token like this might come from service16 getting a token in a call from service77, then exchanging it for a token that works for calling service26, with the authorization server noting the whole situation in the newly issued token ๐.
{
"aud":"https://service26.example.com",
"iss":"https://issuer.example.com",
"exp":1443904100,
"nbf":1443904000,
"sub":"user@example.com",
"act":
{
"sub":"https://service16.example.com",
"act":
{
"sub":"https://service77.example.com"
}
}
}
Figure 6: Nested Actor Claim
When "act" is included as a top-level member of an OAuth token introspection response, it has the same semantics and format as the claim with the same name ๐ .
4.2. "scope" (Scopes) Claim
The value of the "scope" claim is a JSON string holding a space-separated list of scopes associated with the token, in the format described in Section 3.3 of [RFC6749] ๐ฆ.
Figure 7 shows the "scope" claim inside a JWT Claims Set โจ.
{
"aud":"https://consumer.example.com",
"iss":"https://issuer.example.com",
"exp":1443904177,
"nbf":1443904077,
"sub":"dgaf4mvfs75Fci_FL3heQA",
"scope":"email profile phone address"
}
Figure 7: Scopes Claim
OAuth 2.0 Token Introspection [RFC7662] already defines the "scope" parameter for conveying the scopes associated with the token ๐.
4.3. "client_id" (Client Identifier) Claim
The "client_id" claim carries the client identifier of the OAuth 2.0 [RFC6749] client that requested the token ๐ธ.
Figure 8 shows the "client_id" claim inside a JWT Claims Set, for an OAuth 2.0 client whose identifier is "s6BhdRkqt3" ๐ง.
{
"aud":"https://consumer.example.com",
"iss":"https://issuer.example.com",
"exp":1443904177,
"sub":"user@example.com",
"client_id":"s6BhdRkqt3"
}
Figure 8: Client Identifier Claim
OAuth 2.0 Token Introspection [RFC7662] already defines the "client_id" parameter as the client identifier for the OAuth 2.0 client that requested the token ๐ซถ.
4.4. "may_act" (Authorized Actor) Claim
The "may_act" claim makes a statement that one party is authorized to become the actor and act on behalf of another party ๐. For example, it can come into play when a "subject_token" is presented to the token endpoint in a token exchange request. The authorization server can then use the "may_act" claim in the subject token to figure out whether the client (or the party identified in the "actor_token") is allowed to do the requested delegation or impersonation ๐. The claim value is a JSON object, and its members are claims identifying the party being asserted as eligible to act for the party identified by the JWT containing the claim ๐ . The claims in "may_act" identify that authorized actor and might provide extra info about them. For instance, "iss" and "sub" together are sometimes needed to uniquely identify an authorized actor, while the "email" claim might add useful details about that party ๐ง.
Claims inside "may_act" are only about that party's identity ๐ซฃ. They aren't relevant to the validity of the containing JWT the way top-level claims are. So claims like "exp", "nbf", and "aud" aren't meaningful inside "may_act", and they're not used there ๐ โโ๏ธ.
Figure 9 shows the "may_act" claim inside a JWT Claims Set ๐ฆ. The token's claims are about user@example.com, while the "may_act" claim says admin@example.com is authorized to act on behalf of user@example.com ๐.
{
"aud":"https://consumer.example.com",
"iss":"https://issuer.example.com",
"exp":1443904177,
"nbf":1443904077,
"sub":"user@example.com",
"may_act":
{
"sub":"admin@example.com"
}
}
Figure 9: Authorized Actor Claim
When "may_act" is included as a top-level member of an OAuth token introspection response, it has the same semantics and format as the claim with the same name ๐.
5. Security Considerations ๐
Okay, bestie, security is serious business, so read this part carefully ๐ฅบ. A lot of the guidance from Section 10 of [RFC6749], the Security Considerations in The OAuth 2.0 Authorization Framework, also applies here ๐. On top of that, [RFC6819] has extra security considerations for OAuth, and [OAUTH-SECURITY] has updated guidance based on real deployment experience and newer threats that showed up after OAuth 2.0 was first published ๐จ.
All of the normal security issues discussed in [JWT] also apply here, especially around comparing URIs and dealing with unrecognized values ๐.
And here's the big one ๐ฑ. Both delegation and impersonation bring their own unique security issues. Any time one principal gets the rights of another principal, there's potential for abuse, and that's a real concern ๐ซฃ. Using the "scope" claim (along with other usual constraints, like a limited token lifetime) is suggested to reduce the potential for that abuse, because it restricts the contexts where the delegated rights can be used ๐โจ.
6. Privacy Considerations ๐
Okay, privacy is a whole vibe, bestie ๐ซฃ. Tokens for this stuff can carry privacy-sensitive info, so they MUST only be sent over encrypted channels like Transport Layer Security (TLS) ๐. If you need to keep certain info away from the client, the token MUST be encrypted to its intended recipient ๐. Deployments SHOULD figure out the minimum amount of data they need and only put that in the tokens they issue ๐ . Sometimes data minimization even means only representing an anonymous or pseudonymous user ๐ฆ.
7. IANA Considerations ๐
7.1. OAuth URI Registration
IANA registered the following values in the "OAuth URI" subregistry of the "OAuth Parameters" registry [IANA.OAuth.Parameters]. That subregistry was set up by [RFC6755] ๐ธ.
- URN:
urn:ietf:params:oauth:grant-type:token-exchange- Common Name: Token exchange grant type for OAuth 2.0
- Change Controller: IESG
- Specification Document: Section 2.1 of RFC 8693
- URN:
urn:ietf:params:oauth:token-type:access_token- Common Name: Token type URI for an OAuth 2.0 access token
- Change Controller: IESG
- Specification Document: Section 3 of RFC 8693
- URN:
urn:ietf:params:oauth:token-type:refresh_token- Common Name: Token type URI for an OAuth 2.0 refresh token
- Change Controller: IESG
- Specification Document: Section 3 of RFC 8693
- URN:
urn:ietf:params:oauth:token-type:id_token- Common Name: Token type URI for an ID Token
- Change Controller: IESG
- Specification Document: Section 3 of RFC 8693
- URN:
urn:ietf:params:oauth:token-type:saml1- Common Name: Token type URI for a base64url-encoded SAML 1.1 assertion
- Change Controller: IESG
- Specification Document: Section 3 of RFC 8693
- URN:
urn:ietf:params:oauth:token-type:saml2- Common Name: Token type URI for a base64url-encoded SAML 2.0 assertion
- Change Controller: IESG
- Specification Document: Section 3 of RFC 8693
7.2. OAuth Parameters Registration
IANA registered the following values in the "OAuth Parameters" subregistry of the "OAuth Parameters" registry [IANA.OAuth.Parameters]. That subregistry was set up by [RFC6749] โจ.
- Parameter name:
audience- Parameter usage location: token request
- Change controller: IESG
- Specification document(s): Section 2.1 of RFC 8693
- Parameter name:
requested_token_type- Parameter usage location: token request
- Change controller: IESG
- Specification document(s): Section 2.1 of RFC 8693
- Parameter name:
subject_token- Parameter usage location: token request
- Change controller: IESG
- Specification document(s): Section 2.1 of RFC 8693
- Parameter name:
subject_token_type- Parameter usage location: token request
- Change controller: IESG
- Specification document(s): Section 2.1 of RFC 8693
- Parameter name:
actor_token- Parameter usage location: token request
- Change controller: IESG
- Specification document(s): Section 2.1 of RFC 8693
- Parameter name:
actor_token_type- Parameter usage location: token request
- Change controller: IESG
- Specification document(s): Section 2.1 of RFC 8693
- Parameter name:
issued_token_type- Parameter usage location: token response
- Change controller: IESG
- Specification document(s): Section 2.2.1 of RFC 8693
7.3. OAuth Access Token Type Registration
IANA registered the following access token type in the "OAuth Access Token Types" subregistry of the "OAuth Parameters" registry [IANA.OAuth.Parameters]. That subregistry was set up by [RFC6749] ๐ง.
- Type name:
N_A- Additional Token Endpoint Response Parameters: none
- HTTP Authentication Scheme(s): none
- Change controller: IESG
- Specification document(s): Section 2.2.1 of RFC 8693
7.4. JSON Web Token Claims Registration
IANA registered the following Claims in the "JSON Web Token Claims" subregistry of the "JSON Web Token (JWT)" registry [IANA.JWT]. That subregistry was set up by [JWT] ๐.
- Claim Name:
act- Claim Description: Actor
- Change Controller: IESG
- Specification Document(s): Section 4.1 of RFC 8693
- Claim Name:
scope- Claim Description: Scope Values
- Change Controller: IESG
- Specification Document(s): Section 4.2 of RFC 8693
- Claim Name:
client_id- Claim Description: Client Identifier
- Change Controller: IESG
- Specification Document(s): Section 4.3 of RFC 8693
- Claim Name:
may_act- Claim Description: Authorized Actor - the party that is authorized to become the actor
- Change Controller: IESG
- Specification Document(s): Section 4.4 of RFC 8693
7.5. OAuth Token Introspection Response Registration
IANA registered the following values in the "OAuth Token Introspection Response" registry of the "OAuth Parameters" registry [IANA.OAuth.Parameters]. That registry was set up by [RFC7662] ๐ฆ.
- Name:
act- Description: Actor
- Change Controller: IESG
- Specification Document(s): Section 4.1 of RFC 8693
- Name:
may_act- Description: Authorized Actor - the party that is authorized to become the actor
- Change Controller: IESG
- Specification Document(s): Section 4.4 of RFC 8693
8. References ๐
8.1. Normative References
[IANA.JWT]IANA, "JSON Web Token (JWT)",<https://www.iana.org/assignments/jwt>.[IANA.OAuth.Parameters]IANA, "OAuth Parameters",<https://www.iana.org/assignments/oauth-parameters>.[JWT]Jones, M., Bradley, J., and N. Sakimura, "JSON Web Token (JWT)", RFC 7519, DOI 10.17487/RFC7519, May 2015,<https://www.rfc-editor.org/info/rfc7519>.[RFC2119]Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997,<https://www.rfc-editor.org/info/rfc2119>.[RFC3986]Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, DOI 10.17487/RFC3986, January 2005,<https://www.rfc-editor.org/info/rfc3986>.[RFC6749]Hardt, D., Ed., "The OAuth 2.0 Authorization Framework", RFC 6749, DOI 10.17487/RFC6749, October 2012,<https://www.rfc-editor.org/info/rfc6749>.[RFC7662]Richer, J., Ed., "OAuth 2.0 Token Introspection", RFC 7662, DOI 10.17487/RFC7662, October 2015,<https://www.rfc-editor.org/info/rfc7662>.[RFC8174]Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017,<https://www.rfc-editor.org/info/rfc8174>.[RFC8259]Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", STD 90, RFC 8259, DOI 10.17487/RFC8259, December 2017,<https://www.rfc-editor.org/info/rfc8259>.
8.2. Informative References
[OASIS.saml-core-1.1]Maler, E., Mishra, P., and R. Philpott, "Assertions and Protocol for the OASIS Security Assertion Markup Language (SAML) V1.1", OASIS Standard oasis-sstc-saml-core-1.1, September 2003,<https://www.oasis-open.org/committees/download.php/3406/oasis-sstc-saml-core-1.1.pdf>.[OASIS.saml-core-2.0-os]Cantor, S., Kemp, J., Philpott, R., and E. Maler, "Assertions and Protocol for the OASIS Security Assertion Markup Language (SAML) V2.0", OASIS Standard saml-core-2.0-os, March 2005,<http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf>.[OAUTH-RESOURCE]Campbell, B., Bradley, J., and H. Tschofenig, "Resource Indicators for OAuth 2.0", Work in Progress, Internet-Draft, draft-ietf-oauth-resource-indicators-08, 11 September 2019,<https://tools.ietf.org/html/draft-ietf-oauth-resource-indicators-08>.[OAUTH-SECURITY]Lodderstedt, T., Bradley, J., Labunets, A., and D. Fett, "OAuth 2.0 Security Best Current Practice", Work in Progress, Internet-Draft, draft-ietf-oauth-security-topics-13, 8 July 2019,<https://tools.ietf.org/html/draft-ietf-oauth-security-topics-13>.[OpenID.Core]Sakimura, N., Bradley, J., Jones, M., de Medeiros, B., and C. Mortimore, "OpenID Connect Core 1.0", November 2014,<https://openid.net/specs/openid-connect-core-1_0.html>.[RFC6750]Jones, M. and D. Hardt, "The OAuth 2.0 Authorization Framework: Bearer Token Usage", RFC 6750, DOI 10.17487/RFC6750, October 2012,<https://www.rfc-editor.org/info/rfc6750>.[RFC6755]Campbell, B. and H. Tschofenig, "An IETF URN Sub-Namespace for OAuth", RFC 6755, DOI 10.17487/RFC6755, October 2012,<https://www.rfc-editor.org/info/rfc6755>.[RFC6819]Lodderstedt, T., Ed., McGloin, M., and P. Hunt, "OAuth 2.0 Threat Model and Security Considerations", RFC 6819, DOI 10.17487/RFC6819, January 2013,<https://www.rfc-editor.org/info/rfc6819>.[RFC7521]Campbell, B., Mortimore, C., Jones, M., and Y. Goland, "Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants", RFC 7521, DOI 10.17487/RFC7521, May 2015,<https://www.rfc-editor.org/info/rfc7521>.[RFC7523]Jones, M., Campbell, B., and C. Mortimore, "JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants", RFC 7523, DOI 10.17487/RFC7523, May 2015,<https://www.rfc-editor.org/info/rfc7523>.[WS-Trust]Nadalin, A., Ed., Goodner, M., Ed., Gudgin, M., Ed., Barbir, A., Ed., and H. Granqvist, Ed., "WS-Trust 1.4", February 2012,<https://docs.oasis-open.org/ws-sx/ws-trust/v1.4/ws-trust.html>.
Appendix A. Additional Token Exchange Examples ๐
Okay, so there are two example token exchanges coming up in the next sections, one for impersonation and one for delegation ๐ซถ. I added extra line breaks and indentation so they're easier to read, but that's just for display, promise โจ.
A.1. Impersonation Token Exchange Example
A.1.1. Token Exchange Request โจ
okay so in this one, the client is asking for a token with impersonation semantics ๐ญ (delegation is impossible with only a "subject_token" and no "actor_token"). It tells the authorization server that it needs a token for use at the target service with the logical name "urn:example:cooperation-context" ๐ง
POST /as/token.oauth2 HTTP/1.1
Host: as.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange
&audience=urn%3Aexample%3Acooperation-context
&subject_token=eyJhbGciOiJFUzI1NiIsImtpZCI6IjE2In0.eyJhdWQiOiJodHRwc
zovL2FzLmV4YW1wbGUuY29tIiwiaXNzIjoiaHR0cHM6Ly9vcmlnaW5hbC1pc3N1ZXI
uZXhhbXBsZS5uZXQiLCJleHAiOjE0NDE5MTA2MDAsIm5iZiI6MTQ0MTkwOTAwMCwic
3ViIjoiYmRjQGV4YW1wbGUubmV0Iiwic2NvcGUiOiJvcmRlcnMgcHJvZmlsZSBoaXN
0b3J5In0.PRBg-jXn4cJuj1gmYXFiGkZzRuzbXZ_sDxdE98ddW44ufsbWLKd3JJ1VZ
hF64pbTtfjy4VXFVBDaQpKjn5JzAw
&subject_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Ajwt
Figure 10: Token Exchange Request
A.1.2. Subject Token Claims ๐
the "subject_token" in that request is a JWT ๐ and here's the decoded JWT Claims Set. The JWT is meant for the authorization server to consume within a specific time window โฐ. The subject of the JWT ("bdc@example.net") is the party the new token is being requested on behalf of ๐
{
"aud":"https://as.example.com",
"iss":"https://original-issuer.example.net",
"exp":1441910600,
"nbf":1441909000,
"sub":"bdc@example.net",
"scope":"orders profile history"
}
Figure 11: Subject Token Claims
A.1.3. Token Exchange Response ๐
the "access_token" parameter in the response below holds the new token the client asked for ๐ The other parameters tell you it's a bearer access token that expires in an hour โณ
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-cache, no-store
{
"access_token":"eyJhbGciOiJFUzI1NiIsImtpZCI6IjcyIn0.eyJhdWQiOiJ1cm4
6ZXhhbXBsZTpjb29wZXJhdGlvbi1jb250ZXh0IiwiaXNzIjoiaHR0cHM6Ly9hcy5l
eGFtcGxlLmNvbSIsImV4cCI6MTQ0MTkxMzYxMCwic3ViIjoiYmRjQGV4YW1wbGUub
mV0Iiwic2NvcGUiOiJvcmRlcnMgcHJvZmlsZSBoaXN0b3J5In0.rMdWpSGNACTvnF
uOL74sYZ6MVuld2Z2WkGLmQeR9ztj6w2OXraQlkJmGjyiCq24kcB7AI2VqVxl3wSW
nVKh85A",
"issued_token_type":
"urn:ietf:params:oauth:token-type:access_token",
"token_type":"Bearer",
"expires_in":3600
}
Figure 12: Token Exchange Response
A.1.4. Issued Token Claims ๐
here are the decoded JWT Claims Set details for the issued token ๐ The authorization server issued this new JWT, and it's meant for a system entity known by the logical name "urn:example:cooperation-context", any time before it expires. The "sub" of the JWT matches the subject of the token used in the request. That's what effectively lets the client impersonate that subject at the system entity known by the logical name "urn:example:cooperation-context" when it uses the token ๐
{
"aud":"urn:example:cooperation-context",
"iss":"https://as.example.com",
"exp":1441913610,
"sub":"bdc@example.net",
"scope":"orders profile history"
}
Figure 13: Issued Token Claims
A.2. Delegation Token Exchange Example ๐ค
A.2.1. Token Exchange Request ๐
in this request, the client wants a token and is giving both a "subject_token" and an "actor_token" ๐ซถ It tells the authorization server that it needs a token for use at the target service with the logical name "urn:example:cooperation-context". Policy at the authorization server says the issued token has to be a composite ๐งฉ
POST /as/token.oauth2 HTTP/1.1
Host: as.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange
&audience=urn%3Aexample%3Acooperation-context
&subject_token=eyJhbGciOiJFUzI1NiIsImtpZCI6IjE2In0.eyJhdWQiOiJodHRwc
zovL2FzLmV4YW1wbGUuY29tIiwiaXNzIjoiaHR0cHM6Ly9vcmlnaW5hbC1pc3N1ZXI
uZXhhbXBsZS5uZXQiLCJleHAiOjE0NDE5MTAwNjAsInNjb3BlIjoic3RhdHVzIGZlZ
WQiLCJzdWIiOiJ1c2VyQGV4YW1wbGUubmV0IiwibWF5X2FjdCI6eyJzdWIiOiJhZG1
pbkBleGFtcGxlLm5ldCJ9fQ.4rPRSWihQbpMIgAmAoqaJojAxj-p2X8_fAtAGTXrvM
xU-eEZHnXqY0_AOZgLdxw5DyLzua8H_I10MCcckF-Q_g
&subject_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Ajwt
&actor_token=eyJhbGciOiJFUzI1NiIsImtpZCI6IjE2In0.eyJhdWQiOiJodHRwczo
vL2FzLmV4YW1wbGUuY29tIiwiaXNzIjoiaHR0cHM6Ly9vcmlnaW5hbC1pc3N1ZXIuZ
XhhbXBsZS5uZXQiLCJleHAiOjE0NDE5MTAwNjAsInN1YiI6ImFkbWluQGV4YW1wbGU
ubmV0In0.7YQ-3zPfhUvzje5oqw8COCvN5uP6NsKik9CVV6cAOf4QKgM-tKfiOwcgZ
oUuDL2tEs6tqPlcBlMjiSzEjm3yBg
&actor_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Ajwt
Figure 14: Token Exchange Request
A.2.2. Subject Token Claims ๐
the "subject_token" in that request is a JWT, and the decoded JWT Claims Set is right here ๐ This JWT is meant for the authorization server to consume before a specific expiration time. The subject of the JWT ("user@example.net") is the party the new token is being requested on behalf of ๐ธ
{
"aud":"https://as.example.com",
"iss":"https://original-issuer.example.net",
"exp":1441910060,
"scope":"status feed",
"sub":"user@example.net",
"may_act":
{
"sub":"admin@example.net"
}
}
Figure 15: Subject Token Claims
A.2.3. Actor Token Claims ๐ญ
the "actor_token" in that request is also a JWT, and here are its decoded JWT Claims Set details. It's meant for the authorization server to consume before a specific expiration time too โณ The subject of the JWT ("admin@example.net") is the actor who will wield the security token being requested ๐ฆ
{
"aud":"https://as.example.com",
"iss":"https://original-issuer.example.net",
"exp":1441910060,
"sub":"admin@example.net"
}
Figure 16: Actor Token Claims
A.2.4. Token Exchange Response ๐ฅณ
the "access_token" parameter in the response below holds the new token the client asked for ๐
The other parameters say it's a JWT that expires in an hour, and that the access token type doesn't apply because the issued token isn't an access token ๐
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-cache, no-store
{
"access_token":"eyJhbGciOiJFUzI1NiIsImtpZCI6IjcyIn0.eyJhdWQiOiJ1cm4
6ZXhhbXBsZTpjb29wZXJhdGlvbi1jb250ZXh0IiwiaXNzIjoiaHR0cHM6Ly9hcy5l
eGFtcGxlLmNvbSIsImV4cCI6MTQ0MTkxMzYxMCwic2NvcGUiOiJzdGF0dXMgZmVlZ
CIsInN1YiI6InVzZXJAZXhhbXBsZS5uZXQiLCJhY3QiOnsic3ViIjoiYWRtaW5AZX
hhbXBsZS5uZXQifX0.3paKl9UySKYB5ng6_cUtQ2qlO8Rc_y7Mea7IwEXTcYbNdwG
9-G1EKCFe5fW3H0hwX-MSZ49Wpcb1SiAZaOQBtw",
"issued_token_type":"urn:ietf:params:oauth:token-type:jwt",
"token_type":"N_A",
"expires_in":3600
}
Figure 17: Token Exchange Response
A.2.5. Issued Token Claims ๐
here are the decoded JWT Claims Set details for the issued token ๐ The authorization server issued this new JWT, and it's meant for a system entity known by the logical name "urn:example:cooperation-context", any time before it expires. The "sub" of the JWT matches the subject of the "subject_token" used in the request. The "act" of the JWT matches the subject of the "actor_token" used in the request. This shows delegation and names "admin@example.net" as the current actor, the one who's been given authority to act on behalf of "user@example.net" ๐
{
"aud":"urn:example:cooperation-context",
"iss":"https://as.example.com",
"exp":1441913610,
"scope":"status feed",
"sub":"user@example.net",
"act":
{
"sub":"admin@example.net"
}
}
Figure 18: Issued Token Claims
Acknowledgements ๐ซถ
this spec was developed within the OAuth Working Group, which has dozens of active and dedicated participants ๐ It was produced under the chairmanship of Hannes Tschofenig, Derek Atkins, and Rifaat Shekh-Yusef, with Kathleen Moriarty, Stephen Farrell, Eric Rescorla, Roman Danyliw, and Benjamin Kaduk serving as Security Area Directors ๐
the following individuals contributed ideas, feedback, and wording to this spec: Caleb Baker, Vittorio Bertocci, Mike Brown, Thomas Broyer, Roman Danyliw, William Denniss, Vladimir Dzhuvinov, Eric Fazendin, Phil Hunt, Benjamin Kaduk, Jason Keglovitz, Torsten Lodderstedt, Barry Leiba, Adam Lewis, James Manger, Nov Matake, Matt Miller, Hilarie Orman, Matthew Perry, Eric Rescorla, Justin Richer, Adam Roach, Rifaat Shekh-Yusef, Scott Tomilson, and Hannes Tschofenig ๐ธ thank you all, you're literally the best ๐ญ
Authors' Addresses ๐ฎ
Michael B. Jones
Microsoft
Email: mbj@microsoft.com
URI: https://self-issued.info/
Anthony Nadalin
Microsoft
Email: tonynad@microsoft.com
Brian Campbell (editor)
Ping Identity
Email: brian.d.campbell@gmail.com
John Bradley
Yubico
Email: ve7jtb@ve7jtb.com
Chuck Mortimore
Visa
Email: chuck.mortimore@visa.com
๐ฆ where this page comes from
- ietf: rfc8693 2020-01
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms