Review: Add Ingress/TLS + wire Keycloak env vars for production deploy
Verdict: NEEDS_REFINEMENT
Template Completeness
- [x] Type — Feature
- [ ] Lineage — MISSING
- [x] Repo — prediction-assistant
- [x] User Story — present
- [x] Context — present
- [x] File Targets — 7 targets (3 new, 4 existing)
- [x] Feature Flag — None (acceptable for infra work)
- [ ] Acceptance Criteria — MISSING (only Test Expectations present)
- [x] Test Expectations — present (3 items)
- [x] Constraints — present
- [x] Checklist — present
- [x] Related — present (Blocks #93, Sprint 12)
Traceability
- [x] story:platform-setup label — Platform Setup
- [x] story note verified — found in project-prediction-assistant user-stories section
- [x] arch:k8s-deploy label — k8s deployment component
- [ ] arch note MISSING — [SCOPE] Create architecture note arch-k8s-deploy for component k8s-deploy
- [x] arch:keycloak label — Keycloak auth component
- [ ] arch note MISSING — [SCOPE] Create architecture note arch-keycloak for component keycloak
- [x] Forgejo issue — ldraney/prediction-assistant#105, open
File Targets
- [x] k8s/overlays/prod/ingress.yaml (new) — verified: does not exist, correctly marked as new
- [x] k8s/overlays/prod/cluster-issuer.yaml (new) — verified: does not exist, correctly marked as new
- [ ] k8s/overlays/prod/redirect-middleware.yaml (new) — ISSUE: resource type unclear. "Middleware" is a Traefik CRD concept. Issue does not specify which ingress controller is in use or what k8s resource kind this file should contain
- [x] k8s/overlays/prod/kustomization.yaml — verified: exists, currently has image pin, patches, and labels. New resources must be added to the resources list
- [x] k8s/base/configmap.yaml — verified: exists with RAILS_ENV, RAILS_LOG_TO_STDOUT, RAILS_SERVE_STATIC_FILES, RAILS_MAX_THREADS, PORT. No Keycloak vars present (confirms the gap)
- [x] k8s/base/deployment.yaml — verified: exists with envFrom configMapRef and secret env vars (DATABASE_URL, SECRET_KEY_BASE, KALSHI_*). No Keycloak env vars present
- [x] k8s/base/worker-deployment.yaml — verified: exists with same env pattern as deployment.yaml. No Keycloak env vars present
Repo Placement
OK — issue filed on ldraney/prediction-assistant. All 7 file targets are within the prediction-assistant repo k8s/ directory.
Dependencies
- Documented: Blocks #93 "Verify prediction-assistant.com is live" (todo column, sprint:12)
- Undocumented: Depends on pal-e-services#173 "tofu apply — provision prediction-assistant infra" (board item 1772, todo column, sprint:12). The Keycloak env vars reference secrets (KEYCLOAK_CLIENT_SECRET at minimum) that must be provisioned by Terraform before pods can start with correct auth. This dependency is not documented in the issue.
- Related: pal-e-services#171 "Add Keycloak realm + OIDC client" (validation column, sprint:11) — the Keycloak realm and OIDC client must exist before these env vars are meaningful.
Acceptance Criteria
No ### Acceptance Criteria section exists. The Test Expectations section provides partial coverage but is insufficient:
- "kustomize build k8s/overlays/prod/ succeeds" — verifiable by agent
- "Ingress routes prediction-assistant.com to service" — only verifiable post-deploy, not by agent
- "Keycloak env vars present in pod specs" — verifiable via kustomize build output, but does not specify WHICH vars
Missing criteria:
- Which specific Keycloak env vars must appear: KEYCLOAK_CLIENT_ID, KEYCLOAK_CLIENT_SECRET, KEYCLOAK_URL, KEYCLOAK_REALM (per config/initializers/omniauth.rb)
- KEYCLOAK_CLIENT_SECRET must come from a Secret (not ConfigMap) — security constraint not stated
- TLS certificate provisioning verified (ClusterIssuer references valid issuer)
- HTTP-to-HTTPS redirect behavior
Blast Radius
- ConfigMap changes via envFrom propagate to both web and worker deployments — both are listed as file targets, so this is covered
- Adding Keycloak env vars to base/ affects both prod and dev overlays. If dev should use different Keycloak settings (different realm URL, different client), the issue should specify overlay-level overrides
- No sibling services in this repo to check for similar patterns
Decomposition Assessment
7 file targets in 1 repo, 3 test expectations, estimated agent work ~3-5 minutes. No decomposition needed.
Recommendation
[BODY]Add ### Acceptance Criteria section with verifiable conditions: "kustomize build output contains KEYCLOAK_CLIENT_ID, KEYCLOAK_CLIENT_SECRET, KEYCLOAK_URL, KEYCLOAK_REALM in pod specs", "KEYCLOAK_CLIENT_SECRET sourced from Secret not ConfigMap", "Ingress host is prediction-assistant.com", "TLS secretName references cert-manager Certificate"[BODY]Add ### Lineage section (e.g., "Standalone — discovered during deployment audit")[BODY]Specify which Keycloak env vars (KEYCLOAK_CLIENT_ID, KEYCLOAK_CLIENT_SECRET, KEYCLOAK_URL, KEYCLOAK_REALM per config/initializers/omniauth.rb) and whether each goes in ConfigMap or Secret (KEYCLOAK_CLIENT_SECRET MUST be a Secret)[BODY]Clarify what k8s resource type redirect-middleware.yaml represents (Traefik Middleware CRD? Ingress annotation? Something else?) and which ingress controller is in use[BODY]Document dependency on tofu apply (pal-e-services#173) for k8s secrets provisioning[SCOPE]Create architecture note arch-k8s-deploy for component k8s-deploy[SCOPE]Create architecture note arch-keycloak for component keycloak