ci: canary-test the secret scanner, and actually run tests/ - #530
Merged
Conversation
Phase 3 (preventive) of the secret-scanner programme. Two gaps, one shape.
1. THE SECRET SCANNER HAD NO CANARY. Every defect found in the 201-repo sweep
was invisible in CI, because a gate that cannot fail is indistinguishable
from a gate that passes:
* `continue-on-error: true` on gitleaks — the scan found a live Cloudflare
Global API Key in a PUBLIC repo and reported success anyway, for months,
across ~200 repos.
* `rust-secrets` grepped `./src` only. A Cargo workspace keeps code in
crates/*/src, so grep exited 2 on a missing directory and the enclosing
`if` read that as "clean" — 8 of 64 Rust repos (12.5%) were never
scanned at all.
* `const.*KEY.*=` never matched `static AUTH_KEY: &str = "…"`. That was
found ONLY because a canary planted 5 secrets and the job reported 4.
No amount of reading the regex would have shown it.
`tests/test_secret_scanner_canary.sh` plants known secrets and asserts the
scanner still trips: 9 assertions covering detection (with a COUNT, not just
an exit code — the `static` defect passed an exit-code check), workspace
layout, correct-code exemptions, exemption over-breadth, the self-flipping
cutoff, and the malformed-cutoff refusal.
It extracts the step body from secret-scanner-reusable.yml at run time and
executes it. NOT a copy — a copy silently drifts from what ships, which is
how these defects survived review in the first place.
MUTATION TESTED. Reintroducing each historical defect kills the canary:
src-only (F-10) ✓ no-static (F-11) ✓ cannot-fail (F-08) ✓
over-broad env exemption ✓ disarmed date guard ✓ 5/5 killed.
A canary that cannot fail would be the very thing it guards against.
2. tests/ WAS WIRED INTO NO WORKFLOW. `test_check_trusted_base.sh` has existed
for some time and never executed in CI — same shape again: a test that never
runs looks exactly like a test that passes. `self-test.yml` runs every
tests/*.sh, so adding a test is now sufficient to have it enforced. It is
fail-closed: empty discovery fails the job rather than reporting a vacuous
pass.
Also regenerates REGISTRY.a2ml — 7 stale source_hash entries accumulated from
#522/#525 plus these new files. This is the fourth registry-drift repair today;
the drift keeps reaching main because `Registry + topology in sync` is not a
required status check while a phantom `Dependabot` context forces --admin on
every merge. That ruleset fix is owner-only and tracked separately; without it
this repair will be needed again.
Verified: both test files pass locally (2/2); canary 9/9 against the shipping
reusable; 5/5 mutants killed; `build-registry.sh --check` exits 0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.




Phase 3 (preventive) of the secret-scanner programme. Two gaps, one shape.
1. The secret scanner had no canary
Every defect found in the 201-repo sweep was invisible in CI, because a gate that cannot fail is indistinguishable from a gate that passes:
continue-on-error: trueon gitleaksrust-secretsgrepped./srconlycrates/*/src;grepexits 2 on a missing dir and theifread that as clean. 8 of 64 Rust repos (12.5%) never scanned at allconst.*KEY.*=missedstatic AUTH_KEYtests/test_secret_scanner_canary.shplants known secrets and asserts the scanner still trips — 9 assertions:Note assertion 2 counts findings rather than checking the exit code. The
static AUTH_KEYdefect passed an exit-code assertion — exit 1 only proves ≥1 was found, not that all were.It extracts the step body from
secret-scanner-reusable.ymlat run time and executes it. Not a copy: a copy silently drifts from what ships, which is how these defects survived review.Mutation tested
A canary that cannot fail would be the very thing it guards against. Reintroducing each historical defect kills it:
./src-only scanstaticfrom the KEY patternenv::varexemption5/5.
2.
tests/was wired into no workflowtests/test_check_trusted_base.shhas existed for some time and never executed in CI — the same shape a third time: a test that never runs looks exactly like a test that passes.self-test.ymlruns everytests/*.sh, so adding a test is now sufficient to have it enforced. Fail-closed: empty discovery fails the job rather than reporting a vacuous pass.Also: registry regeneration
7 stale
source_hashentries accumulated from #522/#525 plus these new files.mainbecauseRegistry + topology in syncis not a required status check, while a phantomDependabotcontext forces--adminon every merge — which bypasses all protection including the check that correctly failed on the PR. That ruleset fix is owner-only and tracked separately; without it this repair will be needed again.Verified
scripts/build-registry.sh --checkexits 0🤖 Generated with Claude Code