DR-103: destructive scripts fail closed on an explicit target allowlist
DR-103: destructive scripts fail closed on an explicit target allowlist
Section titled “DR-103: destructive scripts fail closed on an explicit target allowlist”Context
Section titled “Context”The id-400 pre-run sweep (scripts/cocoindex-nightly-sweep.ts) shipped with a
prod-denylist guard: refuse when SUPABASE_URL contains PROD_PROJECT_REF.
Review (PR #156, CodeRabbit finding) showed the guard fails open: with the
env var unset — one missing variable in a misconfigured CI environment — the
only protection on a destructive multi-table delete silently disappears. The
same shape had already been recorded in the machine-signal register (id-379
instance 8, id-381): a guard that is present and executing but watching too
weak a signal.
Decision
Section titled “Decision”A script that deletes or rewrites database rows MUST fail closed on an
explicit target allowlist: it requires a positively-supplied expected-target
identifier (e.g. KH_SWEEP_EXPECTED_PROJECT_REF) and refuses unless the live
connection target matches it. A missing guard input is a refusal, never a
pass. Denylists (refuse the prod ref) may be kept in addition, but are never
sufficient alone. The invoking workflow must supply the expected identifier
explicitly, so the authorisation is visible at the call site.
Reference implementation: scripts/cocoindex-nightly-sweep.ts +
.github/workflows/cocoindex-nightly.yml (id-400, commit edbc9e25).
Alternatives Considered
Section titled “Alternatives Considered”- Denylist only (refuse prod) — rejected: fails open on missing env, and protects only the one environment it names; every other wrong target passes.
- Require the env var but keep the denylist shape — rejected as the general rule: still answers “is this NOT prod” rather than “is this the intended target”.
- Interactive confirmation — not viable for CI-invoked scripts.
Consequences
Section titled “Consequences”- New destructive scripts (sweeps, resets, backfills, mass deletes) copy the allowlist shape; review treats a denylist-only or env-presence guard on a destructive path as a defect.
- Guard inputs appear explicitly in workflow env blocks, making the intended target auditable per invocation.
- Existing destructive scripts are brought under the rule opportunistically as they are next touched (no dedicated sweep mandated by this decision).