In Keycloak, set SSO Session Idle (Realm settings, Sessions tab, default 30 minutes) to how long a user may stay inactive before they sign in again, set SSO Session Max (default 10 hours) as the absolute ceiling, keep Access Token Lifespan at about 5 minutes, and turn on refresh token rotation (Revoke Refresh Token on, Refresh Token Max Reuse 0) under the Tokens tab. There is no separate refresh token lifetime to configure, because a refresh token only lives as long as the client session and the SSO session it belongs to. The rest of this post is the recipe: each setting with its console path, a sensible range for your kind of application, and the reasoning behind the range, followed by one consolidated section on balancing security against user experience.
The values here were checked against the Keycloak Server Administration Guide for the current 26.x line, as of Keycloak 26.8.1, announced on 13 October 2026. The defaults quoted are the ones a new realm gets, and the table in the next section says where they come from.
Key Takeaways
- SSO Session Idle and SSO Session Max are the two settings that matter most, and both live under Realm settings, Sessions, together with the client session and offline session timeouts.
- A refresh token has no lifetime of its own in Keycloak. It expires with the client session, which cannot outlive the SSO session.
- Turn on Revoke Refresh Token with Max Reuse 0 for public clients such as single-page apps and mobile apps. RFC 9700 requires rotation or sender-constrained refresh tokens for them.
- The idle timeout only works if your application stops refreshing tokens when the user is away. A background refresh loop counts as activity.
- Match the numbers to the standard that applies to you: 15 minutes idle for PCI DSS scope, 1 hour idle and 24 hours max as the NIST AAL2 ceiling, and 5 to 15 minutes idle for high-value applications, the range OWASP and NIST AAL3 point to.
Which Keycloak timeouts matter, and where they live
Keycloak spreads its session and token lifetimes across two tabs of Realm settings. The Session and token timeouts section of the Server Administration Guide lists every field. The table below shows the ones this post is about, their tab, and the default a new realm gets. The guide does not print most of the defaults, so they are taken from the DEFAULT_* constants in Keycloak’s Constants.java at the 26.8.1 tag, which are written in seconds: DEFAULT_SESSION_IDLE_TIMEOUT = 1800, with the comment “30 minutes” beside it, DEFAULT_SESSION_MAX_LIFESPAN = 36000 (“10 hours”), DEFAULT_ACCESS_TOKEN_LIFESPAN = 300 (5 minutes), DEFAULT_OFFLINE_SESSION_IDLE_TIMEOUT = 2592000 (30 days) and DEFAULT_OFFLINE_SESSION_MAX_LIFESPAN = 5184000 (60 days). The guide confirms two of them in prose. Its step-up flow example sets a Max Age of 36000 and explains that “this value is in seconds and it is equivalent to 10 hours, which is the default SSO Session Max timeout set in the realm”, and its offline access section states the two offline defaults in days: you must use the token “at least once per thirty days or for the value of the Offline Session Idle”, and with Offline Session Max Limited on, “offline tokens expire after 60 days”. The rest of this post refers back to this table whenever it quotes a default.
| Setting | Tab | Default | What it bounds |
|---|---|---|---|
| SSO Session Idle | Sessions | 30 minutes | Inactivity before the user session (and everything under it) ends |
| SSO Session Max | Sessions | 10 hours | Absolute lifetime of the user session |
| SSO Session Idle Remember Me, SSO Session Max Remember Me | Sessions | 0 (inherit) | The same two limits when the user ticked Remember Me |
| Client Session Idle, Client Session Max | Sessions | 0 (inherit) | Per-application session, and so the refresh token’s expiry |
| Offline Session Idle | Sessions | 30 days | Inactivity before an offline token is revoked |
| Offline Session Max Limited, Offline Session Max | Sessions | Off, 60 days | Absolute lifetime of an offline token, once the flag is on |
| Login timeout, Login action timeout | Sessions | 30 minutes, 5 minutes | How long a sign-in attempt, and one page of it, may take |
| Access Token Lifespan | Tokens | 5 minutes | How long an issued access token is valid |
| Revoke Refresh Token, Refresh Token Max Reuse | Tokens | Off, 0 | Refresh token rotation and how many replays are tolerated |
Two things in that table trip people up. First, the client session and offline session settings are on the Sessions tab, not the Tokens tab, even though they decide when refresh tokens expire: the guide lists Client Session Idle, Client Session Max and the Offline Session settings in its “Sessions tab” table, and keeps the “Tokens tab” table for Revoke Refresh Token, Access Token Lifespan and the other token settings. Second, there is no “Refresh Token Lifespan” row, because neither of those tables has one. We come back to that in the refresh section.
It helps to keep the hierarchy in mind. When a user signs in, Keycloak creates one SSO session (the docs call it the user session). Each application the user then opens gets its own client session under it. The guide puts it this way: “the SSO user session is the parent of zero or more client sessions, one client session is created for every different client app the user logs in.” When the SSO session is invalidated, the client sessions and their refresh tokens go with it. Our earlier overview, Session Management in Keycloak: From Refresh to Idle Timeouts, walks through that model if you want more background before the numbers.

