Review: Terraform Keycloak OIDC client westside-admin
Verdict: NEEDS_REFINEMENT
Board item #1096 — forgejo_admin/pal-e-platform#301 — Terraform: Keycloak OIDC client westside-admin. Reviewed 2026-04-25.
Critical Finding
The ticket's core premise is incorrect. It instructs the dev agent to "find the westside-app client definition and clone its structure." No such terraform-managed client exists. The Keycloak terraform module at
terraform/modules/keycloak/main.tf deploys only the Keycloak server (namespace, secret, PVC, deployment, service, theme configmap). The keycloak terraform provider is not configured in terraform/providers.tf, no keycloak_realm resource exists, and no keycloak_openid_client resource exists. The westside-basketball realm and existing westside-app client are managed manually via the Keycloak admin console, not by terraform.This means the ticket as written cannot be executed. The dev agent will either (a) get blocked, or (b) bootstrap the keycloak provider + realm import + client resource themselves, which is materially larger scope than "add a client resource."
Template Completeness
- [x] Type — Task
- [x] Lineage
- [x] Repo
- [x] User Story
- [x] Context
- [x] Scope
- [x] Acceptance Criteria
- [x] Test Expectations
- [x] Constraints
- [x] Checklist
- [x] Related
Traceability
- [x] story:admin-row-crud label — Admin Row CRUD
- [x] story note verified —
story-westside-admin-admin-row-crudexists; user-stories section onproject-westside-adminexists - [x] arch:keycloak label
- [ ] arch note MISSING — search for
arch-keycloakreturned no results. Existing arch notes for the project arearch-domain-westside-admin,arch-dataflow-westside-admin,arch-deployment-westside-admin. No keycloak-component arch note exists in pal-e-docs. [SCOPE] Create architecture notearch-keycloakdocumenting the Keycloak component (realm, clients, terraform vs manual management boundary). - [x] Forgejo issue — #301, open
File Targets
Ticket references
~/pal-e-platform/keycloak.tf "or equivalent." Verified state of repo:- [ ]
~/pal-e-platform/keycloak.tf— DOES NOT EXIST. Keycloak terraform lives atterraform/modules/keycloak/main.tf. - [ ] "westside-app client definition" — DOES NOT EXIST in terraform. Grepped
terraform/forkeycloak_openid_client,keycloak_realm,provider "keycloak",mrparkers,keycloak/keycloak— zero matches. The realm and any existing clients are unmanaged by IaC. - [x]
terraform/modules/keycloak/main.tf— exists, deploys Keycloak server only. - [x]
terraform/providers.tf— exists; declares kubernetes, helm, tailscale, minio. No keycloak provider.
Repo Placement
Repo (
forgejo_admin/pal-e-platform) is correct for terraform-managed Keycloak resources. No mismatch.Dependencies
Implicit prerequisite NOT declared in ticket:
- Configuring the
keycloakterraform provider inproviders.tf(with admin credentials sourced from existingkeycloak-adminsecret or a new tfvar). - Importing or declaring the
westside-basketballrealm as a terraform resource (or marking it as data-only via adata "keycloak_realm"lookup so the new client can reference it without taking over realm management). - Decision needed: does this ticket also adopt the existing
westside-appclient into terraform (import), or leave it manual and only add the newwestside-adminclient? The ticket assumes the latter is trivially possible by "cloning"; in reality there is no terraform pattern to clone.
Downstream board items relying on this:
- #1087 (westside-admin SvelteKit scaffold) — needs this client to wire OIDC env vars, but does not block scaffolding.
- #1088 (deployment) and #1095 (pal-e-deployments overlay) — consume the client_id and (if confidential) client_secret from k8s secret. Currently no defined export path.
Acceptance Criteria
ACs are testable as written, but several depend on the unstated bootstrap work (provider config, realm reference). The "If confidential: secret available in pal-e-platform secret store" criterion has no defined target — there is no existing secret-export pattern in this module to follow. Needs an explicit decision.
Blast Radius
If the dev agent attempts to manage the
westside-basketball realm via a fresh keycloak_realm resource without import, terraform will try to create a realm that already exists, returning a 409 from Keycloak — or worse, if force-imported wrong, it will overwrite realm settings (login theme, password policies, registered users not stored in terraform) and could break westside-app SSO for Lucas and Marcus. This is a real outage risk. Realm must be imported via tofu import or referenced as a data source — not declared fresh.Decomposition Assessment
If the bootstrap work (provider config + realm import + client resource + secret export) is included, this exceeds the 5-minute single-agent window: 3+ file targets in 1 repo, 7 ACs, plus a real outage risk requiring careful import sequencing. NEEDS DECOMPOSITION after the SCOPE questions are answered. Suggested split:
- Add
keycloakterraform provider + import (or data lookup) thewestside-basketballrealm. PR showstofu planwith zero diff after import. - Add
keycloak_openid_clientresource forwestside-adminwith the spec'd settings. - If confidential: add secret export to k8s for the deployment overlay to consume.
Recommendation
[SCOPE]Lucas/Ava: confirm strategy — bootstrap keycloak terraform provider in this ticket, or first land a separate "adopt Keycloak under IaC" ticket and rebase this on top? Premise of "clone existing client pattern" is false; pick the replacement plan.[SCOPE]Decide: public+PKCE or confidential client? Ticket leaves it open, but the answer drives whether secret-export work is in scope.[SCOPE]Create architecture notearch-keycloakdocumenting the component and the IaC boundary (what's terraform-managed vs admin-console-managed).[BODY]Fix file path reference:~/pal-e-platform/keycloak.tf→terraform/modules/keycloak/main.tf.[BODY]Replace "find the westside-app client definition and clone" with the actual bootstrap path chosen in the SCOPE decision above.[BODY]Add explicit AC for realm management: "westside-basketballrealm referenced viadata "keycloak_realm"lookup OR imported viatofu import, with no realm-level drift intofu plan."[DECOMPOSE]After SCOPE answered: split into 2-3 sub-tickets per Decomposition Assessment. Route toskill-decompose-ticket.