Phase 28: Keycloak Declarative Onboarding
Phase 28: Keycloak Declarative Onboarding
Goal: Manage Keycloak realms, clients, and roles declaratively in pal-e-services Terraform so that
tofu apply creates full auth config alongside namespaces, Harbor projects, and ArgoCD apps — with disaster recovery from git.Owner: Dev agent
Repo:
forgejo_admin/pal-e-servicesDepends on: Keycloak server deployed (pal-e-platform, done), admin password in pillar (PR #141, merged), theme files mounted (PR #130, merged)
Why
Today, onboarding auth for a new project requires 5+ manual steps in the Keycloak admin console — creating realms, clients, roles, redirect URIs, themes. These steps are untracked, unrepeatable, and unrecoverable. If the cluster is rebuilt from Terraform, all auth config is lost. 63 westside-basketball users, 3 mcd-tracker users — their realms, clients, and roles exist only in Keycloak's H2 database on a 2Gi PVC.
Scope
- Add
mrparkers/keycloakTerraform provider (~v5.x) topal-e-services - New
var.keycloak_realmstop-level variable — project-level auth boundaries (decoupled from var.services because multiple services share one realm) - New
var.keycloak_clientstop-level variable — per-app OIDC client configs (decoupled from var.services because some clients have no corresponding deployed service, e.g. mcd-tracker-ios) - Import existing state: 2 realms (westside-basketball, mcd-tracker), 4 clients, 5 custom roles, 1 protocol mapper
- Master realm explicitly excluded (admin realm, risk of lockout, static config)
- Zero-diff plan gate — no apply until
tofu planshows zero changes lifecycle { ignore_changes }on client secrets and default client scopes for import safety- Update service onboarding SOP
Deliverables
- Ticket 1 (5 pts): Add Keycloak provider + import existing state. Zero-diff plan verified. PR merged.
- Ticket 2 (1 pt): Update service onboarding SOP with keycloak_realms/keycloak_clients documentation.
Acceptance Criteria
tofu planon existing state shows zero changes (import complete)- All 63 westside-basketball users can still log in after apply
- Adding a new realm+client to tfvars and applying creates working auth
- Service onboarding SOP updated — auth is part of onboarding
- No manual Keycloak admin console actions required for new projects
Risk Surface
| Risk | Severity | Mitigation |
|---|---|---|
| Client secrets regenerated on apply | Critical | <code>lifecycle { ignore_changes = [client_secret] }</code> |
| Protocol mapper deleted if undeclared | Critical | Explicit <code>keycloak_openid_user_realm_role_protocol_mapper</code> resource |
| Custom roles deleted if undeclared | Critical | Declare all roles in <code>var.keycloak_realms.roles</code> |
| registrationEmailAsUsername reset | Critical | Per-realm field, no shared default |
| Client scopes reset to provider defaults | Medium | <code>lifecycle { ignore_changes }</code> on realm |
| Keycloak down blocks all pal-e-services plans | Medium | Same two-phase pattern as ArgoCD provider |
Testing Strategy
- Import gate:
tofu planshows zero changes = import succeeded - Login smoke: 63 westside users can still log in
- Drift detection: Change setting in admin console →
tofu plandetects it - New project: Add test realm+client →
tofu apply→ login works - Rollback: Remove test realm →
tofu apply→ realm gone
Related
plan-pal-e-platform— parent plan- Issue #142 — parent Forgejo issue
- PR #130 — Keycloak theme (triggered this discovery)
- PR #141 — Pillar secrets (Keycloak admin password now in pillar)
- Spec:
pal-e-platform/docs/superpowers/specs/2026-03-21-keycloak-terraform-onboarding-design.md