history-leak-scan
Skill0 starsChanged 47 days agoMITView on GitHub
Deterministic secret scanner over git history (--history) or staged diff (--staged): provider keys, private keys, JWTs, sensitive filenames, entropy. Backs commit-gate. Use when: "scan for secrets", "did I commit a secret", after a repo goes public.
- Reads credentials
In this repository34 other files it gives its agents.
- audit-codeSkill
- audit-docsSkill
- auditSkill
- bisect-driverSkill
- coding-conventionsSkill
- commit-gateSkill
- compact-ioSkill
- cron-task-manageSkill
- cve-auditSkill
- data-integrity-auditSkill
- decision-logSkill
- deck-builderSkill
- determinism-guardSkill
- etl-validateSkill
- experiment-logSkill
- fetch-firstSkill
- flaky-test-detectorSkill
- github-repo-polishSkill
- golden-lockSkill
- landing-checkSkill
- llm-eval-harnessSkill
- local-secrets-manageSkill
- long-taskSkill
- milestone-trackSkill
- opus-workersSkill
- path-quirk-auditSkill
- reorg-proposalSkill
- research-briefSkill
- seed-controlSkill
- shell-portabilitySkill
- skill-vetSkill
- small-taskSkill
- token-squeezeSkill
- venue-fitSkill
The file
We split this skill into the rules it gives an agent
2 rules. About 0 are common, 1 is distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 42
Run
--canaryfirst: if the scanner was touched since last use. - Distinctive: line 60
No live credential verification (TruffleHog-style API checks) BY DESIGN: that would transmit candidate secrets to provider endpoints.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
history-leak-scan — deterministic secret scanner
The engine is pm-secretscan.js (portable Node, zero deps). It streams
git log -p --all (history) or git diff --cached (staged) and flags added
lines against per-provider regexes (18 rules; one, postgres-url-password,
flags a postgres URL with user:password@host unless the host is local or
.example/.test/.invalid or the password is a template/placeholder) + a
sensitive-filename rule
(.env*, .pem/.p12/.pfx, id_rsa, *_keys.env — a file of that NAME should never
be committed, whatever it contains; example/sample/template/fixture names
exempt) + a generic high-entropy-assignment detector + a weak-password rule,
with token-level placeholder suppression.
Commands
- Full-history scan (one or more repos):
node pm-secretscan.js --history <repo> [<repo>...]Exit 1 if any finding, 0 if clean. Redacts matched tokens in output. - Staged scan (what commit-gate runs):
node pm-secretscan.js --staged <repo> - Worktree scan (commit-gate uses it when a commit can record unstaged content):
node pm-secretscan.js --worktree <repo>- diff vs HEAD plus every untracked, non-ignored file (e.g. aftergit add -A, or with a pathspec /-o). - Self-test (part of the definition of done):
node pm-secretscan.js --canaryPlants real-format secrets + placeholders in a throwaway repo, asserts=10 real caught (one is a current-format
sk-proj-OpenAI key that only the openai-key rule can see; >=2 are postgres URLs) and 0 false positives. MUST printPASSbefore you trust a scan result — an unverified gate is theater.
When invoked
- Run
--canaryfirst if the scanner was touched since last use; paste the PASS line. Never report a "clean" scan from an unverified scanner. - Enumerate the repos to scan (
find <root> -name .git -type d). Scan all with--history. - Triage every finding by READING the actual line — distinguish a live credential from a guarded dev-default or an example. Do NOT auto-rotate; report, and on a real leak point at secret-rotation + the secrets-inventory.
- Report outcome-first: repos clean vs. findings, each finding as file@commit + rule + redacted snippet, and the honest severity.
Known limits
- Catches secrets that were COMMITTED. Files that were always gitignored
(
.env, key files) are correctly out of history — verify they were never committed by a clean history scan, not by their current absence. - Entropy detection can miss bespoke low-entropy formats — that's why the
per-provider regexes exist; extend
RULESwhen a new provider appears (and add a canary fixture for every new rule — a rule without a canary is unverified). - No live credential verification (TruffleHog-style API checks) BY DESIGN: that would transmit candidate secrets to provider endpoints. Triage of live-vs-dev-default stays a human/model judgment step.
- Heuristic exemption also covers rendered-doc twins under
docs/*.html(a generated HTML render of an exempt.md); strong provider/private-key rules still apply there. Diff headers with special-char filenames (git C-quotes them, e.g. an em-dash path) are unquoted before the filename rules run — otherwise every rule keyed on the filename would silently no-op. - Redaction shows first-4 + last-2 of long tokens; still treat output as sensitive.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

