GitHub(nextgroup2706/ken_nogi)は今後使わず自社Gitea運用に切替え。 NodeSrvは旧リポジトリの履歴を破棄しファイルのみ統合(Dokploy用サービスアカウントは 別途mygit-admin/NodeSrv.gitに履歴あり)。notepmエクスポート(12GB)とPleasanter インストーラzip(208MB)はサイズが大きいため.gitignoreで除外。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
8.0 KiB
org-master-sync phase3: 本番プリザンター投入 + Keycloak本番切替
2026-08-12実施。本番プリザンター(nextoffice.next-hd.co.jp)へのマスタ投入と、Keycloak nexthdレルムの検証環境→本番環境切替、SSO確認画面の完全排除を実施した記録。
1. 本番プリザンターへのマスタデータ投入
.env.productionにemail-overrides(kenichiro.nogi=460,mitsuharu.takahashi=678)を設定merge-master.js --no-create-groups実行 → 613件新規作成(グループ・組織テーブルへの新規作成なし、既存一致分のみ反映)- 役職マスタ8件・職級マスタ6件・利用権限タイプマスタ4件、LINEWORKS取得結果と完全一致
- Groups APIは新規作成ゼロ(既存59グループから変化なし)
- 所属グループ(Class035)は反映時点で全員空 — 本番Groups APIに一致するグループが存在しなかったため(意図通り、別途対応)
途中、本番プリザンターがバージョンアップ+SSO対応作業中で一時的にAPI不通(502)になる場面あり。復旧後に再開。
2. Keycloak nexthdレルムの洗い替え
背景: これまでのnexthdレルムは検証環境プリザンター(nextoffice2.next-hd.net)のマスタ(SiteId=1)を基準に同期していた351件。本番運用切替につき、本番マスタ(SiteId=502552)ベースへ全面入れ替えが必要だった。
手順:
- 旧351件(検証同期分)を全削除(
DELETE /admin/realms/nexthd/users/{id}、service-account-org-master-sync除く) sync-keycloak.js --executeを.env.productionで実行 → 351件新規作成、update/delete 0件- サンプル確認(
ntkco12216→kenichiro.nogi_502662):Class011=460,Class036=kenichiro.nogi@next-hd.co.jp、正しく反映
ハマった点: 初回実行時、削除より先にcreate/updateが走る設計のため、旧351件が残った状態で本番データのcreateを試み、メールアドレス重複エラー(User exists with same email)で失敗。旧データを先に全削除してから再実行して解決。
プリザンターSAML Client URL変更: Keycloak Admin API経由でclientId(EntityId)・redirectUrisをnextoffice2.next-hd.net→nextoffice.next-hd.co.jpへ更新。表示名も「プリザンター(本番)SSO」に変更。
3. 検証用レルムnexthd-testの複製
nexthdが本番専用になるため、今後も継続利用する検証環境としてnexthd-testを新規作成。
試して失敗した方法:
- Keycloak管理コンソールの「Create realm」でpartial-exportしたJSONをそのままアップロード → 内部UUID(
id)が既存レルムと衝突しConflict detected idを再帰的に全削除 → 今度はauthenticationFlows内の相互参照(親子関係)が壊れUnable to resolve auth flow binding overrideauthenticationFlowsのidだけ保持 → 別のid衝突(constraint_auth_pk)
成功した方法: 空レルム作成 + Partial Import
- Keycloak管理コンソールで
nexthd-testを空レルムとして作成 PartialImportRepresentation形式({ifResourceExists, clients, identityProviders, identityProviderMappers, groups}。authenticationFlowsは対象外、Keycloak仕様上の制約)でJSON生成、id/internalIdを再帰削除clients内のauthenticationFlowBindingOverrides(元レルムのカスタムフローid参照)を削除しないとUnable to resolve auth flow binding override for: browserで失敗するため要除去- Partial Import画面からアップロード → クライアント9件・IdP1件・グループ63件、正常インポート
- ユーザー(351件)とグループメンバーシップ(1940件)はPartial Import非対応のため別途Admin API経由で個別複製(
GET /admin/realms/nexthd/users→POST /admin/realms/nexthd-test/users、グループ紐付けは元レルムのGET /users/{id}/groups→PUT /users/{id}/groups/{groupId})
org-master-syncクライアントのシークレットは複製時にリセットされる(平文コピーされない仕様)ため、GUIから再発行が必要だった。.envのKEYCLOAK_REALM/KEYCLOAK_ADMIN_CLIENT_SECRETをnexthd-test向けに更新済み。
4. SSO確認画面の完全排除(最重要の技術的知見)
要件: LINEWORKS SSOログイン時、確認画面(Account already exists → Add to existing account のワンクリックも含む)を一切出さず完全自動ログインさせたい。
試して失敗したアプローチ(Keycloak 26.0.8実機検証):
Confirm link existing accountをDisabled → 新規ユーザー作成画面に見えるUpdate Account Informationが出た- 真因判明:
Update Profile on First Login(Review Profileステップの個別設定)がmissing。LINEWORKSがfirstName/lastNameを送らない(<AttributeStatement>が空、NameIDのみ)ため「情報不足」判定 →offに変更して解消
- 真因判明:
- 改めて
Confirm link existing accountをDisabled →Account verification options配下のVerify Existing Account by Re-authenticationがフォールスルー実行され、パスワード未設定でInvalid username or password Verify Existing Account by Re-authenticationもDisabledに変更 → その孫ステップUsername Password Form for identity provider reauthenticationはUI上Requirement変更不可(常にRequired固定)で実行され、同じエラーが再発
結論: Keycloakの標準First Broker Loginフローは、親ステップをDisabledにしても配下のRequired固定ステップがフォールスルー実行される仕様上の制約があり、フロー設定の調整だけでは確認画面を完全に消せない。
最終解決策(実機検証済み): Keycloak Admin API POST /admin/realms/{realm}/users/{id}/federated-identity/{provider} で、SSOログイン前にfederated-identityを事前登録する。userIdはSAML NameIDと一致する値(LINEWORKSメールアドレス)。これによりKeycloakは「初回ログイン」と判定せず、First Broker Loginフロー自体を丸ごとスキップし、通常のBrowserフローのみで確認画面なし・即ログイン成功する。
実装:
apps/org-master-sync/src/lib/keycloakClient.jsにgetFederatedIdentities/linkFederatedIdentity追加sync-keycloak.jsのユーザーcreate/update時に自動リンク(未リンクの場合のみPOST、既にリンク済みなら何もしない)- 351人全員へ一括登録実施済み
- テスト94件全パス
フロー設定はDisabledのまま維持する方針(ユーザー確定)。 federated-identity登録漏れのユーザーは「確認画面を出す」のではなく「Invalid username or passwordでログイン自体を弾く」方が安全という判断。サイレントにログインさせないことをデフォルトの安全策として採用。
残課題
→ 対応済み(本番側でAuthentication.jsonのProviderをnull→"SAML"に変更してSSO有効化"SAML"に更新確認済み)SAML署名証明書のSubject DNが旧URL(→ 放置確定。SSOログイン成功済み=署名検証は正常通過している証拠(署名検証は公開鍵でのバイト列検証のみでCNの中身は見ない)。エラーが出る場合はKeycloak Client詳細→Keysから鍵再生成nextoffice2.next-hd.net)のまま→ 対応済み。nexthd-testレルムのFirst Broker Loginフロー・認証フローカスタマイズ(Account verification options等)は未複製Confirm link existing account/Account verification optionsをDisabled、IdPUpdate Profile on First Loginをoffに変更、351人分federated-identityも一括登録。nexthd-testのSAML Client URLはたまたまnextoffice2.next-hd.netのまま(複製タイミングが本番URL変更"前"だったため)、検証環境として意図せず正しい状態