Review: Codify Keycloak public ingress IaC

review-1482-2026-06-17-r2 Review

review needs-refinement

Verdict: NEEDS_REFINEMENT

Re-review of board item #1482. Previous review: review-1482-2026-06-17. The #453 dependency blocker has been resolved (issue closed, reference removed from body). Three [SCOPE] items remain from the first review.

Template Completeness

  • [x] Type -- Feature
  • [x] Lineage -- present, references godaddy-tofu#36 and pal-e-services#121
  • [x] Repo -- ldraney/pal-e-platform
  • [x] User Story -- present, well-written
  • [x] Context -- thorough, explains experimental verification and manual patches
  • [x] File Targets -- 3 targets specified with line numbers
  • [x] Feature Flag -- "None" (appropriate for IaC change)
  • [x] Acceptance Criteria -- 5 criteria
  • [x] Test Expectations -- 2 items
  • [x] Constraints -- 3 constraints documented
  • [x] Checklist -- present
  • [x] Related -- 2 references (godaddy-tofu#36, pal-e-services#121)
All required sections for the Feature template are present and complete.

Traceability

  • [x] story:custom-domains label -- present on board item
  • [ ] story note MISSING -- [SCOPE] The user-stories table on project-pal-e-platform does not contain a story:custom-domains entry. Current entries: superuser-deploy, superuser-observe, superuser-recover, superuser-onboard-service, superuser-remote-access, superuser-sso, superuser-unified-ui, superuser-docs-frontend. Create user story entry on project-pal-e-platform user-stories section.
  • [x] arch:keycloak label -- present on board item
  • [ ] arch note MISSING -- [SCOPE] No arch-keycloak note found in pal-e-docs. Create architecture note arch-keycloak for component keycloak.
  • [x] arch:edge-proxy label -- present on board item
  • [ ] arch note MISSING -- [SCOPE] No arch-edge-proxy note found in pal-e-docs. Create architecture note arch-edge-proxy for component edge-proxy.
  • [x] Forgejo issue -- ldraney/pal-e-platform#454, open

File Targets

  • [x] terraform/dns.tf -- verified: file exists with existing A records for palinks.app and landscaping-assistant.app using module.hetzner_edge.server_ipv4. New auth record follows established pattern.
  • [x] terraform/modules/keycloak/main.tf -- verified: KC_HOSTNAME env block is at lines 132-135 exactly as stated. Block sets KC_HOSTNAME = keycloak.${var.tailscale_domain}. File is 291 lines total.
  • [x] salt/pillar/caddy.sls -- verified: file exists with existing site entries for palinks and landscaping. New auth entry follows established YAML structure (domain, proxy_target, www_redirect).

Repo Placement

Correct. All three file targets are in ldraney/pal-e-platform and the issue is filed there. pal-e-services#121 is appropriately tracked as a separate companion issue for the KEYCLOAK_URL secret update.

Dependencies

  • pal-e-platform#453 -- RESOLVED. Issue is now closed (state: "closed", title: "CLOSED: Add Woodpecker CI pipeline..."). The dependency reference has been removed from the issue body. The context section correctly states "The tofu CI pipeline (.woodpecker/terraform.yaml) is already in place." No longer blocking.
  • Board item #1483 ("Update KEYCLOAK_URL for landscaping-assistant") shares story:custom-domains and arch:keycloak labels, currently in backlog. This is downstream -- should be sequenced after #1482. Not a blocker.
  • pal-e-services#121 -- companion issue for KEYCLOAK_URL update. Open. Referenced in Lineage as "Companion to." Not blocking.
  • godaddy-tofu#36 -- documentation, referenced as related (not blocking).

Acceptance Criteria

5 acceptance criteria, all verifiable by an agent:
  • tofu plan output -- verifiable via CLI
  • tofu apply success -- verifiable via CLI
  • salt state.apply caddy on edge-proxy -- verifiable via SSH (post-merge manual step per Constraints)
  • OIDC discovery on auth.palinks.app -- verifiable via curl
  • OIDC discovery on keycloak.tail5b443a.ts.net -- verifiable via curl (regression check)
Criteria are well-specified and testable.

Blast Radius

  • KC_HOSTNAME is referenced only once in the codebase (terraform/modules/keycloak/main.tf:133). Removal is safe from a code standpoint.
  • Removing KC_HOSTNAME causes Keycloak to derive its hostname from the request's Host header, enabling multi-domain access. Services using keycloak.tail5b443a.ts.net as issuer will continue working (AC #5 verifies this).
  • No existing references to auth.palinks.app in pal-e-platform, confirming net-new configuration.
  • Downstream KEYCLOAK_URL update tracked separately by pal-e-services#121 / board #1483.

Decomposition Assessment

3 file targets in 1 repo. 5 acceptance criteria. Estimated agent work: ~3-4 minutes (straightforward IaC additions following existing patterns). No decomposition needed.

Recommendations

  • [SCOPE] Create story:custom-domains user story entry on project-pal-e-platform user-stories section.
  • [SCOPE] Create architecture note arch-keycloak for component keycloak.
  • [SCOPE] Create architecture note arch-edge-proxy for component edge-proxy.
The #453 dependency blocker from the first review is fully resolved. The three remaining items are all [SCOPE] -- they require human decision to create backing traceability notes. The issue body itself is complete and ready for implementation once the backing notes exist.