JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens
Extracted elements (29)
The profile does not provide a mechanism for clients to directly request specific claims in JWT access tokens; instead, the authorization server infers required claims from client_id, scope, and resource parameters. This preserves the authorization server's control over token content.
The profile mandates asymmetric signing (recommending RS256) to simplify key distribution: resource servers can retrieve public keys from AS metadata without a shared secret, enabling cross-vendor interoperability without out-of-band coordination.
Although both RFC 7523 and this document use JWTs in the OAuth 2.0 context, they serve different purposes: RFC 7523 defines how a JWT Bearer Token is used to request an access token, while RFC 9068 defines how access tokens themselves are encoded in JWT format.
Any additional identity attribute whose semantics are described in the IANA JWT registry SHOULD be encoded using the corresponding registered claim name. Arbitrary non-registered attributes may be included only if claim names are collision-resistant or tokens are used in private subsystems.
Authorization servers and resource servers conforming to this specification MUST include RS256 (as defined in RFC 7518) among their supported signature algorithms.
Authorization servers SHOULD use OAuth 2.0 Authorization Server Metadata (RFC 8414) to advertise signing keys via 'jwks_uri' and expected 'iss' value. If both OAuth 2.0 AS Metadata and OpenID Connect discovery are supported, their values MUST be consistent.
Authorization servers wanting to include roles, groups, or entitlements in a JWT access token SHOULD use the corresponding attributes from the SCIM 'User' resource schema defined in RFC 7643 Section 4.1.2 as claim types.
For access tokens from grants involving a resource owner (e.g., authorization code grant), 'sub' SHOULD correspond to the resource owner's subject identifier. For grants without a resource owner (e.g., client credentials), 'sub' SHOULD correspond to a client application identifier.
If a scope parameter is included in the authorization request, the issued JWT access token SHOULD include a 'scope' claim as defined in RFC 8693 Section 4.2. All individual scope strings MUST have meaning for the resources indicated in the 'aud' claim.
If JWT access token encryption was negotiated with the authorization server at registration time and the incoming token is not encrypted, the resource server SHOULD reject it.
If the authorization request includes a 'resource' parameter (RFC 8707), the resulting JWT access token 'aud' claim SHOULD have the same value. If no 'resource' parameter is present, the authorization server MUST use a default resource indicator in 'aud', potentially inferred from the 'scope' parameter.
JWT access tokens MUST be signed and MUST NOT use 'none' as the signing algorithm. Use of asymmetric cryptography is RECOMMENDED to simplify validation key retrieval for resource servers.
JWT access tokens MUST include the 'application/at+jwt' media type in the 'typ' header parameter. The 'typ' value used SHOULD be 'at+jwt' (omitting the 'application/' prefix per RFC 7515 Section 4.1.9).
Resource servers MUST verify that the 'typ' header value is 'at+jwt' or 'application/at+jwt' and reject tokens carrying any other value.
The authorization server MUST NOT issue a JWT access token if the authorization granted by the token would be ambiguous. If scope strings in a request refer to different default resource indicator values, the AS SHOULD reject the request with 'invalid_scope'.
The current time MUST be before the 'exp' claim value. Implementers MAY provide small leeway (usually no more than a few minutes) to account for clock skew. Validation failures MUST result in an 'invalid_token' error per RFC 6750 Section 3.1.
The resource server MUST validate that the 'aud' claim contains a resource indicator corresponding to an identifier it expects for itself and MUST reject the JWT access token if no such value is found.
The resource server MUST validate the signature of all incoming JWT access tokens per RFC 7515 using the algorithm in the 'alg' header. The resource server MUST reject any JWT in which 'alg' is 'none' and MUST use keys provided by the authorization server.
Clients MUST NOT inspect the content of access tokens; OAuth 2.0 treats them as opaque to clients. Authorization servers may switch from JWT to opaque tokens at any time, and logic depending on readable token content would break without recourse.
JWT access tokens are visible to clients and potentially end users (if unencrypted). Mitigations include encrypting the token, encrypting sensitive claims, omitting sensitive claims, or falling back to opaque access tokens.
The mandatory 'sub' claim enables resource servers to correlate requests. To prevent cross-resource-server tracking, authorization servers SHOULD assign distinct 'sub' values per resource server. To prevent within-resource correlation, distinct 'sub' and 'jti' values per token issuance may be required.
Authentication information claims 'auth_time', 'acr', and 'amr' (all defined in OpenID Connect Core) MAY be included when a resource owner is involved. Their values are fixed across all access tokens derived from a given authorization response, even after token refresh or exchange.
The JWT access token data structure requires the following REQUIRED claims: 'iss' (issuer), 'exp' (expiration), 'aud' (audience), 'sub' (subject), 'client_id' (as per RFC 8693 Section 4.3), 'iat' (issued at), and 'jti' (JWT ID).
This document registers the 'application/at+jwt' media type in the IANA Media Types registry to indicate content that is an OAuth 2.0 access token encoded in JWT format.
This document registers three new claims in the IANA 'JSON Web Token (JWT)' registry: 'roles', 'groups', and 'entitlements', sourced from RFC 7643 Section 4.1.2, for conveying authorization attributes in JWT access tokens.
Authorization servers MUST use a distinct identifier as the 'aud' claim value to uniquely identify access tokens issued for distinct resources, preventing cross-JWT confusion. Authorization servers should also prevent clients from controlling the 'sub' claim in ways that could impersonate high-privilege principals.
Resource servers must accept signatures made with any key published in AS metadata or OpenID Connect discovery, so an attacker compromising any one published key can forge valid tokens. Using distinct keys for ID Tokens vs. JWT access tokens does not meaningfully reduce attack surface.
To prevent cross-JWT confusion between OAuth 2.0 JWT access tokens and OpenID Connect ID Tokens, the 'typ' header parameter MUST be set to 'at+jwt', enabling resource servers to reject ID Tokens presented as access tokens. This follows the recommendations in RFC 8725.
The JWT access token header encodes 'typ' (set to 'at+JWT'), 'alg' (signing algorithm, e.g., 'RS256'), and 'kid' (key ID). Claims are encoded as base64url-separated-by-period JSON, as shown in the example: {"typ":"at+JWT","alg":"RS256","kid":"RjEwOwOA"}.