Skip to content

feat(seed): fail loudly when a Postgres DSN's user is not the server admin - #129

Merged
mrobinson2 merged 1 commit into
mainfrom
fix/seed-dsn-username-guard
Jul 21, 2026
Merged

feat(seed): fail loudly when a Postgres DSN's user is not the server admin#129
mrobinson2 merged 1 commit into
mainfrom
fix/seed-dsn-username-guard

Conversation

@mrobinson2

Copy link
Copy Markdown
Owner

Why

A DSN whose userinfo disagrees with the server's administrator_login fails at container start with:

FATAL: password authentication failed for user "vaultadmin"

The message names the password, so it points at the wrong secret. The real defect is the username.

This cost a six-day dev outage, 2026-07-15 → 07-21. The environment was rebuilt using the sanitized default dbadmin, while postgres-connection-string and paperclip-db-url still carried the pre-v1.4 vaultadmin inherited from the platform this repo was extracted from. ca-paperclip-dev and ca-honcho-dev were down the whole time; Log Analytics shows the failure starting 2026-07-15 09:50 and running continuously until the secrets were corrected.

Both DSNs are external secrets — operator-supplied, never generated by this script — so nothing in the repo could catch the drift.

What

seed-keyvault.sh now validates the userinfo of both DSN secrets against the expected administrator_login:

  • Source of truth: POSTGRES_ADMIN_USERNAME, else the Terraform variable's own default, parsed from variables.tf so the two cannot drift.
  • Checks values kept from a previous run, not only newly provided ones — a stale vault value nobody re-seeds is exactly how this happened.
  • Skips the __unset__ placeholder and any non-DSN value.
  • --postgres-admin-username NAME overrides; empty disables.

administrator_login is immutable (changing it forces Postgres replacement), so the DSN is always the side that must move — the error message says so.

Verification

New --self-check runs offline (no vault, no az, no network) and is wired into the CI scripts job beside the canary self-check:

  PASS  matching user passes
  PASS  mismatched user fails (the 2026-07-15 outage)
  PASS  plain postgresql scheme parses
  PASS  placeholder is skipped
  PASS  non-DSN value is skipped
  PASS  empty expectation disables the check
  PASS  password containing an @ does not confuse the parser

Also confirmed against the real failure shape — POSTGRES_CONNECTION_STRING=postgresql+psycopg://vaultadmin:… now aborts the run with an actionable message instead of seeding a DSN that breaks every consumer. shellcheck --severity=error clean.

🤖 Generated with Claude Code

…admin

A DSN whose userinfo disagrees with the server's administrator_login produces
FATAL "password authentication failed for user ..." at container start. That
message names the password, so it sends you auditing postgres-admin-password —
which is fine — while the actual defect is the username.

This cost a six-day dev outage (2026-07-15 → 07-21). The environment was
rebuilt with the sanitized default `dbadmin`, while postgres-connection-string
and paperclip-db-url still carried the pre-v1.4 `vaultadmin` inherited from the
platform this repo was extracted from. ca-paperclip-dev and ca-honcho-dev could
not reach Postgres the entire time.

Both DSNs are `external` secrets — operator-supplied, never generated here — so
nothing in the repo could have caught the drift. Now seed-keyvault.sh checks the
userinfo of postgres-connection-string and paperclip-db-url against the expected
administrator_login, taken from POSTGRES_ADMIN_USERNAME or, failing that, the
Terraform variable's own default so the two cannot drift apart. The check covers
values kept from a previous run, not just newly provided ones — a stale vault
value nobody re-seeds is precisely how this happened.

administrator_login is immutable (changing it forces server replacement), so the
DSN is always the side that has to move. `--postgres-admin-username` overrides
for a server that really does use a different login; an empty value disables it.

New `--self-check` runs the guard's cases offline (no vault, no az, no network),
wired into the CI scripts job next to the canary self-check.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mrobinson2
mrobinson2 merged commit b6dbc3e into main Jul 21, 2026
10 checks passed
@mrobinson2
mrobinson2 deleted the fix/seed-dsn-username-guard branch July 21, 2026 09:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant