---
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
