ADR-401 item 6 · Audit: docs/security/security-consistency-audit-2026-06-09.md (F5)
Verified findings:
docker/docker-compose.yml:38,92-93 publishes Postgres 5432 and Garage 3900/3903 to the host (dev); the Garage admin API has no auth. Prod compose publishes nothing — correct, but the invariant is unguarded.
docker/nginx.prod.conf:30 — HSTS commented out. Neither nginx.prod.conf nor web/nginx.conf sets X-Frame-Options, X-Content-Type-Options, or CSP.
.env.example:84,100,205 — POSTGRES_PASSWORD=password plus two CHANGE_THIS_TO_A_RANDOM_SECRET_KEY placeholders. Nothing refuses to boot on placeholder secrets.
Acceptance criteria
ADR-401 item 6 · Audit:
docs/security/security-consistency-audit-2026-06-09.md(F5)Verified findings:
docker/docker-compose.yml:38,92-93publishes Postgres 5432 and Garage 3900/3903 to the host (dev); the Garage admin API has no auth. Prod compose publishes nothing — correct, but the invariant is unguarded.docker/nginx.prod.conf:30— HSTS commented out. Neithernginx.prod.confnorweb/nginx.confsetsX-Frame-Options,X-Content-Type-Options, or CSP..env.example:84,100,205—POSTGRES_PASSWORD=passwordplus twoCHANGE_THIS_TO_A_RANDOM_SECRET_KEYplaceholders. Nothing refuses to boot on placeholder secrets.Acceptance criteria
X-Frame-Options,X-Content-Type-Options, and a CSP to prod nginx (dev nginx: headers minus HSTS)nginx.prod.conf;.env.examplecontains a real-looking secret valueDEVELOPMENT_MODEwhenPOSTGRES_PASSWORD == "password"or any secret matchesCHANGE_THIS