コンテンツにスキップ

ADR 0001: identity-admin stays a BFF, layered so non-browser callers can be added later without rework

  • Status: Accepted
  • Date: 2026-10-06

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.

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 only
Application service ← permission checks, target policy, business rules, audit writes (the core logic)
Keycloak adapter ← KeycloakAdminClient, encapsulates the Admin REST API

The 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.
  • 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.