How to configure the SSO session idle timeout
Path: Realm settings, Sessions tab, SSO Session Idle. Admin REST API field: ssoSessionIdleTimeout, an integer in the RealmRepresentation (the unit is covered in the REST section below).
The Keycloak docs describe it as: “If a user is inactive for longer than this timeout, the user session is invalidated. This timeout value resets when clients request authentication or send a refresh token request.” So “activity” means two things to Keycloak: a client starting a login against the realm, or a client refreshing a token. A user clicking around inside your app does not count by itself.

Recommended ranges
| Application type | SSO Session Idle | Why |
|---|---|---|
| Consumer web app, typical SaaS | 30 minutes (the default) | The OWASP Session Management Cheat Sheet gives “15-30 minutes for low risk applications” as the common idle range (Idle Timeout) |
| Workforce tools behind MFA | 30 minutes to 1 hour | NIST SP 800-63B-4 says, under AAL2 reauthentication, “The inactivity timeout SHOULD be no more than 1 hour” |
| Systems in PCI DSS scope | 15 minutes or less | PCI DSS requirement 8.2.8 requires re-authentication after a session has been idle for more than 15 minutes, per the PCI SSC FAQ on 8.2.8 |
| High-value apps (banking, admin consoles, health records) | 5 to 15 minutes | OWASP’s “2-5 minutes for high-value applications” (Idle Timeout) and the NIST AAL3 inactivity timeout, which “SHOULD be no more than 15 minutes” |
Going below five minutes is rarely worth it in Keycloak, because at that point the idle timeout is about as long as the access token itself and every page load risks a round trip through the login page. If you need stronger protection for a few sensitive actions rather than the whole session, step-up authentication is the better tool.
Two details that change the effective value
The two-minute grace window only applies without persistent sessions. The docs note that “for idle timeouts, a two-minute window of time exists that the session is active. For example, when you have the timeout set to 30 minutes, it will be 32 minutes before the session expires”, but they also say that logic “is only applied if persistent user sessions are not active”. The Keycloak 26.0.0 release notes say of persistent user sessions that “In Keycloak 26, this feature is enabled by default”, so a stock 26.x realm expires the session at the configured value. You only see the extra two minutes if you turned persistent sessions off.
A background refresh loop defeats the idle timeout. Because a token refresh resets the idle clock, an application that refreshes on a timer keeps the session alive while the user is at lunch. Our docs guide on session timeouts and idle policy covers the fix: track real user input in the application, and stop refreshing (and log the user out) once the user has been idle for your limit.
How to configure the SSO session max lifespan
Path: Realm settings, Sessions tab, SSO Session Max. Admin REST API field: ssoSessionMaxLifespan, an integer in the RealmRepresentation.
This is the hard ceiling. The docs define it simply as “the maximum time before a user session expires”, and no amount of activity extends it. When it is reached the user signs in again, and every client session under the SSO session ends with it.

