secret-audit
Procedure
- Tooling: prefer
gitleaks git --report-format json --report-path /tmp/gitleaks.json .ifcommand -v gitleakssucceeds (detectis deprecated since gitleaks 8.19; on an older gitleaks usegitleaks detect --source .); elsetrufflehog git file://. --json; else fall back to grep overgit log -p --allwith the pattern set below. - Fallback pattern set (grep -E):
AKIA[0-9A-Z]{16},sk-(live|test|proj|ant)-[A-Za-z0-9_-]{16,},gh[pousr]_[A-Za-z0-9]{30,},xox[abpr]-,-----BEGIN [A-Z ]*PRIVATE KEY-----,eyJ[A-Za-z0-9_-]{20,}\.eyJ,(?i)(password|passwd|secret|token|api[_-]?key)\s*[:=]\s*["'][^"']{12,}["'], plus.env,*.pem,*.p12,id_rsafilenames in history:git log --all --diff-filter=A --name-only --format='' | grep -E '(^|/)(\.env|.*\.pem|.*\.p12|id_rsa)$'. - Deduplicate; for each finding record
path | first commit (sha, date, author) | still in HEAD? | type. - Classify: live in HEAD (critical), only in history (high), example/test/false positive (note, no action).
- Remediation plan, in this order, as a checklist for the user:
- Rotate every credential found (it is compromised once committed, even if purged).
- Remove from HEAD: move to env/
.env(gitignored), commit. - Purge history only if the repo is/will be public or shared:
git filter-repo --path <file> --invert-pathsor--replace-text, then force-push with--force-with-leaseand tell collaborators to re-clone. Do not run this without explicit approval. - Add prevention:
.gitignoreentries, pre-commit hook (gitleaks git --pre-commit --staged .;protect --stagedon gitleaks older than 8.19), and this plugin'ssecret-scanhook.
- Print the findings table and the checklist. Never print full secret values; mask to first 4 + last 2 chars. That includes notes: when a value matches a known placeholder (the AWS docs example key, a vendor's sample token), say so by name and keep the masked form, never the full string.
Rules
- Never rewrite history or force-push in this skill; propose only.
- Never paste unmasked secrets into the transcript.
Eval
evals/secret-audit/: fixture repo where a .env with a fake AWS key was committed then deleted two commits later; expected: finding reported as "only in history" with the introducing sha, value masked, rotate-first plan, no history rewrite executed.