Configure OAuth2 & OpenID Connect expiration times
This document describes how to configure the token expiration time for various tokens in Ory, including the user login and consent flow, access tokens, ID tokens, auth codes, and refresh tokens.
Access token
Access tokens are short-lived tokens that grant access to resources for a limited time. By default, the access token in Ory lasts for one hour. However, you can configure the access token's expiration time per client or globally by using the Ory CLI.
Use the Ory CLI to configure the access token's lifespan. The following command sets the access token's lifespan to two hours globally:
ory patch oauth2-config --project <project-id> --workspace <workspace-id> \
--replace "/ttl/access_token=\"2h\"" \
--format yaml
Refresh token
Refresh tokens are long-lived tokens that are used to obtain new access tokens. By default, the refresh token in Ory lasts for 30 days.
The maximum age of refresh tokens is 6 months. This means that refresh tokens must be rotated at least every 6 months.
Use the Ory CLI to configure the refresh token's lifespan. The following command sets the refresh token's lifespan to one day globally:
ory patch oauth2-config --project <project-id> --workspace <workspace-id> \
--replace "/ttl/refresh_token=\"24h\"" \
--format yaml
Authorization code
Auth codes are temporary codes that are exchanged for access tokens. By default, the auth code in Ory lasts for ten minutes. For example, if you want the auth code to last for five minutes, set the config as follows:
ory patch oauth2-config --project <project-id> --workspace <workspace-id> \
--replace "/ttl/authorization_code=\"5m\"" \
--format yaml
ID token
ID tokens are JSON Web Tokens (JWTs) that contain user identity information. By default, the ID token in Ory lasts for one hour. However, you can modify this value using:
ory patch oauth2-config --project <project-id> --workspace <workspace-id> \
--replace "/ttl/id_token=\"5m\"" \
--format yaml
Login and consent flow
The user login and consent flow in Ory defines how long the user has to submit login credentials and consent. By default, the user session lasts for 1 hour. However, you can modify this value using the Ory CLI:
ory patch oauth2-config --project <project-id> --workspace <workspace-id> \
--replace "/ttl/login_consent_request=\"2h\"" \
--format yaml
Authentication session
The authentication session in Ory defines how long the user remains authenticated after logging in. By default, the authentication session lasts for 30 days and the maximum time is 180 days. You can modify this value using the Ory CLI:
ory patch oauth2-config --project <project-id> --workspace <workspace-id> \
--replace "/ttl/authentication_session=\"30d\"" \
--format yaml
The authentication session has no impact on any existing access, refresh, or ID tokens. If it is expired, the user will have to perform the "login flow" again when performing the OAuth2 Authorization Code Flow or OpenID Connect Implicit / Hybrid Flow.
Furthermore, OpenID Connect Back-Channel Logout will not work if the authentication session is expired which is a known limitation to be addressed in the future.
Lifespan configuration for specific clients
In Ory, you can modify the access, ID, and refresh token lifespan for each grant type (authorization_code
, implicit
,
refresh_token
, client_credentials
, urn:ietf:params:oauth:grant-type:jwt-bearer
) individually per client.
To configure the lifespan for specific clients, use the SDK:
import { Configuration, OAuth2Api } from "@ory/client"
const ory = new OAuth2Api(
new Configuration({
basePath: `https://${process.env.ORY_PROJECT_SLUG}.projects.oryapis.com`,
accessToken: process.env.ORY_API_KEY,
}),
)
export async function setClientLifespans(clientId: string) {
await ory.setOAuth2ClientLifespans({
id: clientId,
oAuth2ClientTokenLifespans: {
authorization_code_grant_access_token_lifespan: "1h",
authorization_code_grant_id_token_lifespan: "12h",
authorization_code_grant_refresh_token_lifespan: "24h",
client_credentials_grant_access_token_lifespan: "1h",
implicit_grant_access_token_lifespan: "1h",
implicit_grant_id_token_lifespan: "12h",
jwt_bearer_grant_access_token_lifespan: "1h",
refresh_token_grant_access_token_lifespan: "1h",
refresh_token_grant_id_token_lifespan: "12h",
refresh_token_grant_refresh_token_lifespan: "24h",
},
})
}