chore(dev): move RLS bootstrap to postgres initdb.d, drop password-drift reset #353

Merged
David merged 1 commit from chore/PMS-488-postgres-initdb-rls into main 2026-06-24 12:38:03 +02:00
Owner

What

Replaces the postgres service's 58-line entrypoint: override in compose.dev.yml with a first-init script (scripts/pg-init.sh) mounted at /docker-entrypoint-initdb.d/00-init.sh.

The override bundled three unrelated jobs: a password-drift reset, the PMS-285 RLS role split (mokosh_migrator BYPASSRLS + mokosh_app NOBYPASSRLS), and superuser-only bootstrap the migrations cannot do themselves (four untrusted CREATE EXTENSIONs + GRANT CREATE ON DATABASE to the migrator).

Changes

  • Drop the password-drift reset entirely. Reconciling a drifted password against a persistent dev volume is the wrong trade-off; to change a password, run just dev-clean and re-provision from a fresh volume.
  • Keep RLS + the extension/grant bootstrap, moved into scripts/pg-init.sh. The postgres image runs it once on an empty volume, as the superuser over the trusted local socket, before the TCP listener opens.
  • Because initdb.d runs before postgres accepts TCP, the server (connecting via postgres:5432) can no longer race role/extension creation - a window the backgrounded entrypoint had.
  • Since initdb.d only runs against an empty data dir, the roles never pre-exist, so the create-then-alter idempotency guards are dropped for plain CREATE, and ON_ERROR_STOP=1 aborts boot loudly on a real failure instead of the old || echo ...continuing.

Verification

  • docker compose -f compose.dev.yml config parses; no entrypoint: key remains; mount present.
  • sh -n scripts/pg-init.sh passes; just pre-commit green.
  • Manual (recommended on review): just dev-clean && just dev, then \du mokosh_migrator mokosh_app (migrator shows Bypass RLS, app does not), \dx lists uuid-ossp/pg_trgm/citext/pgcrypto, migrations apply with no permission-denied and CREATE SCHEMA mokosh_auth succeeds.

#PMS-488

## What Replaces the `postgres` service's 58-line `entrypoint:` override in `compose.dev.yml` with a first-init script (`scripts/pg-init.sh`) mounted at `/docker-entrypoint-initdb.d/00-init.sh`. The override bundled three unrelated jobs: a password-drift reset, the PMS-285 RLS role split (`mokosh_migrator` BYPASSRLS + `mokosh_app` NOBYPASSRLS), and superuser-only bootstrap the migrations cannot do themselves (four untrusted `CREATE EXTENSION`s + `GRANT CREATE ON DATABASE` to the migrator). ## Changes - Drop the password-drift reset entirely. Reconciling a drifted password against a persistent dev volume is the wrong trade-off; to change a password, run `just dev-clean` and re-provision from a fresh volume. - Keep RLS + the extension/grant bootstrap, moved into `scripts/pg-init.sh`. The postgres image runs it once on an empty volume, as the superuser over the trusted local socket, before the TCP listener opens. - Because initdb.d runs before postgres accepts TCP, the server (connecting via `postgres:5432`) can no longer race role/extension creation - a window the backgrounded entrypoint had. - Since initdb.d only runs against an empty data dir, the roles never pre-exist, so the create-then-alter idempotency guards are dropped for plain `CREATE`, and `ON_ERROR_STOP=1` aborts boot loudly on a real failure instead of the old `|| echo ...continuing`. ## Verification - `docker compose -f compose.dev.yml config` parses; no `entrypoint:` key remains; mount present. - `sh -n scripts/pg-init.sh` passes; `just pre-commit` green. - Manual (recommended on review): `just dev-clean && just dev`, then `\du mokosh_migrator mokosh_app` (migrator shows Bypass RLS, app does not), `\dx` lists uuid-ossp/pg_trgm/citext/pgcrypto, migrations apply with no permission-denied and `CREATE SCHEMA mokosh_auth` succeeds. #PMS-488
chore(dev): move RLS bootstrap to postgres initdb.d, drop password-drift reset
All checks were successful
E2E / Playwright against staging (pull_request) Successful in 54s
Check / fmt + clippy + build + tests (pull_request) Successful in 2m54s
Create release / Create release from merged PR (pull_request) Successful in 3s
Integration / integration tests (pull_request) Successful in 9m39s
c55ae98c6a
Replace the postgres service's 58-line entrypoint override with a first-init script mounted at /docker-entrypoint-initdb.d/00-init.sh. The override bundled three jobs: a password-drift reset, the PMS-285 RLS role split, and superuser-only extension/grant bootstrap that the unprivileged migrator cannot do during migrations.

Drop the password-drift reset entirely - reconciling a drifted password against a persistent dev volume is the wrong trade-off; changing a password now means `just dev-clean` to re-provision from a fresh volume.

Keep RLS and the extension bootstrap by moving them into scripts/pg-init.sh, which the postgres image runs once as the superuser over the trusted local socket, before the TCP listener opens. That ordering removes the race the backgrounded entrypoint had, where the server could connect via postgres:5432 before the roles existed. Because initdb.d only runs against an empty data dir the roles never pre-exist, so the create-then-alter idempotency guards are dropped for plain CREATE, and ON_ERROR_STOP=1 makes a real failure abort boot loudly instead of the old `|| echo ...continuing`.

#PMS-488

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
David merged commit 3713f71d3f into main 2026-06-24 12:38:03 +02:00
David deleted branch chore/PMS-488-postgres-initdb-rls 2026-06-24 12:38:03 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/mokosh-server!353
No description provided.