Queue-North-Website/scripts
null 26136f4e5c security: the scanner never ran its private-key pattern, and verify never saw dist
Three faults in one guard, the only thing standing between a credential and a
pushed commit. Found while planning Batch 17; closes #235.

1. grep was called without -e, at both call sites. The private-key pattern
   starts with dashes, so grep read it as an option, exited 2, and the beside-it
   2>/dev/null threw the complaint away. A staged private key passed the
   pre-commit hook, and had since the rule was written. Proven in a scratch
   repository before and after.

2. The 2026-08-29 pattern, committed as-is in 7415e19, flagged two comment
   lines that exist to show the shape of a credential. verify was therefore red,
   and release.sh would have died after bumping package.json, package-lock.json
   and the Dockerfile, leaving a tree that pre-push then refuses.

3. verify never scanned dist/, though SECURITY_CHECKLIST.md has listed the
   bundle scan as a release check for months. A key can reach the bundle from an
   environment variable inlined at build time without ever being committed.

What changed, beyond -e: every pattern is compiled against empty input before
the scan and an unreadable one exits 2, because silence from a broken matcher
looks exactly like a clean tree. The NAME=value pattern now also catches quoted
values, which is how a real secret is usually written down and which it has
always missed. A line that must show a credential shape carries `secrets-ok:`
and a reason, which excuses that line alone and stays visible to review and to
grep. Guard 20-secrets runs --tracked and --built dist/.

Proven by mutation, per GUARDS.md: a staged PEM header, a bare API_KEY=, a
quoted API_KEY=, an exported secret and an AWS key id each exit 1; a ${VAR}
value, a <placeholder>, an excused line and a delete-only commit each exit 0; an
unreadable pattern exits 2 with content staged and with none; a key planted in
dist/ fails guard 20-secrets alone, masked in the report.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 04:23:39 -05:00
..
verify.d security: the scanner never ran its private-key pattern, and verify never saw dist 2026-09-10 04:23:39 -05:00
backup.sh chore: adopt template scripts and git hooks, retire phase-versioning 2026-08-18 01:18:20 -05:00
check-env.sh security: the scanner never ran its private-key pattern, and verify never saw dist 2026-09-10 04:23:39 -05:00
deploy.sh fix(deploy): stop two ways this tooling would have broken production 2026-08-18 03:33:20 -05:00
doc-triggers.py chore: adopt template scripts and git hooks, retire phase-versioning 2026-08-18 01:18:20 -05:00
docker-test.sh chore: add docker-push.sh, docker-test.sh, npm scripts, bump v0.5.0 2026-05-14 01:18:44 -05:00
forgejo-issue.py chore: adopt template scripts and git hooks, retire phase-versioning 2026-08-18 01:18:20 -05:00
healthcheck.sh fix(infra): queuenorth.com is the production origin, and it is this deployment 2026-08-18 02:08:12 -05:00
preflight.sh fix(infra): queuenorth.com is the production origin, and it is this deployment 2026-08-18 02:08:12 -05:00
prerender.js feat(seo): publish privacy policy, remove street address, prerender all routes (batch 0.9.3) 2026-08-01 01:45:52 -05:00
qa-browser.mjs fix(ui): header CTA clipped at iPad portrait, and reCAPTCHA cut off at 320px 2026-08-18 04:05:37 -05:00
release.sh fix(deploy): stop two ways this tooling would have broken production 2026-08-18 03:33:20 -05:00
restore-check.sh chore: adopt template scripts and git hooks, retire phase-versioning 2026-08-18 01:18:20 -05:00
secrets.sh security: the scanner never ran its private-key pattern, and verify never saw dist 2026-09-10 04:23:39 -05:00
status.sh chore: adopt template scripts and git hooks, retire phase-versioning 2026-08-18 01:18:20 -05:00
verify.sh chore: adopt template scripts and git hooks, retire phase-versioning 2026-08-18 01:18:20 -05:00