From f7425838428ef32af8cc654c717b5c3fce396efc Mon Sep 17 00:00:00 2001 From: Lucas Berger Date: Fri, 12 Jun 2026 21:41:02 -0400 Subject: [PATCH] =?UTF-8?q?docs:=20add=20backlog=20item=20999.17=20?= =?UTF-8?q?=E2=80=94=20define=20&=20enforce=20dev/prod=20image=20boundary?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .planning/ROADMAP.md | 23 +++++++++++++++++++ .../.gitkeep | 0 2 files changed, 23 insertions(+) create mode 100644 .planning/phases/null-999.17-define-enforce-the-dev-prod-boundary-in-shipped-images/.gitkeep diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 948e759..62fcfa0 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -513,3 +513,26 @@ Plans: Plans: - [ ] TBD (promote with /gsd-review-backlog when ready) + +### Phase 999.17: Define & enforce the dev/prod boundary in shipped images — dev-bypass and personal data must never reach production artifacts (BACKLOG) + +**Goal:** [Captured for future planning] The `DEV_AUTH_BYPASS` concept (and any other dev-only affordance) must be provably confined to local dev — never to production, and never baked into the Docker images CI builds and publishes. Today the guard is runtime-only (`NODE_ENV !== 'production' && DEV_AUTH_BYPASS === 'true'` in `apps/api/src/auth/devBypass.ts`), which is correct but relies on env discipline at deploy time. There is no enforced, documented line between the dev image and the shipped image. Equally important: **none of the operator's data or family-specific context** (seeded dev DB rows, real Fastmail emails, app passwords, encryption keys, OIDC secrets, the dev `DEV_USER`, local `.env` values) may be embedded in published images. + +**Options / decisions to make when picking this up:** + +- **Define the boundary explicitly:** document what "dev image" vs "shipped/prod image" means — which env vars, build args, seed data, and code paths are dev-only — and make it a referenceable convention (e.g. a `docs/dev-vs-prod.md` + a note in CLAUDE.md / deployment docs). +- **Build-time enforcement, not just runtime:** consider compiling out or hard-failing on dev-bypass in prod builds (e.g. build arg / env assertion at image build that aborts if `DEV_AUTH_BYPASS` is set, or a startup guard that refuses to boot a `production` image with bypass enabled). Today the only guard is the runtime conditional — a defense-in-depth build/boot check is missing. +- **No data/secrets in images:** audit the Dockerfile(s) and CI publish job (Phase 8 / `publish.yml`) to confirm `.env`, dev seed SQL, local DB dumps, encryption keys, and family-specific fixtures are `.dockerignore`d and never `COPY`'d. Verify the published image is data-free and seed-free. +- **CI assertion:** add a check in the publish pipeline that fails the build if a dev-bypass code path is active, a forbidden env/secret is present, or personal data is staged into the image context. +- **Dev-only seed isolation:** the host-side dev stack seeds `DEV_USER` (id 1) + sample calendar/list data; ensure that seed path is unreachable from the production image and compose. + +**Boundary:** This is about the dev↔prod artifact boundary and image hygiene, not about removing dev-bypass (it is needed for local verification and CI harness runs per Phases 7/8). The runtime guard stays; this adds definition, documentation, build/boot enforcement, and a CI safety net. + +**Context:** Raised 2026-06-12 during Phase 10 (Admin Role & Settings) discussion — `DEV_USER`/dev-bypass surfaced as the head of the admin chain (first-login-wins bootstrap), prompting the concern that the dev/prod line is under-defined and that no operator/family data should ever ship in CI-built images. Tags: ci, docker, security, dev-bypass, secrets, data-hygiene, deployment. + +**Requirements:** TBD +**Plans:** 0 plans + +Plans: + +- [ ] TBD (promote with /gsd-review-backlog when ready) diff --git a/.planning/phases/null-999.17-define-enforce-the-dev-prod-boundary-in-shipped-images/.gitkeep b/.planning/phases/null-999.17-define-enforce-the-dev-prod-boundary-in-shipped-images/.gitkeep new file mode 100644 index 0000000..e69de29