docs(16-04): complete gitleaks+dockerignore plan — add SUMMARY, advance state

This commit is contained in:
Lucas Berger
2026-06-13 08:16:49 -04:00
parent bc83495946
commit 946dafe5fb
3 changed files with 118 additions and 7 deletions
+3 -3
View File
@@ -331,7 +331,7 @@ Plans:
- [x] 16-01-PLAN.md — Image-hygiene runtime: bake NODE_ENV=production + boot-time refuse-to-boot guard (IMG-01)
- [x] 16-02-PLAN.md — pnpm audit gate + waiver allowlist + advisory-only tiered outdated report (DEP-01, DEP-02)
- [x] 16-03-PLAN.md — Fold eslint-plugin-security into the lint gate as blocking errors + triage (SEC-02)
- [ ] 16-04-PLAN.md — gitleaks config + full-history baseline + .dockerignore (SEC-01, IMG-02)
- [x] 16-04-PLAN.md — gitleaks config + full-history baseline + .dockerignore (SEC-01, IMG-02)
**Wave 2** *(blocked on Wave 1 completion)*
@@ -359,7 +359,7 @@ Plans:
| 13. Real Lint Gate (ESLint) | v1.1 | 3/3 | Complete | 2026-06-12 |
| 14. Desktop E2E Coverage | v1.1 | 1/1 | Complete | 2026-06-12 |
| 15. Doc-Only CI Skip + MD Lint | v1.1 | 3/3 | Complete | 2026-06-12 |
| 16. CI Dep Audit, Sec & Img Hyg | v1.1 | 3/6 | In Progress| |
| 16. CI Dep Audit, Sec & Img Hyg | v1.1 | 4/6 | In Progress| |
## Backlog
@@ -367,7 +367,7 @@ Plans:
**Goal:** [Captured for future planning] Abstract the calendar backend behind a provider interface so Fastmail/CalDAV is one implementation among potentially many. Shipping with a single provider is fine, but the broker, sync, and event-expansion layers should be structured so additional providers (e.g. other CalDAV hosts, Google Calendar, generic ICS feeds) can be added without rework. Captures the "provider" seam as an explicit architectural concern.
**Requirements:** TBD
**Plans:** 3/6 plans executed
**Plans:** 4/6 plans executed
Plans:
+7 -4
View File
@@ -4,13 +4,13 @@ milestone: v1.1
milestone_name: Operability & Polish
status: executing
stopped_at: Completed 16-03-PLAN.md
last_updated: "2026-06-13T09:26:02.327Z"
last_updated: "2026-06-13T12:16:33.687Z"
last_activity: 2026-06-13 -- Phase 16 execution started
progress:
total_phases: 19
completed_phases: 6
total_plans: 23
completed_plans: 20
completed_plans: 21
percent: 32
---
@@ -26,7 +26,7 @@ See: .planning/PROJECT.md (updated 2026-06-10)
## Current Position
Phase: 16 (ci-dependency-audit-and-security-checks) — EXECUTING
Plan: 4 of 6
Plan: 5 of 6
Status: Ready to execute
Last activity: 2026-06-13 -- Phase 16 execution started
@@ -106,6 +106,7 @@ _Updated after each plan completion_
| Phase 16 P01 | 188 | 3 tasks | 4 files |
| Phase 16-ci-dependency-audit-and-security-checks P02 | 25 | 3 tasks | 5 files |
| Phase 16-ci-dependency-audit-and-security-checks P03 | 2 | 2 tasks | 5 files |
| Phase 16 P04 | 45 | 4 tasks | 3 files |
## Accumulated Context
@@ -171,6 +172,8 @@ Recent decisions affecting current work:
- [Phase ?]: D-08 (16-01): assertNotDevBypassInProduction() boot guard — first statement in isMainModule(), exits non-zero when NODE_ENV=production AND DEV_AUTH_BYPASS=true; unit-tested
- [Phase ?]: D-03-SEC-VERSION: Pinned eslint-plugin-security@3.0.1 over 4.0.1 — stable, flat-config compatible with ESLint 9.39.4, more bake time
- [Phase ?]: D-03-OBJ-INJECT: detect-object-injection disabled globally in eslint-plugin-security block — all hits were numeric loop indices / schema-derived keys; zod guards real API input; 14 of 15 rules remain at error
- [Phase ?]: D-04-ALLOWLIST: crypto.test.ts TEST_KEY allowlisted by path — human-verified Vitest beforeAll synthetic AES-256-GCM fixture; 4th [[allowlists]] block in .gitleaks.toml
- [Phase ?]: D-04-BASELINE: gitleaks full-history baseline is empty [] after allowlisting — 613 commits / 23 MB scanned clean; PR-diff scans in 16-05 start from provably clean state
### Roadmap Evolution
@@ -235,7 +238,7 @@ Recent decisions affecting current work:
## Session Continuity
Last session: 2026-06-13T09:26:02.314Z
Last session: 2026-06-13T12:16:33.678Z
Stopped at: Completed 16-03-PLAN.md
Resume file: None
@@ -0,0 +1,108 @@
---
phase: 16-ci-dependency-audit-and-security-checks
plan: "04"
subsystem: infra
tags: [gitleaks, secret-scanning, dockerignore, image-hygiene, security, ci]
requires:
- phase: 16-ci-dependency-audit-and-security-checks
provides: Phase context, CI workflow, security check baseline strategy
provides:
- .gitleaks.toml — default ruleset + 4 allowlists (VAPID fixture, .env.example, .env.spike, crypto.test.ts AES fixture)
- scripts/gitleaks-baseline.json — committed empty-array full-history baseline (613 commits, 23 MB, zero findings)
- .dockerignore — excludes secrets/dev/bulk from Docker build context while preserving apps/api/src and workspace manifests
affects:
- 16-05 (gitleaks PR-diff scan CI job — consumes .gitleaks.toml + --baseline-path scripts/gitleaks-baseline.json)
- 16-06 (static .dockerignore assertion — greps the exclusion patterns added here)
tech-stack:
added:
- gitleaks v8.30.1 (secret scanner — used locally to generate baseline; CI binary installed in 16-05)
patterns:
- gitleaks allowlist-by-path pattern for known test fixtures (paths regex array in [[allowlists]] blocks)
- Full-history baseline committed as empty JSON; PR-diff scan uses --baseline-path to ignore pre-existing known-safe history
key-files:
created:
- .gitleaks.toml
- scripts/gitleaks-baseline.json
- .dockerignore
modified: []
key-decisions:
- "D-04-ALLOWLIST: crypto.test.ts TEST_KEY allowlisted by path — human-verified Vitest beforeAll synthetic AES-256-GCM fixture, not a real credential; 4th [[allowlists]] block added after human approval at the Task 3 checkpoint"
- "D-04-BASELINE: baseline is empty JSON array after allowlisting; all 613 commits scanned clean; PR-diff scans in 16-05 start from provably clean history"
patterns-established:
- "gitleaks allowlist block structure: [[allowlists]] with description + paths (raw TOML string regex) — match existing block style when adding future fixture paths"
requirements-completed: [SEC-01, IMG-02]
duration: 45min
completed: 2026-06-13
---
# Phase 16 Plan 04: Gitleaks Config, Full-History Baseline, and .dockerignore Summary
**gitleaks config (4 path allowlists) + committed empty baseline (613 commits clean) + .dockerignore keeping secrets/dev/bulk out of Docker build context**
## Performance
- **Duration:** ~45 min
- **Started:** 2026-06-13
- **Completed:** 2026-06-13
- **Tasks:** 3 (Tasks 1-2 by prior executor; Task 3 checkpoint + continuation by this executor)
- **Files modified:** 3 created + 1 extended (.gitleaks.toml 4th allowlist)
## Accomplishments
- `.gitleaks.toml` authored with `[extend] useDefault = true` inheriting the full default ruleset, plus 4 `[[allowlists]]` blocks covering the VAPID test fixture, .env.example, .env.spike, and the synthetic AES-256-GCM key in crypto.test.ts
- `scripts/gitleaks-baseline.json` regenerated after allowlisting the crypto.test.ts fixture — 613 commits scanned, ~23 MB of git history, zero findings; baseline is an empty JSON array `[]`, giving 16-05's PR-diff scan a provably clean starting state
- `.dockerignore` created, excluding `.env`, `node_modules`, `.git`, `.planning/`, `apps/api/tests/`, `apps/pwa/e2e/`, seed scripts, and bulk artifacts while preserving `apps/api/src` (required by the builder stage's `COPY apps/api ./apps/api`), `apps/pwa/src`, workspace manifests, and all `package.json`/`tsconfig.json` files
## Task Commits
1. **Task 1: .gitleaks.toml with default ruleset + fixture/env allowlists** - `2f1592c` (chore)
2. **Task 2: .dockerignore (secrets/dev/bulk, preserve builder inputs)** - `5819247` (chore)
3. **Task 3 (post-checkpoint): allowlist crypto.test.ts in .gitleaks.toml** - `fba22b4` (chore)
4. **Task 3 (post-checkpoint): regenerate clean full-history baseline** - `bc83495` (chore)
## Files Created/Modified
- `.gitleaks.toml` — gitleaks config: useDefault=true + 4 path-based allowlists (VAPID fixture, .env.example, .env.spike, crypto.test.ts AES fixture)
- `scripts/gitleaks-baseline.json` — committed full-history baseline: empty `[]` (613 commits clean)
- `.dockerignore` — Docker build context filter: excludes secrets/dev/bulk, preserves builder-stage inputs
## Decisions Made
- **D-04-ALLOWLIST:** The Task 3 human-verify checkpoint surfaced one baseline finding: `TEST_KEY` at `apps/api/tests/broker/crypto.test.ts:15`, a synthetic AES-256-GCM key assigned to `process.env.APP_PASSWORD_ENCRYPTION_KEY` in a Vitest `beforeAll`. Human verified it is a test fixture. Operator approved adding a 4th `[[allowlists]]` block for `apps/api/tests/broker/crypto\.test\.ts` so future PR-diff scans also suppress it by path. Allowlist added, baseline regenerated — result is zero findings.
- **D-04-BASELINE:** Empty baseline `[]` is the correct output when all known fixtures are properly allowlisted. The 16-05 gitleaks workflow will pass `--baseline-path scripts/gitleaks-baseline.json` so PR-diff scans only alert on new findings introduced in the PR, not pre-existing allowlisted history.
## Deviations from Plan
The original plan had Tasks 1-2 as `type="auto"` and Task 3 as a `type="checkpoint:human-verify"`. The continuation task (adding the 4th allowlist and regenerating the baseline) was triggered by the human-verified finding at the checkpoint — this is expected flow, not a deviation. The 4th allowlist block was added per the operator's "Approve + allowlist it" decision.
None - plan executed exactly as specified; the checkpoint and human-directed allowlist addition are the intended workflow.
## Issues Encountered
None — gitleaks scan completed cleanly in 3 seconds; zero unexpected findings after allowlisting the known test fixture.
## Threat Surface Scan
No new network endpoints, auth paths, file access patterns, or schema changes introduced by this plan. All changes are static config files (`.gitleaks.toml`, `.dockerignore`) and a JSON report artifact (`scripts/gitleaks-baseline.json`).
## User Setup Required
None — no external service configuration required. The gitleaks binary is installed in CI via the 16-05 workflow step, not checked in.
## Next Phase Readiness
- `16-05` (gitleaks PR-diff scan CI job): `.gitleaks.toml` and `scripts/gitleaks-baseline.json` are in place — 16-05 can wire the `gitleaks git --config .gitleaks.toml --baseline-path scripts/gitleaks-baseline.json` CI step immediately
- `16-06` (static .dockerignore assertion): `.dockerignore` contains all patterns the static assertion greps for; `apps/api/src` exclusion is verified absent
---
*Phase: 16-ci-dependency-audit-and-security-checks*
*Completed: 2026-06-13*