87 lines
3.7 KiB
Markdown
87 lines
3.7 KiB
Markdown
---
|
|
phase: 16-ci-dependency-audit-and-security-checks
|
|
plan: "01"
|
|
subsystem: api-security
|
|
tags: [security, boot-guard, docker, tdd]
|
|
dependency_graph:
|
|
requires: []
|
|
provides: [assertNotDevBypassInProduction, bootGuards.ts, ENV NODE_ENV=production]
|
|
affects: [apps/api/src/index.ts, apps/api/Dockerfile]
|
|
tech_stack:
|
|
added: []
|
|
patterns: [TDD RED/GREEN, process.exit spy, boot-time guard]
|
|
key_files:
|
|
created:
|
|
- apps/api/src/lib/bootGuards.ts
|
|
- apps/api/tests/lib/bootGuards.test.ts
|
|
modified:
|
|
- apps/api/src/index.ts
|
|
- apps/api/Dockerfile
|
|
decisions:
|
|
- "D-07: ENV NODE_ENV=production baked into production Dockerfile stage — engages devBypass.ts hard guard at image build time, not at runtime"
|
|
- "D-08: assertNotDevBypassInProduction() placed as first statement in isMainModule() — boot-time refuse-to-boot guard converts silent misconfig into loud exit(1)"
|
|
- "Guard evaluated at call time (not import time) — allows unit tests to set env vars before calling without module cache manipulation"
|
|
metrics:
|
|
duration_seconds: 188
|
|
completed_date: "2026-06-13"
|
|
tasks_completed: 3
|
|
files_changed: 4
|
|
---
|
|
|
|
# Phase 16 Plan 01: Boot-time Dev-Bypass Guard Summary
|
|
|
|
**One-liner:** Boot-time refuse-to-boot guard (`assertNotDevBypassInProduction`) plus `ENV NODE_ENV=production` baked into the production Dockerfile stage, turning a silent auth-bypass misconfiguration into an immediate non-zero exit.
|
|
|
|
## What Was Built
|
|
|
|
### Task 1 — RED (test commit 8414e89)
|
|
Created `apps/api/tests/lib/bootGuards.test.ts` with 3 test cases:
|
|
1. `NODE_ENV=production` + `DEV_AUTH_BYPASS=true` → `process.exit(1)` is called (spy throws to make it observable)
|
|
2. `NODE_ENV=development` + `DEV_AUTH_BYPASS=true` → no `process.exit`
|
|
3. `NODE_ENV=production` + `DEV_AUTH_BYPASS` unset → no `process.exit`
|
|
|
|
Suite failed with `Cannot find module '../../src/lib/bootGuards.js'` — RED state confirmed.
|
|
|
|
### Task 2 — GREEN (feat commit c2ffd1c)
|
|
- Created `apps/api/src/lib/bootGuards.ts` exporting `assertNotDevBypassInProduction(): void`
|
|
- JSDoc documents D-08, call-time env evaluation, and required placement rule
|
|
- Added import to `apps/api/src/index.ts`
|
|
- Added call as the **first** statement in `isMainModule()` block (before VAPID config, workers, serve())
|
|
- 3/3 unit tests pass, `pnpm typecheck` green
|
|
|
|
### Task 3 — Dockerfile ENV (chore commit 5b4f32a)
|
|
- Added `ENV NODE_ENV=production` to the `production` stage in `apps/api/Dockerfile`
|
|
- Placed between `WORKDIR /app/apps/api` and `COPY --from=pwa-builder` (exactly as specified)
|
|
- Comment references D-07
|
|
- Exactly 1 occurrence; no other stage is affected
|
|
|
|
## Deviations from Plan
|
|
|
|
None — plan executed exactly as written.
|
|
|
|
## TDD Gate Compliance
|
|
|
|
- RED gate commit: `8414e89` — `test(16-01): add failing tests for boot-time dev-bypass guard`
|
|
- GREEN gate commit: `c2ffd1c` — `feat(16-01): add boot-time refuse-to-boot guard for dev-bypass in production`
|
|
- REFACTOR: not needed — implementation was clean on first pass
|
|
|
|
## Threat Surface Scan
|
|
|
|
No new network endpoints, auth paths, file access patterns, or schema changes introduced. The boot guard adds a startup-time process.exit — no new externally-reachable surface.
|
|
|
|
## Known Stubs
|
|
|
|
None.
|
|
|
|
## Self-Check: PASSED
|
|
|
|
- `apps/api/src/lib/bootGuards.ts` — FOUND
|
|
- `apps/api/tests/lib/bootGuards.test.ts` — FOUND
|
|
- `apps/api/src/index.ts` modified — assertNotDevBypassInProduction() called at line 115
|
|
- `apps/api/Dockerfile` — `ENV NODE_ENV=production` present in production stage
|
|
|
|
Commits:
|
|
- `8414e89` — test(16-01): add failing tests for boot-time dev-bypass guard
|
|
- `c2ffd1c` — feat(16-01): add boot-time refuse-to-boot guard for dev-bypass in production
|
|
- `5b4f32a` — chore(16-01): bake ENV NODE_ENV=production into production Dockerfile stage
|