en
Guides
Securing Applications
JWT Authorization Grant
enGuidesSecuring ApplicationsJwt Authorization Grant

JWT Authorization Grant

JWT Authorization Grant overview

This guide defines how a JWT Bearer Token can be used in NQRust-Identity as an authorization grant. This feature allows clients to send a JWT assertion to request an access token when the client wants to use an existing trust relationship without a direct user-approval step at the authorization server. The assertion is validated solely through the semantics of the JWT (its claims and signature). The trust relationship usually refers to another Identity Provider server (another OIDC server), and allows to obtain a cross-domain or cross-realm access token. In this sense, it is similar to the external to internal request in token exchange V1 (see Configuring and using token exchange for more information).

The JWT Authorization grant is specified by two different RFCs.

  • Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants (RFC 7521 (opens in a new tab)). General framework for using assertions as grants.
  • JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants (RFC 7523 (opens in a new tab)). Specifics for JWT assertions.

In short, the JWT Authorization is an OAuth extension grant as defined by OAuth 2.0 RFC 6749 (opens in a new tab) that is sent to the token endpoint. The grant_type request parameter must be urn:ietf:params:oauth:grant-type:jwt-bearer. The assertion must be a single JWT with some claims that will be validated by the server. The parameter scope is optional and maintains the same meaning described by Oauth 2.0 and managed by NQRust-Identity for other grants. If the assertion token is valid for authorization, an access token is returned to the client without any interaction to the authorization endpoint.

The trust relationship in NQRust-Identity is defined by an Identity Provider. Currently two Identity Provider types can manage JWT authorization grants:

  1. OpenID Connect v1.0 / NQRust-Identity OpenID Connect
  2. JWT Authorization Grant

OpenID Connect v1.0 (also the NQRust-Identity OpenID Connect which is just an extension of the previous type) can be used to define a trust relationship with an external OpenID Provider or OP (an OAuth 2.0 Authentication Servers implementing the OpenID Connect specification). This is the common choice. The received assertion will be processed using the provider configuration to validate the JWT token in terms of claims and signature.

The JWT Authorization Grant is a new type of Identity Provider in NQRust-Identity to represent a generic trust relationship. Similar to the previous type, its configuration allows to validate the assertion and obtain an access token using the JWT authorization grant.

NQRust-Identity requires the sub claim in the assertion to be the user identifier in the external provider. The NQRust-Identity user should be previously linked to the Identity Provider. This way there is a link between the external and the internal user ID.

The exact processing that NQRust-Identity performs over the assertion is the following (check the mentioned RFCs for more details about what requirements are needed in the assertion JWT):

  1. The requester client should be configured to allow JWT authorization grants.
  2. The claim iss (issuer) should identify the the Identity Provider (issuer configuration option).
  3. The Identity Provider should be configured to allow JWT authorization grants and the client should be configured to allow exchanging grants with this IdP.
  4. The claim sub (subject) should identify the user in NQRust-Identity. As commented, the sub claim needs to be the ID of the user in the external provider. The user in NQRust-Identity should be linked to the Identity Provider. The linking information will finally locate the user in NQRust-Identity.
  5. The claim aud (audience) should identify the NQRust-Identity server (issuer or token endpoint URL).
  6. The claim exp (expiration) should be present and validated.
  7. Other claims like nbf (not before), iat (issued at) and jti (JWT ID) can be present and should be validated in that case.
  8. The JWT should be signed and its signature should be verified with the keys associated to the identity provider in NQRust-Identity.

Brute force protection is not applied to the JWT Authorization Grant for temporarily locked users, since this grant type does not perform user credential-based authentication but relies on an assertion issued by an external identity provider, and therefore cannot be compromised by brute force attacks on credentials of NQRust-Identity user.

Examples

This is an example request for the JWT Authorization grant that is sent to the token endpoint. The client ID is test-client, it uses a secret to authenticate, and it is configured to allow JWT Authorization Grant to an Identity Provider whose issuer is https://jwt-idp.example.com.

POST /realms/demo/protocol/openid-connect/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Accept: application/json
 
client_id=test-client&
client_secret=XXXXX&
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&
assertion=eyJhbGci[...redacted...].eyJpc3Mi[...redacted...].J9l-ZhwP[...redacted...]

The important parameter is the assertion. Below is an example JSON object that can be encoded to produce the JWT Claims Set used inside the assertion.

{
  "jti":"abcd1234-5678-efgh-ijkl-9012mnopqrst",
  "iss":"https://jwt-idp.example.com",
  "sub":"b3588c7e-14cb-46a9-9387-28adfd82f7a4",
  "aud":"https://keycloak.server/realms/demo",
  "iat":1764839065,
  "exp":1764839365,
  "other-claim":true
}

Note the claims should contain iss that identifies the Identity Provider, sub that contains the user ID in the external system that will locate the NQRust-Identity user using the link to the provider, aud should be NQRust-Identity’s issuer or token endpoint, jti guarantees one-time use, and exp is mandatory. Other claims can be added to the token.

The previous JSON example should be signed and the JWT header should specify the algorithm and the key identifier used to sign it. That key needs to be correctly configured in the Identity Provider (via JWKS URL or manually) to validate the signature.

{"alg":"ES256", "kid":"2AOACLJmd5dQ8HPrDxwpkS-83yBhrzaLWSny9wmnYcY"}

