Deploy Keycloak IdP to cluster (Phase 5a) #32
Labels
No labels
domain:backend
domain:devops
domain:frontend
status:approved
status:in-progress
status:needs-fix
status:qa
type:bug
type:devops
type:feature
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
forgejo_admin/pal-e-platform#32
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Lineage
plan-2026-03-08-tryout-prep→ Phase 5 (Auth system — Keycloak IdP) → Phase 5aRepo
forgejo_admin/pal-e-platformUser Story
As a platform operator
I want Keycloak deployed as a self-hosted identity provider on the cluster
So that all Pal-E apps can authenticate users via OIDC/OAuth2 without rolling their own auth
Context
Westside Basketball needs player/parent/coach auth for club operations (monthly payments, team rosters, player profiles). Rather than building auth into basketball-api, we're deploying Keycloak as a platform service — the same way Forgejo, Harbor, Woodpecker, and Ollama are deployed.
Decision: Keycloak was chosen over roll-your-own, magic links, or managed SaaS because it's enterprise-grade, self-hosted, OIDC standard, and reusable across all Pal-E apps. "Do it right, don't do it twice."
For Phase 5a, use the Bitnami Keycloak Helm chart with built-in PostgreSQL (not CNPG — migration to CNPG is a future concern). This matches how Harbor uses its internal database.
File Targets
Files to modify:
terraform/main.tf— addkubernetes_namespace_v1.keycloak,helm_release.keycloak,kubernetes_ingress_v1.keycloak_funnelterraform/variables.tf— addkeycloak_admin_passwordvariable (sensitive, min 8 chars)terraform/outputs.tf— optionally output keycloak URLFiles NOT to touch:
Acceptance Criteria
keycloakcreatedkeycloak.tail5b443a.ts.netvar.keycloak_admin_password(sensitive,type = "string")local-pathstorage classdepends_onreferences Tailscale operator and ACL (same as all other funnels)tofu fmtandtofu validatepassTest Expectations
tofu planshows 3 new resources (namespace, helm_release, ingress)tofu validatepassestofu fmt -checkpassescd terraform && tofu fmt -check && tofu validateConstraints
main.tf(namespace → helm_release → ingress with depends_on)set_sensitivefor admin password withtype = "string"(notset)oci://registry-1.docker.io/bitnamicharts/keycloakfor the chart reference (Bitnami)https://keycloak.${var.tailscale_domain}/postgresql.enabled = truein chart values (do NOT set up CNPG)cpu = "100m", memory = "512Mi", limitsmemory = "1Gi"(Keycloak needs more memory than most services)cpu = "50m", memory = "128Mi", limitsmemory = "512Mi"storageClass = "local-path", size = "2Gi" for Keycloak, "2Gi" for PostgreSQLtailscale.com/funnel = "true"), TLS host = "keycloak"Checklist
Closes #Ntofu planoutput included in PR descriptiontofu fmtandtofu validatepassRelated
project-westside-basketball— first consumer of Keycloak authplan-pal-e-platform— Keycloak may become a permanent platform service