Two backlog trees are complete: `docs/project/backlog/` (75 files, every WP done) and `docs/project/refactor-backlog-setup/` (the arc before it). Move both under `docs/project/archive/` with `git mv`, so history stays intact through `git log --follow`. `SHOWCASE-ROADMAP.md` moves with them, because it points at the now-archived backlog README. Add `docs/project/archive/README.md`. It states that these trees are historical and names the two directories that are still live. Repoint every inbound reference named in RD-30's Files table: CLAUDE.md, the root README, both backend READMEs, `LetterHtml.cs`, `a11y.mdx`, the `document-feature` and `new-ssp` skills, and the readable-codebase PLAN, README, and RD-19 ticket. Fix two upward-relative links inside the moved WP files (WP-68, WP-69) that gained a directory level and would otherwise break. Repoint `.prettierignore`'s two agent-prompt exclusions to their new path, so prettier keeps leaving those files' exact wording alone. Mark RD-30 done and check off its acceptance criteria; flip its README row to done. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
92 lines
4.8 KiB
Markdown
92 lines
4.8 KiB
Markdown
# WP-55 — Real secrets + TLS for the OpenZaak harness
|
|
|
|
Status: done
|
|
Phase: 10 — OpenZaak production hardening
|
|
|
|
## Why
|
|
|
|
`backend/openzaak/docker-compose.openzaak.yml` is explicitly a throwaway dev/test harness:
|
|
`SECRET_KEY: wp-54-local-harness-not-for-prod`, `POSTGRES_HOST_AUTH_METHOD=trust` (no DB
|
|
password), `IS_HTTPS: 'no'`, `DISABLE_2FA: 'true'`. Before anything else in this phase can
|
|
be called "production," the instance needs real secrets, real DB auth, and TLS. The BFF
|
|
side is already fine — `ZgwOptions.cs` binds from `IConfiguration`, so this is a deploy-config
|
|
change, not application code.
|
|
|
|
## Read first
|
|
|
|
- [openzaak-integration.md](../reference/openzaak-integration.md)
|
|
- `backend/openzaak/README.md`
|
|
- [ADR-0005 — OpenZaak behind the BFF](../reference/architecture/0005-openzaak-behind-bff.md)
|
|
|
|
## Decisions (pre-made, don't relitigate)
|
|
|
|
- Secrets come from the deployment environment (env vars / secrets manager), never
|
|
checked into compose or appsettings.
|
|
- TLS termination happens at a reverse proxy/ingress in front of OpenZaak — OpenZaak
|
|
itself doesn't need built-in cert handling.
|
|
- The existing dev harness stays as-is for local iteration (WP-54's trimmed rig is
|
|
intentional and still valuable); this WP adds a production compose/override or an
|
|
env-driven parameterization of the same file, not a replacement of the dev rig.
|
|
|
|
## Files
|
|
|
|
- `backend/openzaak/docker-compose.openzaak.yml` (or a new `docker-compose.openzaak.prod.yml` override)
|
|
- `backend/openzaak/README.md`
|
|
- `backend/src/BigRegister.Api/appsettings*.json` / `Zgw/ZgwOptions.cs` (confirm only, likely no change)
|
|
|
|
## Steps
|
|
|
|
1. Parameterize `SECRET_KEY`, DB user/password, and the ZGW JWT secret via env vars;
|
|
remove hardcoded values from the committed file.
|
|
2. Switch `POSTGRES_HOST_AUTH_METHOD` from `trust` to password auth, password from env.
|
|
3. Set `IS_HTTPS: 'yes'`; document the required reverse-proxy/ingress TLS termination.
|
|
4. Update `backend/openzaak/README.md` with the required env vars and the TLS note.
|
|
5. Confirm the BFF's JWT secret already comes from config — no code change expected.
|
|
|
|
## Acceptance criteria
|
|
|
|
- [x] No secret value is hardcoded in any committed compose/config file.
|
|
- [x] The production compose fails fast (or docs state clearly) when secrets aren't
|
|
supplied — no silent fallback to a real-looking default.
|
|
- [x] README documents exactly which env vars must be set and how TLS is terminated.
|
|
|
|
## Deviation from the original plan
|
|
|
|
The WP's own "Files" section expected the secret to be parameterized directly inside
|
|
`docker-compose.openzaak.yml`'s environment or a straight env-var override. That covers
|
|
`SECRET_KEY`/DB password/`IS_HTTPS` fine (compose does key-based environment merging across
|
|
`-f` files even though the base file writes some blocks as YAML mappings and others as
|
|
anchors), but the ZGW client secret lives inside `setup_configuration/data.yaml`, a file
|
|
OpenZaak's own `setup_configuration` management command reads — compose has no mechanism to
|
|
interpolate env vars _inside_ a mounted file's contents. Solved by templating that one file
|
|
(`data.prod.yaml.template`, no secret) + a tiny host-side `render-prod-secrets.sh`
|
|
(`envsubst`, fail-fast via `${VAR:?...}`) that produces a gitignored `data.prod.yaml`, which
|
|
`docker-compose.openzaak.prod.yml` mounts over the container's `data.yaml` (bind-mounting a
|
|
single file inside an already bind-mounted read-only directory works fine in Docker/Podman —
|
|
verified via `docker compose config` with the override applied). No new dependency: `envsubst`
|
|
is part of `gettext`, already present on this machine.
|
|
|
|
Verified for real: `docker compose -f docker-compose.openzaak.yml -f
|
|
docker-compose.openzaak.prod.yml config` succeeds with all required env vars set and both
|
|
environment overrides (SECRET_KEY, DB password/auth method) present in the merged output;
|
|
fails with a clear `${VAR:?...}` error when any is missing. `render-prod-secrets.sh` itself
|
|
fails fast (tested) when `OPENZAAK_CLIENT_SECRET` etc. are unset, and its rendered
|
|
`data.prod.yaml` was inspected and matched the template with real values substituted.
|
|
`cd backend && dotnet test` (WP-54 harness untouched): 159/159 green. The dev harness
|
|
(`docker-compose.openzaak.yml` alone, `setup_configuration/data.yaml`) is untouched.
|
|
|
|
## Verification
|
|
|
|
`docker compose -f backend/openzaak/docker-compose.openzaak.yml config` with required env
|
|
vars set; `cd backend && dotnet test` (WP-54 harness tests unaffected); manual: the local
|
|
dev harness still works with its dev-only values documented as dev-only.
|
|
|
|
## Out of scope
|
|
|
|
Catalogus provisioning (WP-56), client scope narrowing (WP-57), notifications (WP-58).
|
|
|
|
## Risks
|
|
|
|
If TLS/secrets docs lag an actual deploy, someone could ship with dev defaults — mitigate
|
|
by making the prod compose fail without required env vars rather than silently defaulting.
|