This page applies to Apigee and Apigee hybrid.
View Apigee Edge documentation.
This topic explains how to generate, verify, and refresh JWT access tokens using the OAuthV2 policy.
Introduction
The JWT operations allow the OAuthV2 policy to generate, verify, and refresh access tokens that conform to IETF RFC 9068, a standard that describes how to issue access tokens in JWT format. JWTs are commonly used to share claims or assertions between connected applications. Issuing OAuthV2 access tokens in JWT format is an alternative to issuing opaque access tokens.
When configured for JWT, the OAuthV2 policy generates and returns a Base64-encoded JWT that consists of a header, a payload, and a signature separated by dots. For example:
The encoded contents of these elements
depend on how you configure the OAuthV2 policy. In the policy, you specify such parameters as
the signing algorithm and payload elements like subject and name. For example, the header
might decode as {"alg":"HS256","typ":"at+JWT"}
, and the
payload might decode as: {"sub":"ABC1234567","iat":1516239022}
.
Header
The header specifies a typ
claim (always "at+JWT
) and the alg
claim, indicating the algorithm used to sign the JWT. Apigee
supports RSA and HMAC algorithms: RS(256,384,512) and HS(256,384,512).
Payload
The payload consists of claims about the entity. Some claims must be provided in the policy configuration, while others are automatically generated by the Apigee runtime. The policy supports the following claims:
Claim | Description | Provided by |
---|---|---|
iss |
The token issuer. This value is set as follows: (http|https)://{domain-name-for-proxy}/{proxy-basePath} . For
example: https://api.mycompany.com/auth/v2 . |
Apigee |
sub |
Either the Client ID or the ID of the resource owner (in the case of
password or authorization grant types). If the appEndUserId parameter is
provided in the request, that value is used as the resource owner ID. You can
control where this value is set using the
<AppEndUser> element
of the OAuthV2 policy. |
API developer |
jti |
A unique ID, represented as a UUID-backed random string to uniquely identify the token. | Apigee |
exp |
The expiry time, in other words the time after which the token must be considered invalid. The value is expressed in epoch time (in seconds). | Apigee |
iat |
The issued-at time, the time the token was created. The value is expressed in epoch time (in seconds). | Apigee |
client_id |
The unique identifier of the client application. | API developer |
scope |
The OAuth scope assigned to the token. See also Working with OAuth scopes. | API developer |
Signature
The signature is generated using the encoded header, payload, secret/private key, and the algorithm. The signature is used to ensure that the contents of the token have not been tampered with.
For more information about JWT-format OAuth 2.0 access tokens, see the IETF RFC 9068: JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens.
Prerequisites
This document assumes that you understand how to generate and verify OAuthV2 access tokens using the OAuthV2 policy. Whether you use the JWT operations or the traditional operations that create opaque string tokens, the basic use of the OAuthV2 policy is the same. You can use JWT access tokens with all of the supported OAuthV2 grant types. See also Introduction to OAuth 2.0.
Generating
Use the GenerateJWTAccessToken
and GenerateJWTAccessTokenImplicitGrant
operations to generate a JWT access token with the
OAuthV2 policy. These operations are similar to the policy's traditional GenerateAccessToken
and GenerateAccessTokenImplicitGrant
operations. The main difference is that the JWT operation returns a JWT-formatted access token
instead
of an opaque string token. See also Get OAuth 2.0 tokens.
The following examples show how to use these operations
in the OAuthV2 policy. The examples use the client_credentials
grant type; however, you can
use any of the supported grant types with these operations.
Generating a JWT-format token signed with an HMAC algorithm
Specify the <Algorithm>
element with one of the
HMAC (HS256/HS384/HS512) algorithms. Also provide the <SecretKey>
.
The following example shows a policy configured to generate a JWT signed with the HS512
algorithm, using the specified secret key.
<OAuthV2 name="generate-policy"> <Operation>GenerateJWTAccessToken</Operation> <SupportedGrantTypes> <GrantType>client_credentials</GrantType> </SupportedGrantTypes> <GenerateResponse enabled="true"/> <Algorithm>HS512</Algorithm> <SecretKey> <Value ref="private.mysecretkey"/> </SecretKey> <ExpiresIn ref="kvm.oauth.expires_in">3600000</ExpiresIn> </OAuthV2>
Generating a JWT-format token signed with an RSA algorithm
Specify one of the RSA algorithms (one of RS256/RS384/RS512) in the <Algorithm>
element, and provide
the private key in the <PrivateKey>
element. The following example shows a policy
configured to generate a JWT signed with an RSA private key using the RS256 algorithm.
<OAuthV2 name="generate-policy"> <Operation>GenerateJWTAccessToken</Operation> <SupportedGrantTypes> <GrantType>client_credentials</GrantType> </SupportedGrantTypes> <GenerateResponse enabled="true"/> <Algorithm>RS256</Algorithm> <PrivateKey> <Value ref="private.rsa-privatekey-1"/> </PrivateKey> <ExpiresIn ref="kvm.oauth.expires_in">3600000</ExpiresIn> </OAuthV2>
Generating a JWT-format token with the implicit grant type
The GenerateJWTAccessTokenImplicitGrant
operation generates a JWT access token
using the implicit grant type. It automatically gives the token the implicit grant type;
therefore, the <SupportedGrantTypes>
element is not required.
Because it is a JWT, the <Algorithm>
element is required. The following
example shows the use of the RS256 algorithm. Because of that, the <PrivateKey>
element is required. See also
Use the implicit grant type.
<OAuthV2 name="generate-policy"> <Operation>GenerateJWTAccessTokenImplicitGrant</Operation> <GenerateResponse enabled="true"/> <Algorithm>RS256</Algorithm> <PrivateKey> <Value ref="private.rsa-privatekey-1"/> </PrivateKey> <ExpiresIn ref="kvm.oauth.expires_in">3600000</ExpiresIn> </OAuthV2>
Verifying
Use the VerifyJWTAccessToken
operation to verify a JWT access token with the
OAuthV2 policy. This operation is similar to the VerifyAccessToken
operation; the difference is that VerifyJWTAccessToken
applies to tokens in JWT format,
while VerifyAccessToken
applies to opaque tokens.
Verifying a JWT access token signed with an HMAC algorithm
The following example shows how to configure the OAuthV2 policy to verify a JWT
token that was signed with the HS512 algorithm. When using the VerifyJWTAccessToken
operation
with an HMAC algorithm, the policy configuration must use the <SecretKey>
element
to specify the secret key that was used to sign the JWT.
<OAuthV2 name="OAuthV2-verify-jwt"> <Operation>VerifyJWTAccessToken</Operation> <Algorithm>HS512</Algorithm> <SecretKey> <Value ref="private.mysecretkey"/> </SecretKey> </OAuthV2>
Verifying a JWT access token signed with an RSA algorithm
The following example shows how to configure the OAuthV2 policy to verify a JWT
token that was signed with the RS512 algorithm. When using the VerifyJWTAccessToken
operation
with an RSA algorithm, the policy configuration must use the <PublicKey>
element
to specify the public key that corresponds to the private key that was used to sign the JWT.
<OAuthV2 name="OAuthV2-verify-jwt"> <Operation>VerifyJWTAccessToken</Operation> <Algorithm>RS512</Algorithm> <PublicKey> <Value ref="propertyset.non-secrets.rsa-publickey-1"/> </PublicKey> </OAuthV2>
Refreshing
Use the RefreshJWTAccessToken
operation to refresh a JWT access token.
This operation is similar to the policy's traditional RefreshAccessToken
operation. See also Refreshing an access token.
Refreshing an HMAC-signed access token
The following policy sample illustrates how to configure the OAuthV2 policy to refresh a JWT
token that was signed with an HMAC algorithm. The <SecretKey>
and <Algorithm>
elements are required in this case.
The response of the refresh operation is similar to the response of a newly generated token. The refresh operation generates a new JWT token with an updated expiry time, keeping other claims the same.
<OAuthV2 name="RefreshAccessToken"> <Operation>RefreshJWTAccessToken</Operation> <GenerateResponse enabled="true"/> <Algorithm>HS512</Algorithm> <SecretKey> <Value ref="private.mysecretkey"/> </SecretKey> <RefreshTokenExpiresIn ref="kvm.oauth.expires_in">3600000</RefreshTokenExpiresIn> </OAuthV2>
Refreshing an RSA-signed JWT access token
The following policy sample illustrates how to configure the OAuthV2 policy to refresh a JWT token that was signed with an RSA algorithm. See also Refreshing an access token.
<OAuthV2 name="RefreshAccessToken"> <Operation>RefreshJWTAccessToken</Operation> <GenerateResponse enabled="true"/> <Algorithm>RS256</Algorithm> <PrivateKey> <Value ref="private.rsa-privatekey-1"/> </PrivateKey> <RefreshTokenExpiresIn ref="kvm.oauth.expires_in">3600000</RefreshTokenExpiresIn> </OAuthV2>
Sample token response
For both generate and refresh operations, the response body looks similar to the following
example. Note that the access_token
is represented as a serialized JWT, and
the refresh token is a traditional opaque token.
{ "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6ImF0K0pXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c", "token_type": "Bearer", "developer.email": "developer@example.org", "token_type": "Bearer", "issued_at": "1658352381404", "expires_in": 1799, "refresh_token": "rVSmm3QaNa0xBVFbUISz1NZI15akvgLJ", "refresh_token_issued_at": "1658352381404", "refresh_token_expires_in": 86399, "refresh_token_status": "Approved", "refresh_count": "0", "organization_name": "cerruti", "api_product_list_json": [ "TestingProduct" ] }
Summary of required policy elements
The following table describes JWT-specific elements used in the preceding examples:
Element | Type | Notes |
---|---|---|
Algorithm | Static value | Specifies the algorithm used to sign the token. |
SecretKey | Referenced value | Provides the secret key used to verify or sign tokens with an HMAC algorithm: HS (256/384/512). |
PrivateKey | Referenced value | Provides the private key used to generate the token. Use only when the algorithm is an RSA algorithm: RS (256/384/512). |
PublicKey | Referenced value | Provides the public key used to verify the token. Use only when the algorithm is an RSA algorithm: RS (256/384/512). |
Unsupported policy elements
The following OAuthV2 policy elements are not supported with JWT token configurations:
Element | Notes |
---|---|
ExternalAuthorization | When generating a JWT access token, the OAuthV2 policy will validate the client ID and Secret. |
ExternalAccessToken | When generating a JWT access token, the token will be signed by Apigee and
the claims will be provided by Apigee either by default or through policy configuration.
The policy does support ExternalRefreshToken , which can aid in
migration use cases.
|
RFCCompliantRequestResponse | The generation and refresh of JWT access tokens is RFC compliant by default. |
Usage notes
- Encrypted JWTs are not supported.
- In addition to a JWT access token, the policy response also includes an opaque refresh token for grant types where refresh tokens are supported. Only the password and auth code grant types support refresh tokens.
- Include the Authorization header in requests sent to the proxy containing the OAuthV2 policy.
- You cannot revoke a JWT access token. The generated JWT token will remain valid until it expires. You can revoke a refresh token that is associated to a JWT access token.
- Generation, verification, and refresh of access tokens must be handled by Apigee. Although
an external application or gateway that has access to the public or secret key can decode
the contents of the JWT, the external application does not have information about the API products
that are identified by the
client_id
claim, and therefore cannot play a role in API proxy authorization.