From 31858e02e5d7502a4742df2947a3d335d9a14e99 Mon Sep 17 00:00:00 2001 From: Adam Moussa Date: Thu, 18 Jun 2026 15:58:15 -0400 Subject: [PATCH] fix(secrev): commit compliance-drift secret fixture as dotenv.fixture (canary broke on fresh clone) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The compliance-drift canary's planted tracked-secret fixture was BadName_repo/.env, but the repo root .gitignore lists '.env' — so it was never committed. On a fresh clone of main the file is absent, the secrets-committed check stops firing, and the canary FAILS (expected 6, got 5). It only passed where a gitignored, untracked '.env' happened to exist locally. Verified the failure reproduces in a clean clone of origin/main (3d97139) and in a fresh worktree. Fix (in-convention, mirrors the dependency-cve .fixture-suffix trick): ship the secret as BadName_repo/dotenv.fixture (committable, not gitignored); the --canary materialization renames dotenv.fixture -> .env in its temp work area. The dotgit/ index already TRACKS .env, so git ls-files still reports it and the drift fires. Restores the documented 6/6 canary on any fresh checkout. shellcheck stays clean. --- security-review/checkers/compliance-drift.sh | 7 +++++++ .../compliance-drift/BadName_repo/dotenv.fixture | 1 + .../checkers/fixtures/compliance-drift/README.md | 9 +++++++++ 3 files changed, 17 insertions(+) create mode 100644 security-review/checkers/fixtures/compliance-drift/BadName_repo/dotenv.fixture diff --git a/security-review/checkers/compliance-drift.sh b/security-review/checkers/compliance-drift.sh index d65175d..3115d11 100755 --- a/security-review/checkers/compliance-drift.sh +++ b/security-review/checkers/compliance-drift.sh @@ -342,6 +342,13 @@ if [ "$CANARY" -eq 1 ]; then nm="$(basename "$d")" cp -R "$d" "$FIXTURE_WORK/$nm" mv "$FIXTURE_WORK/$nm/dotgit" "$FIXTURE_WORK/$nm/.git" + # The planted-secret env file is shipped as `dotenv.fixture` (NOT `.env`): the repo's + # root .gitignore lists `.env`, so a literal `.env` fixture would never be committed and + # the secrets-committed drift would vanish on a fresh clone. Restore it to `.env` in the + # materialized work area (the dotgit/ index already TRACKS `.env`, so ls-files still + # reports it). Same committable-without-side-effects rationale as the `.fixture` suffix the + # dependency-cve fixtures use for their manifests. + [ -f "$FIXTURE_WORK/$nm/dotenv.fixture" ] && mv "$FIXTURE_WORK/$nm/dotenv.fixture" "$FIXTURE_WORK/$nm/.env" REPO_NAMES+=( "$nm" ); REPO_DIR["$nm"]="$FIXTURE_WORK/$nm" done elif [ -n "$TARGETS_OVERRIDE" ]; then diff --git a/security-review/checkers/fixtures/compliance-drift/BadName_repo/dotenv.fixture b/security-review/checkers/fixtures/compliance-drift/BadName_repo/dotenv.fixture new file mode 100644 index 0000000..4d56164 --- /dev/null +++ b/security-review/checkers/fixtures/compliance-drift/BadName_repo/dotenv.fixture @@ -0,0 +1 @@ +API_KEY=AKIAIOSFODNN7EXAMPLE diff --git a/security-review/checkers/fixtures/compliance-drift/README.md b/security-review/checkers/fixtures/compliance-drift/README.md index ed22725..5c45d1d 100644 --- a/security-review/checkers/fixtures/compliance-drift/README.md +++ b/security-review/checkers/fixtures/compliance-drift/README.md @@ -15,5 +15,14 @@ Fixtures (each a real git checkout so the tracked-`.env` / `ls-files` checks wor Total = **6** (`EXPECTED_DRIFT_COUNT`). The canary pins `DOCS_ONLY_REPOS=docs-repo` and `COMPLIANCE_EXEMPT=""` internally so it is deterministic regardless of the operator's env. +**Secret-fixture naming:** `BadName_repo`'s planted tracked-secret env file is committed as +`dotenv.fixture`, NOT `.env`. The repo's root `.gitignore` lists `.env`, so a literal `.env` +fixture would silently never be committed — on a fresh clone the `secrets-committed` drift would +vanish and the count would drop to 5 (this regression was caught by this very canary). The +`--canary` materialization renames `dotenv.fixture` → `.env` in its temp work area; the +`dotgit/` index already TRACKS `.env`, so `git ls-files` still reports it. This mirrors the +`.fixture`-suffix convention the `dependency-cve` fixtures use for their manifests. Keep any new +committed secret fixture under a non-gitignored name and rename it in the canary. + When you add/remove a check or fixture, update both the fixture and `EXPECTED_DRIFT_COUNT` in the same commit (the canary edit is itself caught on the next run — design §6.4).