ADR-0002 — Keycloak as base IdP with a pluggable multi-provider identity abstraction
Status: Approved Date: 2026-04-19 Owners: Platform Architecture, Security Supersedes: PLT-ADR-004 (Firebase Authentication) Related: ADR-0001 Kong edge gateway, auth-service SERVICE_OVERVIEW, auth-service SECURITY_MODEL, 01-enterprise-architecture §3.1
1. Context
The original identity choice (PLT-ADR-004) hard-coded Firebase Authentication as the only supported IdP, embedded inside auth-service. This was acceptable while the platform was pre-product: cheap, fast to integrate, MFA out of the box.
As we move to land enterprise tenants, three forces converge:
- Enterprise SSO. Target customers (telco channel partners, enterprises, government) require SSO against their own corporate IdP — Azure AD, Okta, Google Workspace, ADFS, or a generic OIDC/SAML provider. Firebase cannot broker arbitrary tenant IdPs at the realm level we need.
- Regulated regions. Several target markets mandate on-prem / sovereign-cloud identity storage. A SaaS-only IdP (Firebase, Auth0) is not deployable in all regions we intend to operate.
- Vendor lock-in. Any choice made at the core of the platform must be reversible. A thin abstraction in front of the IdP is a small engineering cost; the optionality it preserves is large.
2. Decision
- Adopt Keycloak (self-hosted, LTS) as the platform's base / default IdP. Keycloak is responsible for user credential storage, MFA, and — critically — acting as an OIDC/SAML broker for any tenant that federates their own external IdP.
- Introduce an IdP Provider Abstraction inside
auth-service: a singleIdentityProviderport with pluggable concrete providers —KeycloakProvider(default),TenantOidcProvider,TenantSamlProvider,FirebaseLegacyProvider,NativeProvider(fallback). Provider selection is driven by atenant_identity_providersbinding, not code. - Downstream services remain IdP-agnostic. They see only the platform JWT (issued by
auth-service, signed RS256, validated by Kong). Theidpclaim is recorded for audit but MUST NOT be used for authorization. - Firebase is demoted to legacy-only. Existing Firebase-based users are kept working via
FirebaseLegacyProvider. No new tenant is onboarded onto Firebase. - SCIM 2.0 inbound is exposed by
auth-servicefor enterprise tenants that push users from their corporate IdP.
3. Consequences
Positive
- We can land any enterprise tenant with corporate SSO without a code change — only a config change (register their OIDC discovery URL or SAML metadata).
- Keycloak can be deployed in-region (including sovereign clouds) for regulated markets.
- Vendor lock-in is contained to a single provider class; swapping Keycloak for another base IdP (e.g., AWS Cognito, Authentik) in the future is a
KeycloakProvider-scoped change. auth-servicebecomes an anti-corruption layer: all external claims are normalised into the platform identity model before persistence.
Negative / costs
- Keycloak is an additional piece of operational surface: HA deployment, upgrades, realm import/export, signing-key rotation, DB schema.
- The
IdentityProviderport adds complexity vs. a single-provider codepath — cost is acceptable for the optionality it buys. - Testing matrix grows: per-provider e2e suites + contract tests for the broker boundary.
Neutral
- The platform JWT shape is unchanged other than the new
idp/idp_subclaims. Kong and downstream services need no migration.
4. Alternatives considered
| Option | Why rejected |
|---|---|
| Keep Firebase only | Fails enterprise SSO and sovereign-cloud requirements |
| Auth0 / Okta (SaaS) as base | Same sovereign-cloud / region issues + vendor lock-in + cost at scale |
| Build a homegrown IdP | Security surface too large; SAML 2.0 and OIDC broker features are famously hard to get right — do not reinvent |
| Keycloak only (no abstraction) | Couples every service to Keycloak-specific claims; makes future migration costly |
5. Implementation & rollout
Detailed in auth-service MIGRATION_PLAN §3.
6. Status
Approved 2026-04-19. Keycloak is present in the baseline architecture (01-enterprise-architecture §2, §3, §3.1, §7, §9, §10). auth-service specs are rebaselined under this ADR (SERVICE_OVERVIEW, SECURITY_MODEL, DOMAIN_MODEL, DATA_MODEL, API_CONTRACTS, APPLICATION_LOGIC, EVENT_SCHEMAS, DEPLOYMENT_TOPOLOGY, LOCAL_DEV_SETUP).