ADR 0015 Dex-First Identity Federation
ADR 0015 Dex-First Identity Federation
Section titled “ADR 0015 Dex-First Identity Federation”Context
Section titled “Context”Keycloak currently handles ordinary OIDC, directory lifecycle, custom attributes, and SCIM-related administration. That couples standard consumers to provider-specific behavior and makes client ownership ambiguous. Dex provides the standard federation surface, while Keycloak capabilities remain necessary for directory mutation and selected extensions.
Decision
Section titled “Decision”Dex is the default authentication authority for interactive OIDC routes. Keycloak remains the directory-mutation authority, Dex upstream identity provider, and temporary machine-to-machine token authority while stable Dex lacks the native client-credentials grant. Direct Keycloak authentication requires a declared capability and bounded reason: SCIM mutation, custom attribute claims, provider extension, password grant, or this version-bounded client-credentials exception. Do not custom-build Dex to close the gap; move the route after the feature reaches a stable upstream release and passes live proof.
Contract owns the route schema and compatibility rules. Backend owns provider-neutral admission policy and projections. Assembly owns client inventory, exact issuers, callbacks, secret references, Dex deployment, CNPG database, network policy, and rollout evidence. One client has one writer; Dex-owned clients cannot also be projected directly into Keycloak.
Boundaries
Section titled “Boundaries”Secrets remain OpenBao references. Dex stores durable state in the assembly-managed CNPG plane. Consumer configuration never embeds environment addresses in backend or contract source. Keycloak exception routes require reviewable reason and capability; an unclassified direct route fails admission.
Implementation Evidence
Section titled “Implementation Evidence”- Contract:
schemas/identity-federation/. - Backend: identity stack authentication admission and Dex/Keycloak projections.
- Assembly:
platform/k8s/environments/lxc-pve-lab/runtime.cue,platform/k8s/apps/dex/, the Dex Application, and generated values. - Deployment: Assembly revision
8f287434bd2da4e5df6c12b4fa9dcd61d1c532e0is synced and healthy in Argo CD. - Edge: Cloudflare Tunnel configuration version
287routesdex.yamon.ioto the Pomerium edge; Pomerium admits the public issuer route without creating an authentication loop. - Public smoke proof: discovery and JWKS return HTTP 200, and the
dex-smokeauthorization request returns HTTP 302 to the declared Keycloak connector. - Browser proof: the Keycloak login and consent path returned an authorization code to
the declared loopback callback; the code exchange and refresh grant both succeeded.
The refreshed ID token retained issuer
https://dex.yamon.io, audiencedex-smoke, subject, email, and 11 groups. - Stable-channel boundary: live Dex
v2.44.0returnedunsupported_grant_typeforclient_credentials; source inspection confirmed the handler is absent through stablev2.45.1and exists only on unreleased upstream main. Assembly PR #432 removed the ineffective configuration and Argo CD reconciled the rollback to Synced/Healthy.
Exercised consumer rollback and database recovery remain required before implementation can be marked complete.
Rollback
Section titled “Rollback”Restore each consumer to its prior Keycloak issuer and pinned client configuration. Keep Dex idle until sessions drain; do not delete Keycloak clients or directory state during the additive rollout window.
Revision History
Section titled “Revision History”- 2026-07-30: Proved browser callback and refresh continuity, and bounded machine credentials to Keycloak until native Dex support reaches a stable release.
- 2026-07-30: Recorded deployed issuer and edge-routing smoke evidence.
- 2026-07-12: Accepted by repository owner directive; implementation started.