Keycloakのセッションは、SSOセッション・クライアントセッション・オフラインセッションという3層で理解すると設計がぶれません。本稿では各タイムアウトの意味とOffline Tokenの寿命、失効(revocation)とBack-Channel Logout、そしてKeycloak 26で標準化された永続セッションまでを、現場の運用目線で掘り下げます。
01セッションを3層で捉える
Keycloakのセッション設計は、まず概念を3層に分解するところから始めると迷いません。ひとつめがSSOセッション(ユーザーセッション)で、これは「そのユーザーがKeycloakにログインしている」という事実そのものを表します。ふたつめがクライアントセッションで、SSOセッションの傘の下に、参加した各クライアント(アプリケーション)ごとにぶら下がる子セッションです。ひとつのSSOセッションに、Aアプリ・Bアプリ・Cアプリぶんのクライアントセッションが紐づく、という親子関係になります。
みっつめがオフラインセッションで、これはユーザーがログアウトしても、あるいはサーバーを再起動しても生き残る、まったく別ライフサイクルの特殊なセッションです。Offline Tokenの土台になるのがこれです。同じ「セッション」という言葉でも寿命の桁が違うため、設定画面のどのタイムアウトがどの層に効くのかを取り違えると、想定外のログアウトや、逆にいつまでも残るセッションに悩まされます。
02SSOセッションの寿命 — Idle と Max
Realm settings の Sessions タブに、SSOセッションを支配する2つのタイムアウトがあります。SSO Session Idleはアイドルタイムアウトで、この時間だけ何のアクティビティ(トークンリフレッシュ等)もなければセッションが失効します。既定値は30分です。一方のSSO Session Maxは、アイドルかどうかに関わらずセッションを強制的に失効させる上限で、既定値は10時間です。つまり「最後の操作から30分」か「ログインから10時間」の、どちらか早いほうでSSOセッションは切れます。
ここで実務上ハマりやすいのが、リフレッシュトークンの寿命との関係です。アクセストークンは短命(既定5分)で、クライアントはリフレッシュトークンを使って更新し続けますが、そのリフレッシュ自体がIdleを都度リセットします。したがってSSO Session Idleより短い間隔でリフレッシュしているアクティブなユーザーは、Maxに達するまで切れません。逆にリフレッシュ間隔がIdleを超えるようなクライアント設計だと、ユーザーは操作中でも突然セッションを失います。詳しくはOIDCグラントタイプや認証フローの記事も併せてご覧ください。
なお、アイドル判定には少しの時間差を許容するidle timeout windowがあり、その値はSessionTimeoutHelperで120秒(2分)と定められています(バックグラウンドで期限切れセッションを掃除するPERIODIC_CLEANER側はさらに長い180秒です)。このため、既定30分のSSO Session Idleはちょうど30分で即失効するのではなく、実効的には約32分でセッションが切れる挙動になります。厳密な失効タイミングを詰めるときは、お使いのバージョンのソース/公式ドキュメントで値を確認することをおすすめします。
03クライアントセッションと個別上書き
SSOセッションが「日〜月」単位で生きうるのに対し、個々のクライアントセッションは本来もっと短くあるべきです。RealmにはClient Session IdleとClient Session Maxがあり、これらが未設定(0)のときはSSOセッションのIdle/Maxが適用されます。値を入れると、SSOセッションより短いクライアントセッション寿命を設けられます。狙いは、あるアプリのアクセストークンの実効寿命を、SSO全体とは独立に絞ることです。
さらにKeycloakは、クライアント個別(Advanced settings)でもセッション/トークンのタイムアウトを上書きできます。たとえば「社内ポータルはSSOに追随させたいが、機微データを扱うクライアントだけはクライアントセッションを短くしたい」といった要件を、Realm全体を触らずに実現できます。優先順位は「クライアント個別設定 → Realmのクライアントセッション設定 → RealmのSSOセッション設定」の順にフォールバックする、と捉えると整理しやすいです。
04Offline Token — 30日と60日の罠
Offline Tokenは、ユーザーがオフラインでも(ログアウト後・ブラウザを閉じた後でも)アプリがユーザーの代わりにリソースへアクセスし続けるための、特殊なリフレッシュトークンです。取得にはクライアントの認可リクエストでscope=offline_accessを指定します。公式のServer Administration Guideにある通り、Offline Tokenは通常のSSO Session Idle / SSO Session Maxの対象外で、ログアウトやサーバー再起動を越えて有効であり続けます。
ただし「無期限」ではありません。ここに現場が引っかかる2つの上限があります。ひとつはOffline Session Idleで、既定30日です。この期間内に少なくとも一度、そのOffline Tokenでリフレッシュを行わないと、オフラインセッションは失効します。もうひとつはOffline Session Max Limitedで、これを有効にすると、途中でリフレッシュを続けていてもオフラインセッションは既定60日で強制失効します。Idleは「使い続ければ延びる」上限、Maxは「使っていても切れる」絶対上限、という違いです。
- バッチ/デーモン連携:30日に一度も動かない連携ジョブは、次回起動時にトークン失効に直面します。連携頻度がIdleを下回らない設計にするか、Idleを延ばす判断が要ります。
- コンプライアンス要件:Max Limitedを有効化すると、どれだけアクティブでも60日で再認可が強制され、監査上の「無期限アクセス」を排除できます。金融・公共系ではこちらを推奨されることが多い設定です。
- 数の管理:Offline Tokenはユーザー×クライアントごとにオフラインセッションを生みます。放置すると溜まるため、後述の失効やセッション数の運用とセットで考えます。
05失効(revocation)とnot-before
セッションやトークンを能動的に無効化する手段は、Keycloakには複数あります。まず個別のログアウトは、管理コンソールのSessionsからユーザーセッションを落とす、あるいはユーザー単位で「Sign out」する方法です。Offline Tokenについては、ユーザー自身がAccount Consoleから、管理者がユーザーのConsentsから、付与済みのオフラインアクセスを取り消せます。
面で失効させたいときはRevocation Policy(Not Before)を使います。Realm settings のトークン設定で「この日時より前に発行されたトークン/セッションはすべて無効」という時刻境界を打ちます。鍵の漏洩や大規模インシデント時に、全ユーザーを一斉に締め出す最終手段です。あわせて、クライアントに対してPush not-beforeを実行すると、Keycloakが各クライアントに「この時刻以前のトークンは受け付けるな」と通知し、クライアント側キャッシュのトークンも失効させられます。これは署名鍵ローテーション時、旧鍵で署名されたトークンを確実に排除するのに有効です。鍵運用と併せた設計はセキュリティハードニングの記事も参考にしてください。
06SSO/SLO — Back-Channel Logout
SSOで複数アプリにログインした状態から「全アプリを一斉にログアウトさせる」のがSingle Logout(SLO)です。Keycloakはフロントチャネル(ブラウザ経由のリダイレクト連鎖)とバックチャネル(サーバー間通信)の両方式をサポートしますが、エンタープライズで信頼性が求められる場面ではBack-Channel Logoutを選ぶのが定石です。ブラウザが閉じていても、iframe読み込みに失敗しても、Keycloakが各クライアントのエンドポイントへ直接Logout Tokenを送るため、確実性が段違いです。
設定はクライアントのAdvanced settingsで、backchannel.logout.url(Backchannel logout URL)にクライアント側の受信エンドポイントを登録します。あわせてbackchannel.logout.session.requiredを有効にすると、Logout Tokenにセッションを識別するsidが含まれ、クライアントは「どのセッションを落とすか」を特定できます。仕様の詳細はOIDCレイヤーのドキュメントを確認してください。
- セッション単位 vs 全セッション:sid付きなら該当セッションだけ、なしなら当該ユーザーの全セッションを落とす挙動になります。要件に応じて選びます。
- 到達性:バックチャネルはKeycloakからクライアントへの到達性が前提です。閉域網やIngress構成で経路が通っているかを、SLO実装前に必ず確認します。
- Offline Tokenとの関係:SLOはオンラインセッションを対象とします。Offline Tokenは別ライフサイクルのため、SLOだけでは無効化されない点に注意が必要です。
07セッションの保存とKeycloak 26の変化
セッションの寿命設計と切り離せないのが、セッションを「どこに保存するか」です。歴史的にKeycloakはユーザーセッションをInfinispanのメモリ上に保持し、オフラインセッションだけをDBに永続化していました。この構成は、クラスタ再起動やアップグレードでオンラインセッションが飛ぶという運用上の悩みを抱えていました。
これがKeycloak 25でpersistent-user-sessionsとしてプレビュー導入され、Keycloak 26では既定で有効になりました。現行の新しめのバージョンでは、すべてのユーザーセッションがDBを正とし、Infinispanはあくまでキャッシュ(既定でキャッシュあたり最大10,000エントリ程度)として振る舞います。これにより再起動やアップグレードを越えてセッションが維持され、メモリ使用量は下がる一方、DB負荷は上がるというトレードオフになります。キャッシュの調整はInfinispanキャッシュチューニング、DB側はデータベースチューニングの記事で詳述しています。
実務的な含意として、「ユーザーを長くログインさせたいからOffline Tokenで代用する」という過去のワークアラウンドは、KC26以降では不要になりつつあります。公式も、Offline Tokenは本来「ログアウト後の代理アクセス」という別目的のものだと明言しており、単なる長期ログイン維持にはオンラインセッションの寿命延長で対応するのが筋です。マルチサイト構成では、永続セッションはDBに置き、外部Infinispanはサイト間の無効化通知やタスク同期に用いる、という役割分担になります。マルチアカウント/マルチサイトの統制観点はマルチアカウント統制もご覧ください。
—まとめ
Keycloakのセッションは、SSOセッション・クライアントセッション・オフラインセッションの3層で捉えるのが出発点です。SSOはIdle(既定30分)とMax(既定10時間)、Offline TokenはIdle(既定30日)とMax Limited(有効時60日)という別々の時間軸を持ちます。失効はNot Beforeとpush、確実なログアウトはBack-Channel Logout、そしてKC26以降はセッションがDB永続前提になった——この地図を持っておけば、想定外のログアウトや溜まり続けるオフラインセッションに振り回されずに設計できます。バージョン依存の細部は、必ずお使いのバージョンの公式ドキュメントで裏取りすることをおすすめします。
私たちEMWはKeycloakでエンタープライズの認証基盤を実構築してきました。具体的な事例は導入事例もご覧ください。
—参考(一次情報)
- Keycloak — Server Administration Guide(Managing user sessions / Offline access / Session and token timeouts)
- Keycloak Blog — Storing sessions in Keycloak 26
- Keycloak Blog — Keeping users logged in with Keycloak 25 (Persistent user sessions in preview)
- Keycloak — Securing applications and services with OpenID Connect (OIDC layers / Back-Channel Logout)
- keycloak/keycloak Issue #26532 — Revoking an offline refresh token invalidates all offline sessions
- keycloak/keycloak — SessionTimeoutHelper.java(idle timeout window 120秒 / PERIODIC_CLEANER 180秒)