インフラ拡大に伴うアイデンティティ管理の課題
45名のエンジニアチームが、12個もの社内Webアプリケーションで認証情報を個別に管理している状況を想像してみてください。Jenkinsのダッシュボード、社内Wiki、Grafanaのモニタリング画面、ステージング環境のクラスタなど、あらゆるツールがサイロ化した独立したユーザーデータベースを抱えています。
エンジニアの新規オンボーディングでは、5〜6つの管理コンソールで手動アカウント作成が必要になり、採用ごとにDevOpsエンジニアの時間を1時間も奪ってしまいます。さらに深刻なのがオフボーディングです。金曜日の午後にエンジニアが退職した際、各独立システムのアカウントを手作業で削除していては、アクティブなセッショントークンや孤立したアカウントが見落とされ、深刻なセキュリティリスクに晒されることになります。
当然ながら、メンバーはパスワード疲れに陥ります。各環境で10文字程度の脆弱なパスワードを使い回したり、暗号化されていない共有テキストファイルに認証情報を保存し始めたりします。統合されたIdentity and Access Management(IAM)層が存在しないと、監査ログは散乱し、ワンクリックでのセッション破棄もできず、日常的に使用するツール間でセキュリティ基準が著しく不揃いになってしまいます。
IAMの基本概念:レルム(Realm)、フェデレーション、シングルサインオン(SSO)
コンテナを立ち上げる前に、後々のトラブルシューティングを省くための4つの基礎概念を押さえておきましょう。
- Keycloakレルム(Realm): ユーザー、認証情報、ロール、連携アプリケーションを包含する独立したセキュリティドメインです。デフォルトの
masterレルムは管理者用コントロールプレーンとしてのみ機能します。社内スタッフや日々の業務サービス向けには、必ず別のレルム(例:internal-corp)を新規作成してください。 - OpenID Connect(OIDC)& SAML: Keycloakは最新のIDプロトコルを仲介します。多くのWebプラットフォームは、OAuth 2.0をベースにRS256署名付きJWTトークンを利用するOIDCを介してKeycloakと連携するため、アプリケーション側が生のパスワードを保持・処理することはありません。
- ユーザーフェデレーション(User Federation / LDAP): 重複したデータベースを並行運用する代わりに、KeycloakはOpenLDAPやActive Directoryなどの外部ディレクトリサービスに直接バインドします。ユーザーツリーを読み取り、LDAPバインドリクエストで認証情報を検証し、プロファイルメタデータをローカルにキャッシュします。
- 多要素認証(MFA / 2FA): Keycloakは標準規格RFC 6238のTime-based One-Time Password(TOTP)に対応しています。ユーザーはGoogle AuthenticatorやFreeOTPなどのアプリでQRコードをスキャンするだけで設定でき、有料のSMSゲートウェイを導入する必要はありません。
ハンズオン実践:Keycloak、PostgreSQL、OpenLDAPの環境構築
ステップ1:Docker Composeによるインフラ構成の定義
KeycloakはQuarkusランタイム上で動作し、メタデータの保存先としてPostgreSQLとスムーズに統合できます。Keycloakと併せて、アイデンティティ情報を保管するOpenLDAPと、スキーマ管理用の軽量WebクライアントであるphpLDAPadminも同時に起動します。
32文字以上の高エントロピーなデータベース用および管理者用パスワードを生成する場合、toolcraft.app/ja/tools/security/password-generator のクライアントサイドジェネレーターが便利です。ネットワーク経由でキーを送信せず、ブラウザメモリ上でローカルにエントロピーを計算して安全に生成できます。
以下の設定を docker-compose.yml として保存します。
version: '3.8'
networks:
iam-network:
driver: bridge
volumes:
postgres_data:
ldap_data:
ldap_config:
services:
postgres:
image: postgres:15-alpine
container_name: keycloak-db
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak_admin
POSTGRES_PASSWORD: ReplaceWithAStrongSecretDbPass123!
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- iam-network
restart: unless-stopped
openldap:
image: osixia/openldap:1.5.0
container_name: openldap
environment:
LDAP_ORGANISATION: "Example Corp"
LDAP_DOMAIN: "example.com"
LDAP_ADMIN_PASSWORD: ReplaceWithLdapAdminPass123!
volumes:
- ldap_data:/var/lib/ldap
- ldap_config:/etc/ldap/slapd.d
networks:
- iam-network
restart: unless-stopped
phpldapadmin:
image: osixia/phpldapadmin:0.9.0
container_name: phpldapadmin
environment:
PHPLDAPADMIN_LDAP_HOSTS: openldap
PHPLDAPADMIN_HTTPS: "false"
ports:
- "8080:80"
networks:
- iam-network
depends_on:
- openldap
restart: unless-stopped
keycloak:
image: quay.io/keycloak/keycloak:24.0.1
container_name: keycloak-server
command: start-dev
environment:
KC_DB: postgres
KC_DB_URL_HOST: postgres
KC_DB_URL_PORT: 5432
KC_DB_URL_DATABASE: keycloak
KC_DB_USERNAME: keycloak_admin
KC_DB_PASSWORD: ReplaceWithAStrongSecretDbPass123!
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: ReplaceWithAdminConsolePass123!
ports:
- "8081:8080"
networks:
- iam-network
depends_on:
- postgres
restart: unless-stopped
バックグラウンドで環境を起動します。
docker compose up -d
docker compose logs -f keycloak
ログを確認します。およそ15〜20秒でKeycloakに Running the server in development mode. Started... と出力されます。これで http://localhost:8081 からKeycloakへ、http://localhost:8080 からphpLDAPadminへアクセスできるようになります。
ステップ2:OpenLDAPにテストユーザーを登録
ブラウザで http://localhost:8080 を開きます。管理者DN cn=admin,dc=example,dc=com と設定した LDAP_ADMIN_PASSWORD でサインインします。users という名前の構造的組織単位(OU)を作成し、ou=users,dc=example,dc=com 配下にテストアカウントを追加します。
- 名(givenName): Alex
- 姓(sn): Mercer
- ユーザー名(uid): amercer
- メールアドレス(mail): [email protected]
- パスワード(userPassword): TemporaryPass987!
ステップ3:ユーザーフェデレーションでKeycloakとOpenLDAPを連携
http://localhost:8081のKeycloak管理コンソールにKEYCLOAK_ADMINの認証情報でログインします。- 左上のレルムセレクターをクリックし、Create Realm を選択して、レルム名を
internal-corpと入力します。 - 左側のサイドバーで User federation を開き、Add LDAP providers を選択します。
- 接続パラメータを設定します:
- UI display name:
Company-OpenLDAP - Vendor:
Other - Connection URL:
ldap://openldap:389 - Users DN:
ou=users,dc=example,dc=com - Authentication type:
simple - Bind DN:
cn=admin,dc=example,dc=com - Bind credential:
ReplaceWithLdapAdminPass123! - Username LDAP attribute:
uid - RDN LDAP attribute:
uid - UUID LDAP attribute:
entryUUID - User object classes:
inetOrgPerson, organizationalPerson, person - Edit mode:
READ_ONLY(LDAPを信頼できる単一の情報源として維持する場合は読み取り専用のままにし、ユーザーによるパスワード変更をディレクトリ側へ書き戻したい場合はWRITABLEに切り替えます)
- UI display name:
- Test connection、続けて Test authentication をクリックします。両方で緑色の成功バッジが表示されたら、Save をクリックします。
- 下部の Sync settings ペインまでスクロールし、Sync all users をクリックします。Keycloakの Users タブを確認すると、ディレクトリのメールアドレスやプロファイル情報を保持した状態で
amercerが即座に表示されます。
ステップ4:二要素認証(TOTP)ポリシーの強制適用
LDAPからユーザー情報が連携されたら、連携先ツール全体に2FAを必須化する設定は2分もかからずに完了します。
internal-corpレルム内で、Authentication > Required actions をクリックします。- Configure OTP を見つけ、Set as default action を有効化します。これにより、認証アプリの登録を行っていないすべてのアカウントに対し、次回の初回ログイン時に設定が義務付けられます。
- Authentication > Policies > OTP Policy に移動します。ハッシュアルゴリズムをSHA-256、標準的な6桁コード、有効時間(トークンウィンドウ)30秒に設定することをおすすめします。
さっそくこのフローをテストしてみましょう。http://localhost:8081/realms/internal-corp/account/ にアクセスし、amercer としてサインインします。KeycloakはOpenLDAPに対してパスワードを検証した後、直ちにセッションの進行を停止し、登録用QRコードを表示します。ユーザーは最初の6桁コードを検証するまで、連携ツールにアクセスすることはできません。
現場での運用ノウハウとアーキテクチャの知見
高トラフィックな本番環境でコンテナ化されたKeycloakを運用してきた経験から、特に重要となる3つの運用ルールがあります。
start-devはローカル開発環境のみにとどめる:start-devフラグは重要なTLS検証を無効化し、平文のHTTPに直接バインドします。ステージングや本番環境では、マルチステージDockerfileを用意し、PostgreSQLドライバーを事前キャッシュした上でkc.sh buildを実行してビルドします。そして、443ポートでTLS終端を処理するリバースプロキシ(TraefikやNGINXなど)の背後に配置し、kc.sh start --optimizedでコンテナを起動してください。- アクセストークンの有効期限は短く保つ: アクセストークンの有効期間は5分程度が最適です。トークン更新のハンドシェイクを避けるためだけにアクセストークンを8時間に延ばすような運用は避けてください。ベアラートークンが漏洩した際に管理上の悪夢を招くことになります。5分程度の短いアクセストークンと12時間程度の長めのリフレッシュトークンを組み合わせ、Revoke Refresh Token を有効にして交換のたびにリフレッシュトークンをローテーションさせましょう。
- バックグラウンド同期ジョブを自動化する:
READ_ONLYのLDAP構成では、新規追加されたメンバーがログインするか手動同期を実行するまで、Keycloakの検索一覧に反映されません。これを防ぐため、Periodic Full Sync(86,400秒=24時間ごと)と Periodic Changed Users Sync(300秒=5分ごと)を有効化してください。これにより、新しく追加されたLDAPグループやメンバー変更が手作業ゼロでKeycloakのロールマッピングに反映されます。
Docker上でKeycloakとOpenLDAPを組み合わせることで、堅牢で実績のあるIAMアーキテクチャが完成します。アプリケーションはOIDCを通じて認証を委譲し、システム管理者はクリーンで一元管理されたディレクトリを維持でき、運用中のあらゆる社内ダッシュボードに対してTOTP必須化などの強固なセキュリティベースラインを一貫して適用できます。