Recommended ranges
| Application type | SSO Session Max | Why |
|---|---|---|
| Consumer web app, typical SaaS | 10 hours (the default) to 24 hours | NIST 800-63B-4 says the AAL2 overall reauthentication timeout “SHOULD be no more than 24 hours”, and 10 hours covers a working day |
| Workforce tools | 8 to 12 hours | OWASP says absolute timeouts “depend on how long a user usually uses the application” and that for “an office worker for a full day” the range “could be between 4 and 8 hours”, and NIST AAL3 sets a hard 12-hour limit (next row) |
| Systems in PCI DSS scope | 8 hours | Requirement 8.2.8 is an idle rule, not a ceiling; 8 hours is the working-day value the Skycloak PCI DSS 8.2.8 baseline preset uses |
| High-value apps | 1 to 2 hours, never more than 12 | NIST AAL3 says “the overall timeout for reauthentication SHALL be no more than 12 hours”; shorter is common where a stolen session cookie would be costly |
Remember Me
Path: Realm settings, Sessions tab, SSO Session Idle Remember Me and SSO Session Max Remember Me. They appear only once Remember Me is enabled under Realm settings, Login: the docs say the idle one “is only available when Remember me is enabled”.
These override the two values above for users who ticked the Remember Me box. Per the same docs, if the idle value “is not greater than zero, it uses the same idle timeout as the SSO Session Idle configuration”, and the max value likewise “uses the same session lifespan as the SSO Session Max configuration”, so enabling the checkbox without setting them changes nothing. For a consumer app, 7 to 30 days idle with a 30-day maximum keeps you inside the NIST AAL1 guidance that the overall reauthentication timeout “SHOULD be no more than 30 days at AAL1”. For workforce or regulated applications, either leave Remember Me off or pin both values to the regular limits so the checkbox cannot extend a session past your policy.
How to configure refresh token settings
This is where most misconfiguration happens, so it is worth being precise about what Keycloak does and does not have.
There is no standalone refresh token lifetime
The Tokens tab table in the Server Administration Guide has no “refresh token lifespan” row, and neither does the Sessions tab table. The expiry of a refresh token is instead derived from the session it belongs to. The docs describe Client Session Max as “the maximum time for a client session and before a refresh token expires and invalidates”, and state that “client session values also control the refresh token expiration”. With Client Session Idle and Client Session Max left at zero, the refresh token inherits the SSO Session Idle and SSO Session Max values. Each successful refresh also resets the idle clock on the client session and the SSO session, which is how a user stays signed in through a working day with 30-minute idle.
So if you want refresh tokens to expire sooner for one application than for the rest of the realm, you do not look for a token setting. You set Client Session Idle and Client Session Max, either realm-wide on the Sessions tab or per client under the client’s Advanced tab: the docs say of both values that “Users can override it for individual clients in the Advanced Settings client tab”. The docs advise that the client values “should specify a shorter idle timeout than the SSO Session Idle”, because the client session cannot outlive its parent anyway.
If the difference between the two token types is still fuzzy, Access Token vs Refresh Token: Key Differences covers it, and JWT Token Lifecycle: Expiration, Refresh, and Revocation goes deeper on the lifecycle.
Access Token Lifespan
Path: Realm settings, Tokens tab, Access Token Lifespan. REST field: accessTokenLifespan.
Keep this short and let the refresh token do the work. The default is 5 minutes (DEFAULT_ACCESS_TOKEN_LIFESPAN = 300 seconds in Constants.java at the 26.8.1 tag), and that is a good value for nearly everyone. RFC 9700 makes the case in section 4.14, Refresh Token Protection: refresh tokens “allow the authorization server to issue access tokens with a short lifetime and reduced scope, thus reducing the potential impact of access token leakage”. Going shorter (1 to 2 minutes) is reasonable for high-value APIs that cannot afford a five-minute window after a revocation, at the cost of more calls to the token endpoint. Going longer than 15 minutes mostly just lengthens the window in which a leaked token or a revoked session is still accepted by your APIs.
Refresh token rotation: Revoke Refresh Token and Max Reuse
Path: Realm settings, Tokens tab, Revoke Refresh Token (on), then Refresh Token Max Reuse. REST fields: revokeRefreshToken and refreshTokenMaxReuse, both listed in the Admin REST API’s RealmRepresentation.
When Revoke Refresh Token is on, the docs say “Keycloak revokes refresh tokens and issues another token that the client must use”. Every refresh response then carries a new refresh token, and the one that was just used is spent. The admin console’s own help text for the two fields, in Keycloak’s messages_en.properties at the 26.8.1 tag, spells out what Max Reuse means. The Revoke Refresh Token help text reads “If enabled, a refresh token can only be used up to ‘Refresh Token Max Reuse’ and it is revoked when a different token is used”, and the Refresh Token Max Reuse help text reads “Maximum number of times a refresh token can be reused. When a different token is used, revocation is immediate.” With Max Reuse at 0, a refresh token is good for exactly one use, so a replayed one is refused, and that refusal is the signal that the token was copied. The Keycloak Terraform provider’s realm documentation says the same in plainer words: “If unspecified and ‘revoke_refresh_token’ is enabled the default value is 0 and refresh tokens can not be reused”.
You should turn this on because of RFC 9700, section 4.14.2: “Authorization servers MUST utilize one of these methods to detect refresh token replay by malicious actors for public clients”, and the two methods are sender-constrained refresh tokens (mutual TLS or DPoP) or refresh token rotation. A single-page app or a mobile app is a public client, so if you are not binding refresh tokens to the client instance with DPoP, you need rotation. The RFC also explains the cost honestly: when a replay is detected the server “will revoke the active refresh token”, which “stops the attack at the cost of forcing the legitimate client to obtain a fresh authorization grant”.
Three practical points:
- Rotation is a realm setting. Revoke Refresh Token sits on the realm’s Tokens tab, and the docs say it “applies to OIDC clients performing the refresh token flow”. The per-client overrides the guide lists under Advanced Settings for OIDC are Access Token Lifespan, Client Session Idle, Client Session Max, Client Offline Session Idle and Client Offline Session Max; Revoke Refresh Token is not among them. So plan on rotation affecting every OIDC client in the realm that uses the refresh flow, and check them all before you flip it.
- Max Reuse 1 is the compromise for clients that occasionally replay. Our docs guide notes that clients which replay a refresh token, “including multi-tab single-page applications that race a refresh and mobile applications that cache one, will start failing with Invalid refresh token”. If you cannot fix the client, setting Max Reuse to 1 allows one reuse before the token is revoked (per the help text quoted above), which is enough for a single accidental replay to pass instead of ending the session, in exchange for not catching an attacker who happens to be the second user of a token. Treat it as a stopgap and aim for 0.
- It applies to offline tokens too. The offline access section says: “If you enable the Revoke Refresh Token option, you can use each offline token once only. After refresh, you must store the new offline token from the refresh response instead of the previous one.” Any background job holding an offline token has to persist the new one on every refresh.
The step-by-step setup, including how to update client code to store the rotated token, is in our Keycloak Refresh Token Rotation guide.
Client session timeouts and per-client overrides
Path: Realm settings, Sessions tab, Client Session Idle and Client Session Max, or Clients, your client, Advanced tab for one application. REST fields: clientSessionIdleTimeout and clientSessionMaxLifespan.
Use these when one application needs a shorter session than the realm. A finance dashboard in a realm shared with a help center can get a 15-minute client idle and a 2-hour client max while the SSO session keeps its 30-minute and 10-hour defaults. The docs are clear that these settings never affect the SSO session itself: Client Session Idle “never affects the general SSO user session, which is unique”, and Client Session Max “never affects the SSO user session” either. So when the finance client session ends, the user still has a live SSO session, and opening the dashboard again goes through that session rather than a password prompt unless you require re-authentication (for example with prompt=login or a step-up flow).
Two rules keep the values coherent. Set client values shorter than the realm’s SSO values, since a longer client value has no effect once the parent session ends. And when a client’s session ends sooner than you expect, check the client’s Advanced tab before you touch the realm, because a per-client override is the usual cause.
Offline sessions for mobile apps and background jobs
Path: Realm settings, Sessions tab, Offline Session Idle, Offline Session Max Limited and Offline Session Max. Per-client: Client Offline Session Idle and Client Offline Session Max on the client’s Advanced tab.
An offline token is a refresh token a client gets by requesting the offline_access scope. The docs describe it as a token that “is not subject to the SSO Session Idle timeout and SSO Session Max lifespan” and stays valid after the user logs out. It is governed only by the offline settings: use it at least once every 30 days by default (Offline Session Idle), and if you enable Offline Session Max Limited, it expires after 60 days by default regardless of use.
For a mobile app, 30 days idle is a reasonable default and we recommend turning Offline Session Max Limited on with a 60 to 90 day cap so a device that was lost but never reported stops working on its own. Offline tokens are the right tool for nightly jobs and apps that check in occasionally; they are the wrong tool for a browser session. Keycloak Offline Tokens Explained covers when to use them and how to revoke them.
Recommended values by application type
Here is everything above in one place. The numbers are starting points that you can defend with a linked standard, not rules; tighten them where your risk assessment says so.
| Setting | Consumer web / SaaS | Workforce tools (MFA) | PCI DSS scope | High-value (banking, admin) | Mobile app (offline tokens) |
|---|---|---|---|---|---|
| SSO Session Idle | 30 min | 30 min to 1 h | 15 min | 5 to 15 min | 30 min (for the web sign-in) |
| SSO Session Max | 10 to 24 h | 8 to 12 h | 8 h | 1 to 2 h | 10 h |
| Remember Me idle / max | 7 to 30 d / 30 d | Off | Off, or pinned to the regular values | Off | Off (offline tokens cover it) |
| Client Session Idle / Max | 0 (inherit) | 0 (inherit) | 0, or shorter per app | Shorter per sensitive app | 0 (inherit) |
| Access Token Lifespan | 5 min | 5 min | 5 min | 1 to 5 min | 5 min |
| Revoke Refresh Token / Max Reuse | On / 0 | On / 0 | On / 0 | On / 0 | On / 0 (1 only while fixing replays) |
| Offline Session Idle | 30 d (unused) | 30 d (unused) | 30 d, scope not granted | Do not grant offline_access | 30 d |
| Offline Session Max Limited / Max | Off | Off | On / 60 d | n/a | On / 60 to 90 d |
Sources for the ranges: OWASP Session Management Cheat Sheet for the 2 to 5 and 15 to 30 minute idle bands and the 4 to 8 hour absolute band, NIST SP 800-63B-4 for the AAL1 (30 days), AAL2 (24 hours, 1 hour idle) and AAL3 (12 hours, 15 minutes idle) limits, the PCI SSC FAQ on requirement 8.2.8 for the 15-minute idle rule, and RFC 9700 for rotation on public clients. Note what is not on that list: a 5-minute idle rule specific to banking, and a SOX session timeout. If someone quotes one of those rules to you, ask for the clause.
The cluster, without the on-call
Skycloak runs real upstream Keycloak in the region you choose, and takes the upgrades, backups, certificate rotation and patching off your team. No fork, so you can export and self-host whenever you want.
Balancing security and user experience
The short version of the trade-off is that the idle timeout is what users feel, the max lifespan is what limits a stolen session, and rotation is what limits a stolen refresh token. You can be strict on the last two without annoying anyone, so start there.
- Spend your strictness on the max lifespan and on rotation, not on idle. A user who is actively working never notices a 10-hour ceiling or a rotated refresh token. They notice a 5-minute idle every time they read an email. Set idle to the longest value your standard allows, and make the ceiling and rotation do the security work.
- Enforce idle in the application as well as the realm. Keycloak only sees refreshes and logins, so an app that refreshes on a timer makes any idle value meaningless. Gate the refresh on real user activity, as our docs guide shows for keycloak-js, oidc-client-ts and NextAuth. The OWASP cheat sheet adds that “Session timeout management and expiration must be enforced server-side”, because with a client-side timer “an attacker could manipulate these to extend the session duration”; the realm setting is that server-side enforcement.
- Use step-up for the risky actions instead of a short session for everything. Keeping a 30-minute idle session but requiring a fresh MFA before a payout or a role change gives you most of the security of a 5-minute idle with almost none of the friction. See Step-Up Authentication with Keycloak.
- Give Remember Me its own numbers, or turn it off. With the Remember Me timeouts at zero it does nothing, and with them unbounded it quietly becomes the real policy for anyone who ticks the box.
- Treat offline tokens as a separate policy. They ignore the SSO limits, so decide who gets the
offline_accessscope, cap them with Offline Session Max Limited, and remember rotation applies to them too. - Keep access tokens short so revocation means something. When you end a session, whether from the admin console or with the single-session revoke, an access token your APIs verify by signature alone is still accepted until its
exppasses, unless they introspect it. The Keycloak docs make the same point for a disabled client: “Access tokens that were already issued while the client was still enabled remain valid until they expire.” Five minutes is the longest you want that window to be. - Change timeouts in a maintenance window. Keycloak evaluates the limits when a session is next used, so tightening SSO Session Max ends every session already older than the new value, immediately. Our docs guide calls this out for the same reason.
- Review the values with the rest of your hardening. Session and token lifetimes are one row of the Keycloak Security Hardening Checklist; run through the rest while you are in the realm.
Configuring the timeouts with the Admin REST API
Everything in this post is a field on the RealmRepresentation, so you can read and set it with the Admin REST API. The representation types them as plain integers with no unit. The unit is seconds, as the defaults quoted beside the table at the top of this post show (1800 for the 30-minute SSO Session Idle, 36000 for the 10-hour SSO Session Max), and the GET below will show that same 36000 on an untouched realm.
# Read the current values
curl -s "https://keycloak.example.com/admin/realms/my-realm" \
-H "Authorization: Bearer $ADMIN_TOKEN" | jq '{
ssoSessionIdleTimeout,
ssoSessionMaxLifespan,
ssoSessionIdleTimeoutRememberMe,
ssoSessionMaxLifespanRememberMe,
clientSessionIdleTimeout,
clientSessionMaxLifespan,
accessTokenLifespan,
revokeRefreshToken,
refreshTokenMaxReuse,
offlineSessionIdleTimeout,
offlineSessionMaxLifespanEnabled,
offlineSessionMaxLifespan
}'
# Apply the "workforce tools" column: 1 hour idle, 10 hours max,
# 5 minute access tokens, rotation on with no reuse
curl -s -X PUT "https://keycloak.example.com/admin/realms/my-realm" \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"ssoSessionIdleTimeout": 3600,
"ssoSessionMaxLifespan": 36000,
"clientSessionIdleTimeout": 0,
"clientSessionMaxLifespan": 0,
"accessTokenLifespan": 300,
"revokeRefreshToken": true,
"refreshTokenMaxReuse": 0
}'
The Admin REST API documents this call, PUT /admin/realms/{realm}, as “Update the top-level information of the realm”, and the example sends only the fields for one column of the table; run the GET first so you know the starting values, and again afterwards to confirm nothing else moved. If you manage realms as code, the Keycloak Terraform provider’s realm resource exposes the same settings as arguments (sso_session_idle_timeout, sso_session_max_lifespan, client_session_idle_timeout, access_token_lifespan, revoke_refresh_token, refresh_token_max_reuse and the offline ones). Its documentation says the timeout arguments “should be specified as Go duration strings”, such as 30m, rather than seconds; see Using Terraform to set up and configure Keycloak.
Verifying the result
Settings are only half the job, so check what Keycloak actually issues.
- Decode a token pair. Sign in to a test client, paste the access token and the refresh token into the JWT Token Analyzer, and compare their
expclaims withiat. The access token should show your Access Token Lifespan, and the refresh token’s expiry should match the client (or SSO) idle value you set, never a separate refresh lifetime. - Refresh, then replay. With rotation on, refresh once and confirm you got a new refresh token, then send the old one again and confirm the error. If the replay succeeds, Max Reuse is above zero or Revoke Refresh Token is still off.
- Walk away. Leave the app idle for longer than SSO Session Idle with the tab open. If you are still signed in afterwards, the application is refreshing in the background, and the idle gate from the docs guide is the fix, not a shorter realm value. If something expires sooner than you expected, Keycloak Token Expired: Understanding and Fixing Token Issues lists the usual causes.
- Look at live sessions. In the Keycloak admin console, Sessions and a user’s Sessions tab show what is open and when it was last refreshed. On Skycloak, the dashboard’s user management view lists each user’s active sessions with their last activity time and lets you revoke them, and the Session Management feature page summarises the controls. If you would rather not set the realm values by hand, the Skycloak Session & timeout policy recipe applies the PCI DSS 8.2.8 baseline or a balanced preset in one step and flags the policy as degraded if the values are later loosened.
Common mistakes
- Looking for a refresh token lifetime on the Tokens tab. It is not there. Set Client Session Idle and Client Session Max on the Sessions tab, or per client under Advanced.
- Setting a client session longer than the SSO session. It has no effect, because the client session ends when its parent does.
- Enabling Remember Me without setting its two timeouts. At zero they inherit the regular values, so the checkbox changes nothing.
- Trusting the realm idle value while the app refreshes on a timer. The session never goes idle. Gate the refresh on user activity.
- Turning on rotation realm-wide without checking every client. A single app that replays refresh tokens starts failing with “Invalid refresh token” for its users, as our docs guide warns.
- Forgetting offline tokens. If a client can request
offline_access, those tokens ignore SSO limits. Cap them with Offline Session Max Limited. - Assuming the two-minute grace is still there. On Keycloak 26 with persistent sessions (the default), it is not.
Frequently asked questions
What is the default Keycloak session timeout?
A new realm gets an SSO Session Idle of 30 minutes and an SSO Session Max of 10 hours, with Access Token Lifespan at 5 minutes, Offline Session Idle at 30 days and Offline Session Max at 60 days (only enforced once Offline Session Max Limited is on). The table near the top of this post lists them with their source, Keycloak’s Constants.java, and the two places where the Server Administration Guide confirms them in prose.
How do I set the refresh token lifetime in Keycloak?
You cannot set it directly. A refresh token expires with its client session, which inherits SSO Session Idle and SSO Session Max unless you set Client Session Idle and Client Session Max (realm-wide on the Sessions tab, or per client under Advanced). The Keycloak docs state that “client session values also control the refresh token expiration”.
Should I enable Revoke Refresh Token in Keycloak?
Yes for any realm that serves single-page or mobile apps. RFC 9700 requires either refresh token rotation or sender-constrained refresh tokens for public clients. Set Refresh Token Max Reuse to 0, and only raise it to 1 as a temporary measure while you fix a client that replays tokens.
Does the idle timeout count user clicks as activity?
No. Keycloak resets the idle clock on a login or a token refresh, not on requests to your application. Your app has to stop refreshing when the user is inactive, otherwise a background refresh loop keeps the session alive indefinitely within the max lifespan.
What to do next
Open Realm settings in your realm, go to the Sessions tab and set SSO Session Idle and SSO Session Max from the column of the table that matches your application, then switch to the Tokens tab, confirm Access Token Lifespan is 5 minutes or less and turn on Revoke Refresh Token with Max Reuse 0. Decode a token pair in the JWT Token Analyzer to confirm the expiries, then check the live sessions in your admin console or in Skycloak’s session management. If you would rather have the upgrades, backups and patching behind these settings handled for you, see managed hosting.
Sources
- Keycloak, Server Administration Guide, “Session and token timeouts” and “Offline access”, retrieved 2026-10-21, https://www.keycloak.org/docs/latest/server_admin/#_timeouts
- Keycloak, release notes, “User sessions persisted by default” (26.0.0), retrieved 2026-10-21, https://www.keycloak.org/docs/latest/release_notes/index.html
- Keycloak, “Keycloak 26.8.1 released”, October 2026, https://www.keycloak.org/2026/10/keycloak-2681-released
- Keycloak source,
org.keycloak.models.Constants, retrieved 2026-10-21, https://github.com/keycloak/keycloak/blob/26.8.1/server-spi-private/src/main/java/org/keycloak/models/Constants.java#L59-L72 - Keycloak, Admin REST API, RealmRepresentation, retrieved 2026-10-21, https://www.keycloak.org/docs-api/latest/rest-api/index.html
- Keycloak admin console help text,
messages_en.propertiesat the 26.8.1 tag, retrieved 2026-10-22, https://github.com/keycloak/keycloak/blob/26.8.1/js/apps/admin-ui/maven-resources/theme/keycloak.v2/admin/messages/messages_en.properties - Keycloak Terraform provider,
keycloak_realmresource documentation, retrieved 2026-10-22, https://github.com/keycloak/terraform-provider-keycloak/blob/main/docs/resources/realm.md - IETF, RFC 9700, “Best Current Practice for OAuth 2.0 Security”, sections 2.2.2 and 4.14, January 2025, https://www.rfc-editor.org/rfc/rfc9700
- NIST, SP 800-63B-4, “Digital Identity Guidelines: Authentication and Authenticator Management”, sections 2.1.3, 2.2.3 and 2.3.3, August 2025, https://pages.nist.gov/800-63-4/sp800-63b.html
- OWASP, Session Management Cheat Sheet, “Session Expiration”, retrieved 2026-10-21, https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html
- PCI Security Standards Council, FAQ, “What is the purpose of PCI DSS Requirement 8.2.8?”, retrieved 2026-10-21, https://www.pcisecuritystandards.org/faq/articles/Frequently_Asked_Question/what-is-the-purpose-of-pci-dss-requirement-8-2-8-which-requires-users-to-reauthenticate-after-15-minutes-of-idle-time
- PCI Security Standards Council, Document Library (PCI DSS v4.0.1), https://www.pcisecuritystandards.org/document_library/
- Skycloak docs, “Session Timeouts and Idle Policy”, https://skycloak.io/docs/guides/session-timeouts/
