Review: pal-e-deployments#135 — Cross-namespace admin-app-db-url surfacing (2026-04-25)
Scope
Ticket
pal-e-deployments#135 — surface the admin-app-db-url Secret produced in the basketball-api namespace (PR pal-e-platform#304) into the westside-admin namespace so the westside-admin pod (PR pal-e-deployments#134) can mount DATABASE_URL via secretKeyRef.Producer: pal-e-platform terraform
Consumer: westside-admin Deployment in
module/database creates kubernetes_secret_v1.admin_app_db_url in basketball-api.Consumer: westside-admin Deployment in
westside-admin namespace expects a Secret named westside-admin-secrets with key DATABASE_URL.Verdict
REQUEST_CHANGES — pre-decision required before dev dispatch.
The dev agent should not be asked to "decide during scoping" between four mechanisms (mittwald/kubernetes-replicator, External Secrets Operator, kustomize secretGenerator with duplicated SOPS payload, terraform-emitted second Secret). Each option has materially different blast radius and operational burden, and at least one (replicator / ESO) introduces a brand-new platform dependency that belongs to
pal-e-platform, not to a deployments-overlay PR.Verification
- Read PR
pal-e-deployments#134body + diff — consumer expects Secretwestside-admin-secretsin thewestside-adminns withDATABASE_URL. Currently the SOPS-encryptedwestside-admin-secrets.enc.yamlin the overlay carries a placeholderDATABASE_URL. - Read PR
pal-e-platform#304body + diff — producer createskubernetes_secret_v1.admin_app_db_urlinbasketball-apins. The PR body explicitly defers cross-namespace surfacing to "Track B (#133/#135)" and even names the two leading candidates ("kustomize secretGenerator referencing the same value or a small replicator"). - Issue
pal-e-deployments#135body could not be retrieved directly (noget_issueMCP tool, Tailscale-internal Forgejo not reachable from WebFetch). Review proceeds from the producer/consumer PR bodies, both of which are authoritative on the gap and the candidate set. - Repo precedent check:
bases/standard/kustomization.yamlhas no replicator hook. Nokubernetes-replicator/external-secretsHelm release exists in the visiblepal-e-platform/terraform/main.tfmodule wiring (storage, keycloak, database, ops, observability, etc.). No precedent for cross-namespace secret replication exists in the platform. This ticket is therefore introducing a new pattern, which raises the bar for pre-decision. - Story
story:admin-row-crudand archarch:k8s-deployare the correct labels (consistent with #134 / #304).
Findings
1. Four-option deferral is the wrong shape for a brand-new pattern
Per
feedback_review_before_dispatch and feedback_tickets_not_solution_specs, tickets carry user story + context + AC; dev agents pick implementation. That holds when there is precedent. Here there is none — picking between mittwald-replicator (cluster-wide controller, RBAC, ArgoCD app), ESO (CRDs, secret store, controller), kustomize secretGenerator + duplicated SOPS file, and a terraform-side second kubernetes_secret_v1 in the consumer ns is a platform architecture decision, not an implementation detail. The blast radii differ by orders of magnitude.2. Three of the four options shouldn't even be on the table for this ticket
- mittwald/kubernetes-replicator — adds a new cluster-wide controller. Belongs to
pal-e-platformas its own ticket + tofu module, not to a deployments-overlay PR. Out of scope. - External Secrets Operator — same: new CRDs, controller, SecretStore. Out of scope for a single overlay.
- kustomize secretGenerator with duplicated SOPS ciphertext — violates the spirit of
feedback_never_alter_prod_directly's "single source of truth" thinking. Two encrypted blobs to rotate, two failure modes. Hard to keep in sync with the terraform-emitted producer. - Terraform emits a second
kubernetes_secret_v1in thewestside-adminnamespace — adds ~10 lines tomodule/database, no new dependency, no new controller, idempotent, single source of truth (the Salt pillar value). Already inside the producer module that owns the password lifecycle.
Recommend pre-deciding option 4 (terraform mirrors the Secret into
westside-admin ns), and downscoping the ticket to either (a) a westside-admin-overlay-only fix that simply switches the env var secretKeyRef.name from westside-admin-secrets → admin-app-db-url and removes the placeholder DATABASE_URL from the SOPS file, or (b) a tiny pal-e-platform PR that adds the mirror Secret. The honest answer is the work largely belongs to pal-e-platform, not pal-e-deployments — that should be settled before dispatch.3. File Targets ambiguity
The ticket reportedly lists
services/westside-admin/overlays/prod/ + possibly services/_shared/. The actual repo layout is overlays/westside-admin/prod/ (no services/ prefix, no _shared/ dir). Per feedback_verify_repo_layout_before_ticketing, File Targets must match the live repo or the dev agent burns cycles. Fix before promoting to todo.4. AC must include rotation propagation E2E
Producer Job already rotates via Salt-pillar bump → terraform re-apply. The consumer must observe the new password without manual pod-roll, OR the AC must explicitly state "rotation requires
kubectl rollout restart of westside-admin Deployment." Either is fine; the unstated case is a foot-gun.5. Constraints that must be in the ticket
- No manual SOPS duplication of the encrypted DATABASE_URL.
- No coupling of
pal-e-platformmodule/database to westside-admin app internals (mirror Secret is fine; importing westside-admin config is not). - No new cluster-wide controllers added in this ticket — if a replicator is the right answer long-term, that is its own pal-e-platform ticket gated separately.
Recommendation
- Pre-decide the mechanism with Lucas/Ava before dispatch. Recommended: terraform mirrors the Secret into
westside-adminns from the samemodule/databaseresource. Lowest blast radius, no new dependency, single source of truth. - Move the actual implementation work onto pal-e-platform as a small follow-up PR to #304 (or amend #304 if not yet merged), since terraform owns the password and the producer Secret. Then
pal-e-deployments#135becomes a tiny overlay-only change: rewiredeployment-patch.yamlenvs to source DATABASE_URL from the mirrored Secret name, drop DATABASE_URL from the SOPS-encryptedwestside-admin-secrets.enc.yaml. - Fix File Targets to match real repo paths (
overlays/westside-admin/prod/deployment-patch.yaml,overlays/westside-admin/prod/westside-admin-secrets.enc.yaml). - Add explicit rotation-propagation step to AC.
- Add the three constraints in finding #5.
- Once the above are in the ticket body, ticket can move
backlog→todoperfeedback_todo_means_reviewed.