Keycloakのセッションは、SSOセッション・クライアントセッション・オフラインセッションという3層で理解すると設計がぶれません。本稿では各タイムアウトの意味とOffline Tokenの寿命、失効(revocation)とBack-Channel Logout、そしてKeycloak 26で標準化された永続セッションまでを、現場の運用目線で掘り下げます。

01セッションを3層で捉える

Keycloakのセッション設計は、まず概念を3層に分解するところから始めると迷いません。ひとつめがSSOセッション(ユーザーセッション)で、これは「そのユーザーがKeycloakにログインしている」という事実そのものを表します。ふたつめがクライアントセッションで、SSOセッションの傘の下に、参加した各クライアント(アプリケーション)ごとにぶら下がる子セッションです。ひとつのSSOセッションに、Aアプリ・Bアプリ・Cアプリぶんのクライアントセッションが紐づく、という親子関係になります。

みっつめがオフラインセッションで、これはユーザーがログアウトしても、あるいはサーバーを再起動しても生き残る、まったく別ライフサイクルの特殊なセッションです。Offline Tokenの土台になるのがこれです。同じ「セッション」という言葉でも寿命の桁が違うため、設定画面のどのタイムアウトがどの層に効くのかを取り違えると、想定外のログアウトや、逆にいつまでも残るセッションに悩まされます。

現場のコツ:SSOセッションは「日〜週」、クライアントセッションは「分〜時間」、オフラインセッションは「日〜数十日」という別々の時間軸で設計するのが定石です。全部を同じ感覚でいじると、リフレッシュのタイミングとログアウト挙動が噛み合わなくなります。

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分でセッションが切れる挙動になります。厳密な失効タイミングを詰めるときは、お使いのバージョンのソース/公式ドキュメントで値を確認することをおすすめします。

SSOセッション(ユーザーセッション) Idle 既定30分 / Max 既定10時間 クライアントA Client Session クライアントB Client Session クライアントC Client Session オフラインセッション(別ライフサイクル) ログアウト・再起動を越えて存続 Offline Session Idle 既定30日 / Max Limited 有効時60日 Offline Token(scope=offline_access)の土台
図:SSOセッションを親、クライアントセッションを子とする階層。オフラインセッションは別の時間軸で存続する。

03クライアントセッションと個別上書き

SSOセッションが「日〜月」単位で生きうるのに対し、個々のクライアントセッションは本来もっと短くあるべきです。RealmにはClient Session IdleClient Session Maxがあり、これらが未設定(0)のときはSSOセッションのIdle/Maxが適用されます。値を入れると、SSOセッションより短いクライアントセッション寿命を設けられます。狙いは、あるアプリのアクセストークンの実効寿命を、SSO全体とは独立に絞ることです。

さらにKeycloakは、クライアント個別(Advanced settings)でもセッション/トークンのタイムアウトを上書きできます。たとえば「社内ポータルはSSOに追随させたいが、機微データを扱うクライアントだけはクライアントセッションを短くしたい」といった要件を、Realm全体を触らずに実現できます。優先順位は「クライアント個別設定 → Realmのクライアントセッション設定 → RealmのSSOセッション設定」の順にフォールバックする、と捉えると整理しやすいです。

現場のコツ:「なぜかトークンがすぐ切れる」の多くは、クライアント個別のAdvanced settingsに過去の検証値が残っているケースです。Realmだけ見て原因が掴めないときは、クライアント側の上書きを真っ先に疑ってください。

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は「使っていても切れる」絶対上限、という違いです。

05失効(revocation)とnot-before

セッションやトークンを能動的に無効化する手段は、Keycloakには複数あります。まず個別のログアウトは、管理コンソールのSessionsからユーザーセッションを落とす、あるいはユーザー単位で「Sign out」する方法です。Offline Tokenについては、ユーザー自身がAccount Consoleから、管理者がユーザーのConsentsから、付与済みのオフラインアクセスを取り消せます。

面で失効させたいときはRevocation Policy(Not Before)を使います。Realm settings のトークン設定で「この日時より前に発行されたトークン/セッションはすべて無効」という時刻境界を打ちます。鍵の漏洩や大規模インシデント時に、全ユーザーを一斉に締め出す最終手段です。あわせて、クライアントに対してPush not-beforeを実行すると、Keycloakが各クライアントに「この時刻以前のトークンは受け付けるな」と通知し、クライアント側キャッシュのトークンも失効させられます。これは署名鍵ローテーション時、旧鍵で署名されたトークンを確実に排除するのに有効です。鍵運用と併せた設計はセキュリティハードニングの記事も参考にしてください。

現場のコツ:Offline Tokenの単体revoke(Token Revocation Endpoint)には、バージョンによって「1本revokeすると同一ユーザー/クライアントのオフラインセッションがまとめて消える」といった挙動差の報告があります(keycloak/keycloak #26532)。本番で個別revokeを前提にする前に、お使いのバージョンで必ず実挙動を検証してください。

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レイヤーのドキュメントを確認してください。

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はサイト間の無効化通知やタスク同期に用いる、という役割分担になります。マルチアカウント/マルチサイトの統制観点はマルチアカウント統制もご覧ください。

現場のコツ:KC26でアクティブユーザーが多い環境へ移行する際は、セッションテーブルへの書き込みがDBのボトルネックになりやすいポイントです。SSO Session Idle/Maxとリフレッシュ間隔を見直し、不必要に短いリフレッシュで書き込みを増やしていないかを、移行前に必ず点検してください。

まとめ

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でエンタープライズの認証基盤を実構築してきました。具体的な事例は導入事例もご覧ください。

参考(一次情報)

認証基盤のセッション設計やSSO/SLOの実装でお困りの際は、Keycloakの実構築経験を持つ私たちにお問い合わせください。

相談する
← ブログ一覧へ戻る