feat(keycloak): prod techgarden realm + WS-05 theme, realm withheld (WS-02 H3) - #280
Merged
Conversation
…WS-02 H3) Adds everything the prod techgarden realm needs EXCEPT the one line that turns it on. This is the only change in WS-02 touching a live shared IdP, so it is isolated: a broken hausparty or kian-coffee login is attributable to this PR instantly rather than bisected out of a large merge. THE GO SWITCH: base/realms/techgarden-realm.json exists but is deliberately absent from configMapGenerator.files. config-cli imports /config/*.json from that ConfigMap, so an unlisted file is never seen by Keycloak and https://sso.techgarden.gg/realms/techgarden keeps returning 404 — the pass condition for this phase, not a failure. The flip is that one line. Realm — DERIVED from the dev seed, not copied. Verified deltas vs dev, and nothing else drifted: 1. apex hostnames only — https://techgarden.gg/* and /oauth2/callback (ADR-0006: products are routes, not subdomains). No dev.techgarden.gg anywhere. 2. fromDisplayName "TechGarden", not "TechGarden (dev)" — a verbatim copy would put the wrong sender name on every production email. 3. registrationAllowed: false, declared not defaulted (ADR-0052). 4. all FOUR action-token lifespans carried (reset-credentials 1800, verify-email 43200, admin 259200, base 300). The base value alone would expire forgot-password links in 5 minutes — the bug dev shipped and fixed in #276. 5. THE FOUR DEV PERSONAS DROPPED. dev/power/casual/fresh are a dev fixture with out-of-band passwords; this IdP also fronts hausparty and kian.coffee. Prod gets the owner only. Also carried from WS-03: confidential client techgarden-gateway, revokeRefreshToken: true, 30-day idle / 60-day cap. And the `ai` realm role from #278, which landed after the brief was written (owner-only, held by kian). Theme — 17 files (11 login, 6 email), byte-identical to dev, mounted via spec.unsupported.podTemplate at /opt/keycloak/themes/techgarden/. TWO ConfigMaps, not one: configMapGenerator keys off each file's base name and ConfigMap keys cannot contain "/", so theme.properties and messages_en.properties collide across login/ and email/. theme-revision starts at "1" — prod's counter is independent of dev's "2" and the two must never be synced up. Nothing references the theme until the realm is enabled. Substitution wiring — the sharpest edge. IMPORT_VARSUBSTITUTION_ENABLED is true over /config/*.json, so a seed referencing an unwired variable fails substitution for EVERY realm file in the batch at once. KC_CLIENT_TECHGARDEN_GATEWAY_SECRET and KC_SMTP_PASSWORD are therefore wired NOW, alongside the two new ExternalSecret keys, so the flip cannot take hausparty and kian-coffee down with it. Resend: prod SHARES the dev sender. The free tier allows one verified domain and there is exactly one `resend` entry in the BWS org — so both environments share the 3,000/month cap and ADR-0052's fail-closed-on-429 becomes a shared property. Claude-Session: https://claude.ai/code/session_015tcbrNifvkc8ryk4g2M7XK
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
WS-02 PR2 of 3 — identity. Merge only after #279.
This is the only change in WS-02 that touches a live shared IdP (it also fronts hausparty and kian.coffee), which is exactly why it is isolated into its own PR — a broken login is attributable to this diff instantly rather than bisected out of a large merge.
🔒 The go switch stays OFF
base/realms/techgarden-realm.jsonexists in this repo but is deliberately absent fromconfigMapGenerator.files.config-cli imports
/config/*.jsonfrom that ConfigMap, so an unlisted file is never seen by Keycloak. While it stays unlisted,https://sso.techgarden.gg/realms/techgardenkeeps returning 404 — the pass condition for this phase, not a failure.The flip is exactly one line:
in
kubernetes/clusters/1276-prod/keycloak/keycloak/kustomization.yaml. Nothing else in that directory needs to change — both substitution vars and both secret keys ship here.Realm — derived from dev, not copied
Diffed field-by-field against the dev seed. Only these deltas exist; nothing else drifted.
https://techgarden.gg/*,/oauth2/callbackdev.techgarden.ggsurvives anywhere.fromDisplayName: "TechGarden"(dev:"TechGarden (dev)")registrationAllowed: false, declared not defaulteddev/power/casual/freshare a dev fixture with out-of-band passwords. Copying them seeds four test accounts into the IdP that also fronts hausparty and kian.coffee. Prod gets the owner only.Carried over from WS-03: confidential client
techgarden-gateway,revokeRefreshToken: true, dev-settled 30-day idle / 60-day cap.Theme — 17 files, byte-identical to dev
11 login + 6 email, verified
diff -rclean against the dev copy. Mounted viaspec.unsupported.podTemplateat/opt/keycloak/themes/techgarden/, safe because the 26.6.3 image ships only aREADME.mdthere (the real themes live inside a jar, soparent=basekeeps resolving).Two ConfigMaps, not one — one cannot work.
configMapGeneratorkeys off each file's base name and ConfigMap keys cannot contain/, sotheme.propertiesandmessages_en.propertiescollide acrosslogin/andemail/.techgarden.gg/theme-revision: "1". Prod's counter is independent — dev is on2. WithdisableNameSuffixHash: truethe ConfigMap names never change, so the operator never notices new bytes; without this annotation the pod silently keeps serving the old theme. Bump it on every change underbase/themes/.Nothing references the theme until the realm is enabled, so it is inert for the three live realms.
Substitution wiring — the sharpest edge
IMPORT_VARSUBSTITUTION_ENABLED=trueoverIMPORT_FILES_LOCATIONS=/config/*.jsonmeans substitution runs across the whole batch: a seed referencing an unwired variable fails substitution for every realm file at once, not just its own.So
KC_CLIENT_TECHGARDEN_GATEWAY_SECRETandKC_SMTP_PASSWORDare wired now (prod's Job goes 4 → 6KC_*vars), together with the two newkeycloak-realm-secretskeys. The flip therefore cannot take hausparty and kian.coffee down with it.📧 Resend: prod SHARES the dev sender
There is exactly one
resendentry in the whole BWS org (generically named, notdev-), and the free tier allows exactly one verified sending domain. No prod SMTP secret was ever created. So prod reads the same BWS entry dev reads — the H4 parity pattern, one entry read twice.Consequence: dev and prod share the 3,000/month · 100/day allowance, which makes ADR-0052's fail-closed-on-429 a property the two environments share — dev traffic can exhaust prod's quota. Splitting them needs a paid plan and a second verified domain.
Validation
kustomize buildgreen. Asserted on the rendered output:techgarden-realm.jsonabsent fromkeycloak-realm-config(keys are exactly the three live realms)theme-revision == "1"KC_*vars resolve to keys that exist on the ExternalSecretKC_*vars still wiredtechgarden.ggHTTPRoute; bothhttproute*.yamlbyte-untouched (the onlyeg-publicroute is Keycloak's own pre-existingsso.techgarden.gg)Merging rolls the Keycloak StatefulSet (podTemplate change), 2 instances, rolling. Done-condition: hausparty and kian.coffee logins still work after the roll — I verify both immediately after merge.
🤖 Generated with Claude Code
https://claude.ai/code/session_015tcbrNifvkc8ryk4g2M7XK