> For the complete documentation index, see [llms.txt](/docs/llms.txt)

# JSON Web Tokens | FusionAuth Docs

Learn how FusionAuth provides and manages JSON Web Tokens.

# JSON Web Tokens

JSON Web Tokens (or JWT for short - pronounced "jot") is a standard defined as [RFC 7519](https://tools.ietf.org/html/rfc7519) that provides a portable unit of identity. FusionAuth implements the JWT specification and can provide JWTs as part of the authentication workflows.

If you are using OAuth grants for authentication, only the JWT signing configuration documentation applies.

Much of this tutorial is aimed at those using the Login API, not the hosted login pages.

For more on the OAuth grants and the tokens returned when using them, visit [the OAuth documentation](/docs/lifecycle/authenticate-users/oauth/).

After a User is authenticated via the [Login API](/docs/apis/login) or [OAuth](/docs/lifecycle/authenticate-users/oauth/), FusionAuth creates a JWT and returns it to the caller. This JWT will be cryptographically signed to allow other applications to verify that it was created by FusionAuth.

## Configuring JWTs in FusionAuth[#](#configuring-jwts-in-fusionauth)

FusionAuth provides the ability to configure a couple of aspects of its JWT handling. By navigating to Settings -> Tenants in FusionAuth and selecting the JWT tab, you will see the tenant JWT configuration settings.

The following is an example screenshot of the tenant JWT configuration.

![Tenant Configuration - JWT](/img/docs/tenant-configuration-jwt.png)

### JSON Web Token Settings[#](#json-web-token-settings)

`JWT duration`required

The length of time the issued token (access token and Id token) is valid. JWT tokens are typically short lived.

`Access token signing key`optional

The key used to sign the access token JWT.

`Id token signing key`optional

The key used to sign the Id token JWT.

### Refresh Token Settings[#](#refresh-token-settings)

`Refresh token duration`requiredDefaults to 43,200

The length of time the refresh token is valid. Refresh tokens are typically long lived.

`Refresh token expiration`optionalDefaults to Fixed

The **Refresh token expiration** may be one of the following:

*   **fixed window** (`Fixed`): expires a configurable time-to-live after *initial issuing*
*   **sliding window** (`SlidingWindow`): expires a configurable time-to-live after *the last time the refresh token was used*
*   **sliding window with a maximum lifetime** (`SlidingWindowWithMaximumLifetime`): combines the previous two options like an `OR` operator: expires a configurable time-to-live after *the last time the refresh token was used*, as long as it does not exceed a maximum lifetime after *initial issuing*

To configure the time-to-live, use `refreshTokenTimeToLiveInMinutes`; to configure the maximum lifetime, use `maximumTimeToLiveInMinutes`.

Consider a scenario where a refresh token is issued at 1:00, has an time-to-live of 60 minutes, and a maximum lifetime of 6 hours:

*   If the expiration is **fixed**, the token will expire at 2:00.
*   If the expiration is a **sliding window**, then if the refresh token is used at 1:55, it would then expire at 2:55. If it were then used at 2:50, it would expire at 3:50. This can continue *forever*, as long as the client always refreshes the token before 60 minutes have elapsed (good luck with daylight savings!).
*   If the expiration is a **sliding window with a maximum lifetime**, then if the refresh token is used at 1:55, it would then expire at 2:55. If it were then used at 2:50, it would expire at 3:50. This can continue until 7:00, when the refresh token passes the *maximum lifetime* and expires.

`Refresh token usage`optionalDefaults to Reusable

The **Refresh token usage** may be reusable or one time use. By default, a token is reusable and the token does not change after it was issued. With a one time use token, the token value will be changed each time the token is used to refresh a JWT. This means the client must store the new value after each use.

`One-time use grace period`optionalDefaults to 0

When **Refresh token usage** is set to `One-time use`, you may optionally set the grace period to something greater than `0` seconds.

The grace period is the length of time specified in seconds that a one time use token can be reused.

This value must be greater than `0` and less than `86400` which is equal to 24 hours. Setting this value to `0` effectively disables the grace period which means a one-time token may not be reused. For security reasons, you should keep this value as small as possible, and only increase past `0` to improve reliability for an asynchronous or clustered integration that may require a brief grace period.

Note that one-time use tokens refreshed within a grace period are not considered for revocation when the Tenant Refresh Token Revocation Policy is configured to revoke a one-time use refresh token on reuse. When a token is reused within the grace period the current token will be returned on the API response and the token will not be rotated.

`Refresh token revocation`optional

The events that cause refresh tokens to be revoked. The possible values are:

*   **On action preventing login** revokes all of a user's refresh tokens when a [user action](/docs/lifecycle/manage-users/user-actions) prevents login.
*   **On multi-factor enable** revokes all of a user's refresh tokens when a user enables [multi-factor authentication](/docs/lifecycle/authenticate-users/multi-factor-authentication) for the first time.
*   **On password change** revokes all of a user's refresh tokens when a user changes their password.
*   **On reuse of a one-time use token** which revokes the token, if and when a one-time use refresh token is reused outside of any configured grace period. Only the reused token is revoked; the rest of the user's tokens remain valid.

## Application Specific Configuration[#](#application-specific-configuration)

If you navigate to Applications from the main menu, you can also configure the JWT parameters, including the signing algorithm, on a per application basis. If you don't select to enable Application specific JWT configuration, the tenant configuration will be used.

The following is an example screenshot of an Application specific JWT configuration.

![Application JWT enabled](/img/docs/get-started/core-concepts/application-jwt-enabled-configuration.png)

### JSON Web Token Settings[#](#json-web-token-settings-1)

`Issuer`Read only

The issuer used in the `iss` claim when building the Access Token and Id Token. This is a read-only value in this configuration. It can be modified in the Tenant configuration.

`JWT duration`required

The duration in seconds for which a JWT will be valid after creation. After this time has passed the JWT will expire and can no longer be used.

`Access token signing key`optional

The signing key used to sign the Access Token (which is a JWT) when a user authentic The signing key used to sign the Access Token (which is a JWT) when a user authenticates against this Application. When this value is not selected, FusionAuth will generate a new key pair and assign it to this configuration.

`Id token signing key`optional

The signing key used to sign the Id Token (which is a JWT) when a user authenticates against this Application. When this value is not selected, FusionAuth will generate a new key pair and assign it to this configuration.

![Application Refresh Token configuration](/img/docs/get-started/core-concepts/application-jwt-enabled-refresh-token.png)

### Refresh Token Settings[#](#refresh-token-settings-1)

`Refresh token duration`requiredDefaults to 43,200

The length of time the refresh token is valid. Refresh tokens are typically long lived.

`Refresh token expiration`optionalDefaults to Fixed

The **Refresh token expiration** may be one of the following:

*   **fixed window** (`Fixed`): expires a configurable time-to-live after *initial issuing*
*   **sliding window** (`SlidingWindow`): expires a configurable time-to-live after *the last time the refresh token was used*
*   **sliding window with a maximum lifetime** (`SlidingWindowWithMaximumLifetime`): combines the previous two options like an `OR` operator: expires a configurable time-to-live after *the last time the refresh token was used*, as long as it does not exceed a maximum lifetime after *initial issuing*

To configure the time-to-live, use `refreshTokenTimeToLiveInMinutes`; to configure the maximum lifetime, use `maximumTimeToLiveInMinutes`.

Consider a scenario where a refresh token is issued at 1:00, has an time-to-live of 60 minutes, and a maximum lifetime of 6 hours:

*   If the expiration is **fixed**, the token will expire at 2:00.
*   If the expiration is a **sliding window**, then if the refresh token is used at 1:55, it would then expire at 2:55. If it were then used at 2:50, it would expire at 3:50. This can continue *forever*, as long as the client always refreshes the token before 60 minutes have elapsed (good luck with daylight savings!).
*   If the expiration is a **sliding window with a maximum lifetime**, then if the refresh token is used at 1:55, it would then expire at 2:55. If it were then used at 2:50, it would expire at 3:50. This can continue until 7:00, when the refresh token passes the *maximum lifetime* and expires.

`Refresh token usage`optionalDefaults to Reusable

The **Refresh token usage** may be reusable or one time use. By default, a token is reusable and the token does not change after it was issued. With a one time use token, the token value will be changed each time the token is used to refresh a JWT. This means the client must store the new value after each use.

`One-time use grace period`optionalDefaults to 0

When **Refresh token usage** is set to `One-time use`, you may optionally set the grace period to something greater than `0` seconds.

The grace period is the length of time specified in seconds that a one time use token can be reused.

This value must be greater than `0` and less than `86400` which is equal to 24 hours. Setting this value to `0` effectively disables the grace period which means a one-time token may not be reused. For security reasons, you should keep this value as small as possible, and only increase past `0` to improve reliability for an asynchronous or clustered integration that may require a brief grace period.

Note that one-time use tokens refreshed within a grace period are not considered for revocation when the Tenant Refresh Token Revocation Policy is configured to revoke a one-time use refresh token on reuse. When a token is reused within the grace period the current token will be returned on the API response and the token will not be rotated.

### Lambda Settings[#](#lambda-settings)

The application specific lambda settings are available even if you choose not to enable additional application specific JWT configuration by leaving the **Enable** field off.

`Access token populate lambda`optional

The lambda to be invoked during the generation of an Access Token (JWT) when a user authenticates against this Application.

`Id token populate lambda`optional

The lambda to be invoked during the generation of an Id Token (JWT) when a user authenticates against this Application.

Learn more about the [JWT Populate Lambda](/docs/extend/code/lambdas/jwt-populate).

## Configuring JWT Signing[#](#configuring-jwt-signing)

FusionAuth provides three configuration locations for JWT signing:

*   the tenant default values shown above
*   an Application level setting
*   with [Entity Management](/docs/get-started/core-concepts/entity-management), each entity type can have a unique key

FusionAuth supports configurations for HMAC, ECDSA (Elliptic Curve), EdDSA, or RSA based signing algorithms.

Keys are managed in [Key Master](/docs/operate/secure/key-master) and can be generated or imported there.

### Asymmetric Signing[#](#asymmetric-signing)

If you are using FusionAuth in a hybrid environment where applications may be untrusted, asymmetric signing using EdDSA, ECDSA, or RSA is preferred.

Using this approach allows you to provide applications with a public key to verify the JWT signature while securing the private key in FusionAuth.

Only the party that holds the private key can produce JWTs. It is easier to know for certain who issued and signed the JWT. It will be FusionAuth.

### HMAC Signing[#](#hmac-signing)

If you are in a secure environment and you require better performance, symmetric HMAC signing is best.

The downside of using HMAC signing is that each application requires access to the HMAC secret and you'll need to ensure it is distributed safely.

Anyone with the secret can both produce a JWT with a valid signature and verify the signature which makes it difficult to know for certain who issued and signed the JWT.

## Login and JWTs[#](#login-and-jwts)

When you complete a request to the [Login API](/docs/apis/login), FusionAuth will return a JWT in the JSON response body as well as in an HTTP Only session cookie. The cookie has the benefit of allowing web applications to authenticate directly against FusionAuth and managing JWT identities through the browser. The cookie name that the JWT is returned in is called `access_token`.

Here is an example of this `Set-Cookie` response header that includes a JWT with line breaks and spaces for readability.

Example HTTP Cookie Header

```
Set-Cookie: access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
                         eyJleHAiOjE0ODUxNDA5ODQsImlhdCI6MTQ4NTEzNzM4NCwiaXNzIjoiYWNtZS5jb20iLCJzdWIiOiIyOWFjMGMxOC0wYjRhLTQyY2YtODJmYy0wM2Q1NzAzMThhMWQiLCJhcHBsaWNhdGlvbklkIjoiNzkxMDM3MzQtOTdhYi00ZDFhLWFmMzctZTAwNmQwNWQyOTUyIiwicm9sZXMiOltdfQ.
                         Mp0Pcwsz5VECK11Kf2ZZNF_SMKu5CgBeLN9ZOP04kZo;
                         Secure; HttpOnly
```

The JSON response body will also contain the JWT in an attribute called `token` like this:

*Example JSON Response Body with JWT*

```
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0ODUxNDA5ODQsImlhdCI6MTQ4NTEzNzM4NCwiaXNzIjoiYWNtZS5jb20iLCJzdWIiOiIyOWFjMGMxOC0wYjRhLTQyY2YtODJmYy0wM2Q1NzAzMThhMWQiLCJhcHBsaWNhdGlvbklkIjoiNzkxMDM3MzQtOTdhYi00ZDFhLWFmMzctZTAwNmQwNWQyOTUyIiwicm9sZXMiOltdfQ.Mp0Pcwsz5VECK11Kf2ZZNF_SMKu5CgBeLN9ZOP04kZo",
  "user": {
    "active": true,
    "email": "example@fusionauth.io",
    "expiry": 1571786483322,
    "id": "00000000-0000-0001-0000-000000000000",
    "lastLoginInstant": 1471786483322,
    "passwordChangeRequired": false,
    "passwordLastUpdateInstant": 1471786483322,
    "verified": true
  }
}
```

### Skipping JWT Creation[#](#skipping-jwt-creation)

There are some circumstances where you don't need a JWT returned as part of the [Login API](/docs/apis/login) response and therefore you can instruct FusionAuth to omit the JWT from the response. This will reduce the latency of calling the [Login API](/docs/apis/login) because FusionAuth can skip the creation and signing of the JWT. To disable JWTs during authentication, supply the `noJWT` parameter in the JSON request body on the [Login API](/docs/apis/login/authenticate).

## JWT Payload[#](#jwt-payload)

FusionAuth provides a few custom claims in addition to some registered claims as defined by [RFC 7519 Section 4.1](https://tools.ietf.org/html/rfc7519#section-4.1). The following claims will be found in a JWT issued by FusionAuth.

### Claims[#](#claims)

`applicationId`UUID

The unique Id of the Application for which the user has been authenticated. This claim is only present if the user is registered for the application.

`aud`String

The audience the JWT is intended for. This registered claim is defined by [RFC 7519 Section 4.1.3](https://tools.ietf.org/html/rfc7519#section-4.1.3).

This claim will be equal to the `client_id`, or, if one or more `resource` values was provided, an array containing both the `client_id` and the list of resources.

`authenticationType`String

The method used to authenticate the user that resulted in the generated JWT. The possible values are:

*   `APPLE` - The user was authenticated using Apple. Available since 1.17.0
*   `APPLICATION_TOKEN` - The user was authenticated using an Application Authentication Token.
*   `EpicGames` - The user was authenticated using Epic Games. Available since 1.28.0
*   `FACEBOOK` - The user was authenticated using Facebook. Available since 1.1.0
*   `FEDERATED_JWT` - The user was authenticated using a JWT from an external source.
*   `GENERIC_CONNECTOR` - The user was authenticated using a generic connector. Available since 1.18.0
*   `GOOGLE` - The user was authenticated using Google. Available since 1.1.0
*   `HYPR` - The user was authenticated using HYPR. Available since 1.12.0
*   `JWT_SSO` - A valid JWT associated with one application was exchanged for another JWT associated with a different application.
*   `LDAP_CONNECTOR` - The user was authenticated using an LDAP connector. Available since 1.18.0
*   `LINKEDIN` - The user was authenticated using LinkedIn. Available since 1.23.0
*   `Nintendo` - The user was authenticated using Nintendo. Available since 1.36.0
*   `ONE_TIME_PASSWORD` - The user was authenticated using a one-time password. Available since 1.5.0
*   `OPENID_CONNECT` - The user was authenticated using OIDC. Available since 1.1.0
*   `PASSWORD` - The user was authenticated using a loginId and password combination.
*   `PASSWORDLESS` - The user was authenticated using a passwordless login link. Available since 1.5.0
*   `PING` - The user was authenticated using a `PUT` request on the Login API. This is used to record a login event without prompting for credentials, such as when the FusionAuth SSO session is used.
*   `REFRESH_TOKEN` - The user requested a new JWT using a refresh token.
*   `REGISTRATION` - The user was created using the Registration API. Available since 1.16.0
*   `SAMLv2` - The user was authenticated using SAMLv2. Available since 1.6.0
*   `SAMLv2IdpInitiated` - The user was authenticated using SAMLv2 IdP Initiated login. Available since 1.28.0
*   `SonyPSN` - The user was authenticated using Sony. Available since 1.28.0
*   `Steam` - The user was authenticated using Steam. Available since 1.28.0
*   `TWITTER` - The user was authenticated using Twitter. Available since 1.1.0
*   `Twitch` - The user was authenticated using Twitch. Available since 1.28.0
*   `USER_CREATE` - The user was created using the User API. Available since 1.16.0
*   `WebAuthn` - The user was authenticated using a passkey. Available since 1.41.0
*   `Xbox` - The user was authenticated using Xbox. Available since 1.28.0

`auth_time`LongAvailable since 1.36.0

The time of the initial authentication request, expressed as [unix time](/docs/reference/data-types#unix-time). The value will not change even if the token is re-issued using a Refresh Token.

`email`String

The email address of the user whose claims are represented by this JWT.

Removed in 1.50.0

In version `1.50.0` and later this claim is not returned when the **oauthConfiguration.scopeHandlingPolicy** value of the Application is `Strict`.

`email_verified`Boolean

The verification status of the **email**. This value is `true` when the email is verified.

Removed in 1.50.0

In version `1.50.0` and later this claim is not returned when the **oauthConfiguration.scopeHandlingPolicy** value of the Application is `Strict`.

`exp`Long

The expiration instant of the JWT, expressed as [unix time](/docs/reference/data-types#unix-time). This registered claim is defined by [RFC 7519 Section 4.1.4](https://tools.ietf.org/html/rfc7519#section-4.1.4).

`gty`Array<String>Available since 1.60.0

The list of grant types in chronological order.

For example, if the token was the result of an `authorization_code` grant, the value will be `[authorization_code]`.

If the token was generated using a refresh token using the `refresh_token` grant, the value will be `[authorization_code, refresh_token]` if the initial grant used to obtain the refresh token was the `authorization_code` grant.

This claim is will not be present if the token was generated outside of an OAuth grant.

`iat`Long

The instant that the JWT was issued, expressed as [unix time](/docs/reference/data-types#unix-time). This registered claim is defined by [RFC 7519 Section 4.1.6](https://tools.ietf.org/html/rfc7519#section-4.1.6).

`jti`StringAvailable since 1.18.0

The unique identifier for this JWT. This registered claim is defined by [RFC 7519 Section 4.1.7](https://tools.ietf.org/html/rfc7519#section-4.1.7).

`iss`String

The issuer of the JWT. For FusionAuth, this is always the value defined in the tenant JWT configuration. This registered claim is defined by [RFC 7519 Section 4.1.1](https://tools.ietf.org/html/rfc7519#section-4.1.1).

`preferred_username`StringAvailable since 1.5.0

The username of the user whose claims are represented by this JWT.

Removed in 1.50.0

In version `1.50.0` and later this claim is not returned when the **oauthConfiguration.scopeHandlingPolicy** value of the Application is `Strict`.

`roles`Array<String>

The roles assigned to the user in the authenticated Application. This claim is only present if the user is registered for the Application.

`scope`StringAvailable since 1.50.0

The scope of the Access token. This meaning of this field is specified by [RFC 6749 Section 3.3](https://datatracker.ietf.org/doc/html/rfc6749#section-3.3).

Contains the validated and consented OAuth scopes from the initial authentication request. See [Scopes](/docs/lifecycle/authenticate-users/oauth/scopes) for more detail on scope consent.

`sid`StringAvailable since 1.37.0

The unique Id of the refresh token returned along with this access token when the `offline_access` scope was requested. This unique Id is the persistent identifier for this refresh token, and will not change even when using one-time use refresh tokens. This value may optionally be used to revoke the token using the [Refresh Token API](/docs/apis/jwt/revoke-refresh-tokens).

`sub`UUID

The subject of the token. The value is the unique Id of the FusionAuth user. This registered claim is defined by [RFC 7519 Section 4.1.2](https://tools.ietf.org/html/rfc7519#section-4.1.2).

`tid`UUIDAvailable since 1.36.0

The FusionAuth Tenant unique Id.

`tty`UUIDAvailable since 1.60.0

The token type. This value will always be `at` indicating this is an `access token`.

### Example JWT[#](#example-jwt)

Here is an example JWT that might be returned from FusionAuth:

*Example JWT*

```
{
  "applicationId": "469b0ba1-a849-4603-883e-3b05c0d2b7ce",
  "aud": "469b0ba1-a849-4603-883e-3b05c0d2b7ce",
  "authenticationType": "PASSWORD",
  "email": "richard@fusionauth.io",
  "exp": 1504112919754,
  "iat": 1504103919754,
  "iss": "acme.com",
  "roles": [
    "role 1",
    "role 2"
  ],
  "sub": "6558c73f-b345-4917-9aac-0feab21eeeeb"
}
```

## Refresh Tokens[#](#refresh-tokens)

Refresh tokens are a method of allowing a User to stay logged into an Application for a long period of time without requiring them to type in their password. This method is often used by Applications that don't store sensitive data such as games and social networks.

To receive a refresh token from the Login API, enable Refresh Tokens for the application. Using the FusionAuth UI, navigate to Settings -> Applications -> Security Tab . Here you will find the Login API settings. Ensure that both **Generate Refresh Tokens** and **Enable JWT refresh** fields are enabled.

FusionAuth provides refresh tokens in the response from the [Login API](/docs/apis/login) provided that you supply these elements:

*   `loginId` - the User's login Id
*   `password` - the User's password or Authentication Token
*   `applicationId` - the identifier for the Application the user is logging into

If all of these attributes are supplied to the [Login API](/docs/apis/login) then FusionAuth will produce a refresh token.

If any of the required elements are missing, no refresh token will be generated.

The refresh token will be returned in the JSON in the response body as well as in a cookie header. The refresh token will be in a parameter called `refreshToken` in the JSON response and the HTTP Only persistent cookie will be named `refresh_token`.

Here is an example of this `Set-Cookie` response header for a refresh token.

Example HTTP Cookie Header

```
Set-Cookie: refresh_token=eu1SsrjsiDf3h3LryUjxHIKTS0yyrbiPcsKF3HDp; Max-Age=2592000; Expires=Fri, 29-Sep-2017 15:20:24 GMT; Secure; HttpOnly
```

Here is an example of the JSON response body that contains the refresh token:

*Example JSON with Refresh Token*

```
{
  "refreshToken": "eu1SsrjsiDf3h3LryUjxHIKTS0yyrbiPcsKF3HDp",
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MDQxMDY0ODQsImlhdCI6MTUwNDEwNjQyNCwiaXNzIjoiaW52ZXJzb2Z0LmNvbSIsInN1YiI6ImUzMDIzMmZiLTIxN2EtNDllYi1iN2QxLTI5YzhhNWVmZmM1YiIsImFwcGxpY2F0aW9uSWQiOiIzYzIxOWU1OC1lZDBlLTRiMTgtYWQ0OC1mNGY5Mjc5M2FlMzIiLCJhdXRoZW50aWNhdGlvblR5cGUiOiJQQVNTV09SRCIsInJvbGVzIjpbImFkbWluIl19.eNF4F0iT8qUtyr3kb_-RSM-jibaP0w-419sD94N3Gkk",
  "user": {
    "active": true,
    "email": "example@fusionauth.io",
    "expiry": 1571786483322,
    "id": "00000000-0000-0001-0000-000000000000",
    "lastLoginInstant": 1471786483322,
    "passwordChangeRequired": false,
    "passwordLastUpdateInstant": 1471786483322,
    "verified": true
  }
}
```

Refresh Tokens are considered sensitive information. The token must be secured on the User's device. If a Refresh Token is compromised, the token bearer may perform authenticated requests on behalf of the User.

Once you have a refresh token on the device, you can call the [Refresh a JWT](/docs/apis/jwt/refresh-a-jwt) API to get a new JWT from FusionAuth using the refresh token. Using this pattern allows you to perform authenticated actions using the JWT without prompting the User to authenticate as long as the refresh token is active.