Keycloakはデフォルトのまま動いてしまうため、本番投入前に「締める」作業が抜けやすいプロダクトです。HTTPS強制、hostname、adminコンソールの隔離、ブルートフォース防御、CVE追随まで、現場で実際に確認している項目を公式ドキュメントに沿って整理しました。
Keycloakは開発モード(start-dev)なら証明書もhostnameも気にせず起動できてしまう反面、その手軽さのまま本番へ持ち込むと、あとから穴が見つかりがちなプロダクトです。ここでは新しめのQuarkusベース版(WildFly版は非推奨のため、以下はQuarkus版基準です。バージョン依存の挙動は必ず公式で確認してください)を前提に、本番投入前に「締める」項目をチェックリスト形式で整理します。
01まず全体像 — 何を締めるのか
ハードニングと一口に言っても、レイヤは分かれます。ざっくり「入口(TLS/hostname/proxy)」「管理面(adminコンソールの隔離)」「認証防御(ブルートフォース/パスワードポリシー)」「アプリ結合(クライアント設定)」「運用(CVE追随/ヘッダ)」の5層です。下図の順にレビューしていくと漏れが出にくくなります。
02HTTPS強制とTLSの取り回し
公式ドキュメントは「Keycloakとの通信はすべて安全な通信路を必要とする」と明言しています(Configuring Keycloak for production)。実運用ではTLS終端をどこに置くかで設定が変わります。
- リバースプロキシ/ロードバランサでTLS終端する構成(エンタープライズで多数派):Keycloak自身はHTTPで待ち受け、プロキシがHTTPSを担います。この場合
--proxy-headers forwarded(またはxforwarded)を明示し、KeycloakがForwarded/X-Forwarded-*を信頼して元のスキームを再構成できるようにします。 - Keycloakで直接TLS終端する構成:
--https-certificate-file/--https-certificate-key-file(またはキーストア)でサーバ証明書を渡します。
加えて、realm単位のSSL Required設定を必ず確認します。値はexternal(プライベートIP以外はHTTPS必須・デフォルト)/all(全リクエストHTTPS必須)/none(開発専用)の3つで、本番では原則allを推奨します。noneのrealmが混ざっていないかは、複数realm運用だと見落としやすいポイントです。
proxy-headersを設定し忘れると、リダイレクトURLがhttp://になったりループしたりします。「ログインは通るがリダイレクトで壊れる」症状の大半はここです。同時に、プロキシ側でX-Forwarded-*を外部から詐称されないよう上書き設定にしておくことも忘れずに。03hostnameを確定させる
Quarkus版のhostname設定(v2)は、動的にリクエストから組み立てるより、本番ではフルURLを固定するのが定石です(Configuring the hostname (v2))。プロキシが443で公開する典型構成なら、次のように起動します。
--hostname https://auth.example.comでフロントエンドURLを固定--hostname-strict false --proxy-headers forwardedでプロキシ経由のヘッダを尊重
hostnameを固定しておくと、トークンのissuerやOIDCのメタデータ(.well-known)に出るURLがぶれません。ここが揺れると、RP側のissuer検証やJWKSエンドポイントの解決で地味に事故ります。
04adminコンソールとREST APIの隔離
公式も「攻撃面を減らすため、管理REST APIとコンソールを別ホスト名またはコンテキストパスで公開する」ことをベストプラクティスとして挙げています(Configuring Keycloak for production)。具体策は次の通りです。
- 別ホストで公開:
--hostname https://auth.example.com --hostname-admin https://admin-auth.internal:8443のように管理系だけ別FQDNへ。 - プロキシで遮断:公開プロキシ側で
/adminおよび管理REST APIへのパスをブロックし、社内ネットワークや踏み台/VPN経由のみに限定する。 - 管理系はインターネットに晒さない:多くのエンタープライズ案件では、adminコンソールは閉域からのみ到達可能にするのが現実的な落としどころです。
なおproxy-headersを使うときに注意すべきは、公開すべきポートの整理です。フロント/バックエンド/管理でホスト名を分けても、実際にプロキシすべきは8443(または8080)だけで、ヘルスチェックとメトリクスが乗る9000番ポートは公開しないのが公式の指針です(Configuring a reverse proxy)。管理系の分離とあわせて、マルチアカウント統制のようにネットワーク境界の設計と一体で考えると整理しやすくなります。
05ブルートフォース防御とパスワードポリシー
見落としが多いのが、ブルートフォース防御はデフォルトで無効という点です(Server Administration Guide)。realm設定の Security defenses > Brute force detection から明示的に有効化します。ロックアウト戦略は用途に応じて選びます。
- 一時ロックアウト(Temporary):一定回数の失敗で一定時間ロック。可用性とのバランスが取りやすく、多くの業務システムで無難な選択です。
- 永久ロックアウト(Permanent):閾値超過で無効化。管理者の解除が必要で運用負荷は上がるが、厳格な要件向き。
- 段階的ロックアウト:一時ロックを繰り返すと永久ロックへ昇格。攻撃継続を抑えつつ正規ユーザーの巻き込みを減らせます。
- 多要素の副次失敗に対する別枠のロックアウトも設定できます。
ロックにより正規ユーザーが締め出されると、それ自体がDoSになり得ます。しきい値・待機時間・最大待機時間はヘルプデスクの運用体制と合わせて決めるのが実務です。また、フェデレーション(LDAP/AD等の外部ストレージプロバイダ)経由のユーザーについても、失敗回数のカウント自体は行われます。ただし読み取り専用のフェデレーションストレージではロックアウト状態を永続化できないケースがあり(この問題は後続バージョンで修正されています)、いずれにせよLDAP/AD連携時はフェデレーション側のネイティブなロックアウトポリシーも併用する多層防御で設計するのが堅実です。
パスワードポリシーも忘れずに。長さ・複雑性・履歴・有効期限をrealmのPassword policyで定義し、要件がある場合はHaveIBeenPwned連携など漏洩パスワード拒否も検討します。
06クライアント設定の締め
Keycloak本体を固めても、クライアント(RP)側の設定が緩いと台無しです。本番前に各クライアントを次の観点で棚卸しします。
- Redirect URIを厳格化:ワイルドカード(
*)や過度に広いパスを避け、正確なコールバックURLだけを許可。オープンリダイレクタの温床になります。 - 機密クライアントはconfidential:サーバサイドで動くアプリはaccess typeをconfidentialにし、シークレットで保護。ブラウザ/モバイルなど秘密を保持できないものはpublic + PKCE必須に。
- PKCEの強制:認可コードフローではPKCE(
S256)を要求し、コード横取りを防ぐ。 - 不要なフローを閉じる:Implicit FlowやDirect Access Grants(パスワードグラント)は必要がなければ無効化する。付与タイプの選定はOIDCの認可グラントの観点で整理すると判断しやすくなります。
- Web Originsを必要最小限にし、CORSを絞る。
加えて、クライアント登録(dynamic client registration)を開放している場合は、匿名登録を無効にするか初期アクセストークンで制御し、勝手なクライアントが増えないようにします。
07セキュリティヘッダとブラウザ側防御
Keycloakはrealmの Security defenses > Headers で、レスポンスヘッダを設定できます。クリックジャッキング対策のX-Frame-Options(およびContent-Security-Policyのframe-ancestors)、通信を強制するStrict-Transport-Security(HSTS)、X-Content-Type-Options: nosniffなどがデフォルトで設定されますが、値が自社要件に合っているかは確認が必要です。特にKeycloakのログイン画面を自社アプリのiframeに埋め込む要件がある場合、frame-ancestorsの緩め方を最小限にとどめないと、クリックジャッキング耐性を自ら削ることになります。CSRF・オープンリダイレクタ・トークン失効ポリシーといった防御も同ガイドにまとまっているので、リリース前に一読をおすすめします(Server Administration Guide)。
08CVE追随と過負荷対策
認証基盤はCVEの影響が直撃するコンポーネントです。KeycloakにはSecurity Policyページがあり、脆弱性はリリースノートで開示されます。運用としては、リリース(セキュリティリリース含む)を購読し、影響評価とパッチ適用のリードタイムをあらかじめ決めておくことが重要です。バージョンアップ手順そのものはバージョンアップ運用の記事もあわせてご覧ください。
可用性面では、公式がhttp-max-queued-requestsによる受付キューの上限設定を挙げています。上限超過時は503を返すことで、認証基盤が過負荷で総崩れになるのを防ぎます(Configuring Keycloak for production)。前段のプロキシ/WAFでのレート制限と組み合わせるのが定石です。
—まとめ — 本番前チェックリスト
最後に、本番投入前の確認項目を一覧にします。
- TLS:プロキシ終端なら
proxy-headers、直接終端なら証明書設定を明示。realmのSSL Requiredはallを基本に。 - hostname:
--hostname https://...でフルURL固定。issuer/メタデータのURLがぶれないこと。 - admin隔離:
hostname-adminで別ホスト or プロキシで/admin遮断。9000番は非公開。 - ブルートフォース:realmごとに有効化。ロックアウト戦略とブレークグラス経路を用意。フェデレーション時は連携先も。
- パスワードポリシー:長さ・複雑性・履歴・漏洩パスワード拒否を要件に沿って設定。
- クライアント:redirect URI厳格化、confidential/PKCE、不要フロー無効化、dynamic registration制御。
- ヘッダ:X-Frame-Options / HSTS / CSP / nosniff の値を確認。
- CVE追随:Security Policy購読とパッチ適用SLAの取り決め。
http-max-queued-requestsで過負荷対策。
EMWではKeycloakによるエンタープライズ認証基盤の実構築を通じ、こうしたハードニングを本番運用まで落とし込んできました。導入事例もあわせてご覧ください。