docs: ADR-0038 — EWBI auth drift from mTLS to OAuth2 Client-Credentials (Keycloak federation realm); mTLS deferred
Summary
Corrects a spec drift in the Federation Manager E/WBI authorization model: mTLS is no longer the primary mechanism — OAuth2 Client-Credentials + signed JWT is, per GSMA OPG.04 v6.0 Sec. 9. mTLS is reclassified as deferred defense-in-depth (sender-constrained tokens, RFC 8705) until real Nginx mTLS termination exists.
Introduces ADR-0038 and propagates the correction across the FM and platform architecture docs. The persistence model is excluded from this MR — it is WIP on a separate branch.
The drift
ADR-0016 (FM stack) assumed in passing that E/WBI authorization is mTLS with pre-exchanged client certificates, terminated by Nginx, with FM validating the client-cert thumbprint against partner_ops. Checked against the actual normative artifact — GSMA OPG.04 v6.0 — that does not match:
- OPG.04 Sec. 9 mandates OAuth2 Client-Credentials + signed JWT (JWS, RFC 7515) for E/WBI authorization. The OpenAPI 3.0.3 contract (
OPG.04_EWBI_Federation_API_v1.4.0.yaml) declares a single root-levelsecurityrequirement (oAuth2ClientCredentials: [fed-mgmt]) covering all 74 operations, with no mTLS securityScheme and zero per-operation overrides. - Sec. 9.2 assigns roles (Partner OP = Authorization + Resource Server; Originating OP = Client); Sec. 9.3 mandates signed JWT; Sec. 9.5 requires the same grant for callbacks.
- Sec. 9's lone "if OAuth2 is used" hedge is internally contradictory with the rest of Sec. 9 and the contract itself — read as a drafting slip, not real optionality.
- OPG.02 v10.0 Sec. 4.2.3 / 3.3.4.5 do sanction certificate-based mutual authentication for OP-to-OP connection identity — legitimate, but a different layer than Sec. 9's per-request authorization. The two stack; they don't substitute.
On the implementation side: FM does not implement OAuth2/JWT for E/WBI today, and the Nginx mTLS terminator ADR-0016 assumed does not exist yet — today's cert-thumbprint header is not derived from any real TLS client-certificate handshake, so it proves no identity cryptographically. It is a partner lookup, not authentication, and cannot satisfy REQ-FED-01 on its own.
The platform already runs a centralized Keycloak (core Compose profile) serving OEG's NBI auth and FM's own internal admin routes (realm oop). This ADR extends that existing pattern with a dedicated federation realm — partner OPs are an external, adversarial-by-default trust domain, isolated from internal/admin identity.
Decision (ADR-0038)
- E/WBI authorization = OAuth2 Client-Credentials + signed JWT via the platform's centralized Keycloak,
federationrealm. Each partner gets its own Keycloak client (fed-mgmtscope;fed-mgmt-notiffor callbacks). FM is both Client (outbound) and Authorization+Resource Server (inbound). - mTLS is not deleted — reclassified as deferred defense-in-depth.
partner_ops.cert_thumbprintstays as a future hook (RFC 8705 sender-constrained tokens once real Nginx mTLS termination lands); removed from today's authorization decision path. - Signing = JWS (RFC 7515), matching Keycloak's default and OPG.04 Sec. 9.3's primary recommendation — not the MAC alternative, which only earns its keep absent a real Authorization Server. There is one.
What changes in the docs
| File | Change |
|---|---|
decisions/0038-ewbi-oauth2-client-credentials-mtls-deferred.md |
New ADR. |
decisions/index.md |
ADR-0038 registered (ADR-0037 is canonical-target-ports on develop — renumbered from 0037 to avoid the collision). |
fm/requirements-and-design.md |
REQ-FED-01 rewritten: OAuth2 Client-Credentials + JWT is the requirement; mTLS is deferred. Spec refs corrected. |
fm/overview-and-architecture.md |
EWBI termination + partner-auth positions updated; assumptions F2/F5/F6 revised (F6 elevated to high risk — the federation realm is now the primary EWBI mechanism, with no fallback). |
fm/implementation-and-delivery.md |
§P.3 rewritten from mTLS to OAuth2 (inbound JWKS/JWT validation; outbound token acquisition + cache); mTLS moved to new deferred §P.3.1. Boundary + threat tables updated. |
platform/architecture.md |
FM EWBI gateway pattern + platform boundary/role tables updated. |
platform/future-architecture.md |
Federation-partner auth row updated. |
fm/persistence-model.md is deliberately not in this MR — it is WIP on add-fm-persistent-model. The ADR-0038 Security-Design alignment for the persistence model will land with that branch.
Related issues
This MR is the architecture-side resolution of the FM E/WBI auth drift, tracked in the oop/code/federation-manager repo:
- oop/code/federation-manager#13 (closed) — FM E/WBI auth strategy: OAuth2 now (OPG.04 Sec. 9), mTLS deferred (ADR-0016 amendment) — the strategy issue this ADR records.
- oop/code/federation-manager#18 (closed) — Implement E/WBI OAuth2 Client-Credentials + signed JWT auth, FM to FM (OPG.04 Sec. 9) — the implementation issue.
- oop/code/federation-manager#7 (closed), #8 — historical context (prior E/WBI security / OAuth2 server-URL-config issues, closed).
⚠️ Open tension to flag for reviewers
ADR-0038 chooses a centralized Keycloak federation realm (platform-shared infrastructure) as the Authorization Server. Issue #18 carries a decoupling constraint: "Auth is self-contained to FM; it must not rely on [...] shared platform infrastructure beyond what FM itself runs" and "No hard coupling to any other component's identity provider; FM validates partner tokens against the partner's advertised issuer/authz server."
These two positions are not obviously reconcilable:
- The ADR's model has FM validate inbound partner tokens against the platform's Keycloak (
federationrealm) JWKS — i.e., FM as Resource Server trusts its own platform's AS. - Issue #18's model has FM validate against the partner's advertised issuer — i.e., cross-realm trust / federation, where each OP runs its own AS and they trust each other's JWTs.
Both are defensible readings of OPG.04 Sec. 9 (Sec. 9.2 assigns both Client and AS roles to each OP for its own domain). The difference is whether the inbound Authorization Server is the local platform Keycloak (ADR-0038) or the partner's remote AS (issue #18). This needs a decision before #18's implementation finalizes, so the architecture and the implementation agree. I've left the ADR accepted on the architecture side but flagged this here so it is reviewed consciously.
Commits
c0f9fea docs: propagate ADR-0038 to platform architecture + future-architecture
78dcdf3 docs: align FM implementation-and-delivery EWBI auth to ADR-0038
6dbfe4a docs: align FM overview-and-architecture to ADR-0038
497e93c docs: align FM REQ-FED-01 to ADR-0038 (OAuth2 over deferred mTLS)
ff414a3 feat: add ADR-0038 — EWBI auth is OAuth2 via Keycloak; mTLS deferred