NQRust-Identity will validate the request and assertion. If everything is correct, the response will contain an access token ready to be used.

{
  "access_token":"eyJhbG[...redacted...].eyJleH[...redacted...].RFnNEv[...redacted...]",
  "expires_in":300,
  "refresh_expires_in":0,
  "token_type":"Bearer",
  "not-before-policy":0,
  "scope":"email profile"
}

Following the spec recommendation, the JWT Authorization Grant never issues a refresh token and a transient session is always created. The access token can be used normally in NQRust-Identity through the introspection, user-info or any other endpoint. It will be valid until expired or explicitly revoked by the revocation endpoint.

How to get a valid token for JWT Authorization Grant

The JWT Authorization Grant feature needs a previous JWT assertion in order to be exchanged for an access token. We can name the external OpenID Connect Provider (OP) domaina, the one that is represented in NQRust-Identity via the Identity Provider. And we can name the NQRust-Identity server that receives the JWT authorization grant domainb. The domaina should somehow issue a JWT that is a valid assertion for domainb.

If domaina is a server different to NQRust-Identity, we don’t know how that initial JWT is obtained. But note that the specification enforces some processing of the assertion to be valid and return the access token. The way the client gets or generates such a JWT assertion in domaina depends completely on domaina server and client.

In case the external identity provider is another NQRust-Identity server or realm, Standard Token Exchange can be used to obtain such a token (see Configuring and using token exchange for more information). When both sides are NQRust-Identity realms, the idea can be summarized in two basic points:

  1. For domaina, domainb is an audience that can be restricted via token exchange.
  2. For domainb, domaina is an Identity Provider that is used to validate the assertion. The user in domainb is also a valid user previously linked to domaina via the identity provider.

OAuth Identity and Authorization Chaining Across Domains

Client policies and JWT Authorization Grant

New conditions and executions related to JWT Authorization Grant have been added to clients policies in NQRust-Identity.

  • Condition identity-provider-alias. This condition allows to select requests that involve a specific identity provider alias. A list of aliases can be defined, and the condition evaluates to true if one of the Identity Provider in the list is present. For the moment the condition only manages the JWT Authorization Grant but can be extended for future operations that involve Identity Providers.

  • Executor downscope-assertion-grant-enforcer. The executor enforces requested scopes to not exceed the scopes included in the assertion token (claim scope in the JWT). If a scope is requested that is not already present in the assertion, an error is returned. This executor should be used to prevent getting more privileges (scopes or audiences) than the ones granted in the initial assertion JWT (only downscoping is permitted).

    The enforcer can be used for any request that uses an assertion parameter. Currently it is used for assertion in the JWT Authorization Grant and subject_token in Standard Token Exchange.

  • Executor jwt-claim-enforcer. This executor allows to configure extra requirements for claims in the JWT assertion token. For example, if we want the assertion to contain an iat claim or a custom claim with a specific value. The configuration allows us to set any claim name and any claim value (using a java regex). If the claim in the JWT assertion does not match the regex, the request does not proceed and an error is returned.

    As the previous executor, for the moment this enforcer can be used for JWT Authorization Grant and the Standard Token exchange.

JWT Authorization Grant for Google Identity Provider

Google Identity Provider supports the JWT Authorization Grant, allowing the use of a Google ID Token as an assertion. According to RFC 7523, the assertion MUST be a JWT. Since Google issues JWTs only for ID Tokens (and not for access tokens), only the ID Token can be used for this authorization grant.

To enable this feature, the JWT Authorization Grant switch must be turned on in the Google Identity Provider configuration.

Google ID Token Payload Example

{
    "iss": "https://accounts.google.com", 
    "azp": "XXXX.apps.googleusercontent.com",
    "aud": "XXXX.apps.googleusercontent.com", 
    "sub": "100209199795938692365", 
    "at_hash": "AAos4eSIx4b5uQ8N-OAPYg",
    "iat": 1769503848,
    "exp": 1769507448 
}
  1. Google Issuer.
  2. Client ID that must be the same configured on the Google Identity Provider.
  3. Subject that must be linked to the NQRust-Identity user.
  4. Expires 1 hour after iat.

The specifications described in this guide also apply to Google, with the following exceptions:

  • Audience Validation: Google does not allow adding custom audiences to the ID Token. Therefore, the ID Token cannot contain the Token Endpoint URL or the NQRust-Identity Issuer URL. The aud (audience) claim must simply match the Client ID configured for the Google Identity Provider. This is the only deviation from RFC 7523.
  • Replay Check: It is not possible to perform a replay check because the jti claim is missing from the Google ID Token. Consequently, the same Google ID Token can be used multiple times.
  • Google ID Token Expiration: The duration of a Google ID Token is fixed at 1 hour and cannot be modified. To limit the validity window, a dedicated property in the configuration allows you to set a maximum time limit for the token. The default value is 1 hour (matching the Google ID Token lifespan).

In a scenario where a mobile application already supports login with Google without involving NQRust-Identity, there may be an issue when integrating NQRust-Identity later. For example, NQRust-Identity might be configured with a Google Identity Provider that uses a different Google client than the one used by the mobile app.

In this case, the Google ID token cannot be used with the JWT Authorization Grant because the aud claim in the ID Token does not match the client id configured in the Google Identity Provider.

To address this issue, you can use the Custom audience mapping configuration option commented in the client configuration section. For example, if the Identity Provider alias is google, the previous audience can be configured as valid with the following mapping.