Token Lifespans
Why lifespans matter
Section titled “Why lifespans matter”Every token Keycloak issues has a lifespan. Getting these right is a balance between user experience (fewer re-logins) and security (limiting damage if a token leaks). A token that never expires is dangerous — if it leaks, an attacker has indefinite access. A token that expires every 30 seconds is secure but unusable.
Token lifespans reference
Section titled “Token lifespans reference”Access token lifespan
Section titled “Access token lifespan”Default: 5 minutes (300 seconds). Short by design — if an access token leaks, the window of misuse is small. The exp claim in the token reflects this value. Your API must reject any token where exp is in the past.
A 5-minute access token means an attacker who intercepts it has at most 5 minutes to use it before it is worthless. Combine this with HTTPS-only transport and the risk is minimal.
Refresh token lifespan
Section titled “Refresh token lifespan”The refresh token lifespan is controlled by two session settings:
- SSO Session Idle (default: 30 minutes) — if the user is inactive for this long, the session (and refresh token) expires.
- SSO Session Max (default: 10 hours) — the hard upper limit on how long a session can last, regardless of activity.
The client can silently obtain new access tokens using the refresh token as long as the session is within these bounds.
Offline token
Section titled “Offline token”An offline refresh token is a special refresh token that survives server restarts and persists beyond the normal SSO session expiry. It requires the offline_access scope to be requested at login. Offline tokens are controlled by separate settings:
- Offline Session Idle — how long an inactive offline session persists.
- Offline Session Max — the hard upper limit on offline session lifetime.
Use offline tokens for mobile apps or long-running background services that need to stay authenticated without a user present.
Where to configure lifespans
Section titled “Where to configure lifespans”There are two places to set token lifespans in Keycloak:
Realm-level (applies to all clients in the realm):
- Realm settings → Tokens tab — access token lifespan and SSO session settings.
- Realm settings → Sessions tab — offline session settings.
Client-level override (applies to one client only):
- Individual client → Advanced tab → Token Lifespan section.
- Client settings override the realm defaults for that client only. Useful when one client needs a longer or shorter lifespan than the rest.
Configuring lifespans at the realm level
Section titled “Configuring lifespans at the realm level”- In the admin console, click Realm settings in the left sidebar.
- Click the Tokens tab.
- Adjust Access Token Lifespan (recommended: 1–5 minutes for most apps; 5–15 minutes for SPAs with silent refresh).
- Adjust SSO Session Idle — how long before an inactive session expires (default 30 minutes).
- Adjust SSO Session Max — the hard upper limit on session length (default 10 hours).
- Click Save.
Overriding the access token lifespan for a single client
Section titled “Overriding the access token lifespan for a single client”- In the admin console, click Clients and select your client.
- Click the Advanced tab.
- Scroll to the Token Lifespan section.
- Set Access Token Lifespan to override the realm default for this client only.
- Click Save.
Inspecting a token’s expiry
Section titled “Inspecting a token’s expiry”You can decode a token on the command line to check its exp and iat claims. The difference exp - iat tells you the configured lifespan in seconds.
jwt_payload=$(echo "YOUR_ACCESS_TOKEN" | cut -d '.' -f2 | base64 -d 2>/dev/null); echo $jwt_payload | python3 -m json.toolReplace YOUR_ACCESS_TOKEN with an actual token. The exp minus iat value shows you the configured access token lifespan in seconds.
Trade-offs
Section titled “Trade-offs”| Option | Benefit | Cost |
|---|---|---|
| Short-lived access token (1–5 minutes) | Limits the window a stolen token can be used in — it expires quickly before an attacker gets much value from it | Requires refreshing more often, adding round-trips to the token endpoint and load on Keycloak |
| Long-lived access token (30–60+ minutes) | Fewer client-side refreshes, lowering client latency and load on the token endpoint | If it leaks, an attacker can use it for much longer, because a stateless JWT access token cannot be revoked mid-flight — it has to expire on its own |
| Short refresh token / SSO session idle timeout | Forces a session to die quickly when the user is inactive, reducing risk from a refresh token that leaks with an abandoned device | Users must log in again more often after being away, hurting UX for apps used in short bursts |
| Offline token (a refresh token that survives a server restart) | Good for background jobs or mobile apps that need to keep working with no user around to log in again | Naturally long-lived; if it leaks or isn’t revoked when no longer needed, an attacker can use it for a long time |
Common mistakes
Section titled “Common mistakes”- Setting the access token lifespan to an hour or more “for convenience” — the longer the lifespan, the wider the window a leaked token can be used in, because a JWT access token can’t be revoked mid-flight. Keep it short (single-digit to low double-digit minutes) and rely on the refresh token instead.
- Storing an access or refresh token in localStorage — any JavaScript running on the page can read localStorage; a single XSS gap lets an attacker steal and reuse the token immediately. Use memory or an httpOnly cookie instead.
- Putting frequently changing or sensitive data into a token claim and expecting it to be real-time (e.g. current role, balance, subscription status) — a claim is only a snapshot from when the token was issued and won’t update until the token is refreshed, so a system that trusts these claims directly can silently act on stale data.
- Not setting a reasonable SSO Session Max — letting a session renew indefinitely through refreshes with no hard ceiling keeps a session alive long after it should have died.
Real-world example
Banking apps — commonly set the access-token lifespan very short, around 5 minutes, for applications that need high security, to limit the damage if a token leaks mid-transaction.
Per-device session revocation, as used by major streaming platforms — pairs a short-lived access token with revoking the refresh token for one specific device when a user chooses “sign out this device,” cutting off a session on one TV or phone almost immediately without affecting sessions on other devices.