ADR 0001: identity-admin stays a BFF, layered so non-browser callers can be added later without rework
- Status: Accepted
- Date: 2026-10-06
Context
Section titled “Context”The platform’s four-component shape is: MyPage(①, 全ユーザー)、管理コンソール(②, 管理者)、Identity Hub の業務ロジック層(③)、Keycloak(④)。① と ② は ③ だけを経由し、Keycloak に直接触れない。
The open question: does ③ need to be a general-purpose HTTP API that COSMO and master-data sync call directly, in addition to serving ① and ②?
Looking at the actual two external integrations:
| 対向先 | 方向 | 実態 |
|---|---|---|
| COSMO | Identity → COSMO(利用状況・ログ) | 非同期でよい。API 呼び出しを待たない |
| マスターデータ | マスターデータ → Identity(人員・組織・協力会社) | 定期/イベント駆動の取り込みでよい。同期呼び出しを待たない |
| ①②(ブラウザ) | 双方向 | リクエスト即応答が必要。ブラウザセッションが前提 |
Neither COSMO nor master-data sync needs a synchronous API call. Building a general-purpose “anyone can call it” HTTP API now, before a real synchronous caller exists, is speculative.
Decision
Section titled “Decision”identity-admin remains the Console’s BFF — no new general-purpose API service now. Internally, it is layered:
Router/BFF layer ← session/cookie handling, CSRF, request parsing onlyApplication service ← permission checks, target policy, business rules, audit writes (the core logic)Keycloak adapter ← KeycloakAdminClient, encapsulates the Admin REST APIThe one binding rule: the application service layer takes a plain Actor value (e.g. {issuer, sub, displayName, permissions, authTime} — see ConsolePrincipal), never a session, cookie, or HttpServletRequest. The service layer must be constructible and callable without any browser-session concept existing at all.
Session Management (Task 5 of the Identity Console P0 implementation plan, docs/superpowers/plans/2026-10-05-admin-console-implementation-plan.md) is the first write action built against this rule, and is the template subsequent write actions (Task 6+, and anything in the #5/#9/#14 epics) copy.
Integration directions:
- Identity → COSMO: an event/log pipeline (CloudWatch → S3/Kinesis → COSMO), not a synchronous API call COSMO makes against this app.
- Master data → Identity: an independent sync job/worker that calls the application service layer directly (in-process or via a thin internal entry point), not through the BFF’s cookie/CSRF machinery.
- A future synchronous machine caller (e.g. another internal system auto-provisioning a partner-company account) gets a thin, separately-authenticated entry point (client-credentials, mTLS, or similar) beside the BFF, calling the same application-service methods with a different
Actor. The BFF itself does not change.
Consequences
Section titled “Consequences”- No new service to build, deploy, or operate right now.
- The application-service layer must be kept honestly decoupled from session/cookie state — every future task review should check new service methods against this rule, not just this ADR’s authors.
- If a genuine synchronous external caller materializes later, adding its entry point is additive (a new thin layer beside the BFF), not a rewrite — contingent on the layering rule actually having been followed.
- Audit unification (see ADR 0002) is handled separately, at the sink, not by merging write paths now.