Secret-scan: find leaked secrets in your repo – one zero-dependency Python file

ninthlife1 pts0 comments

GitHub - ninthlife-tools/secret-scan: Find accidentally committed secrets before they cost you money. One Python file, zero dependencies, CI-ready. · GitHub

/" data-turbo-transient="true" />

Skip to content

Type / to search

Sign in<br>Sign upAppearance settings

You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.

Dismiss alert

{{ message }}

ninthlife-tools

secret-scan

Public

Notifications<br>You must be signed in to change notification settings

Fork

Star

master

BranchesTags

Go to file

CodeOpen more actions menu

Folders and files<br>NameNameLast commit message<br>Last commit date<br>Latest commit

History<br>2 Commits<br>2 Commits

LICENSE

LICENSE

README.md

README.md

secret_scan.py

secret_scan.py

test_secret_scan.py

test_secret_scan.py

View all files

Repository files navigation

secret-scan

Find accidentally committed secrets before they cost you money.

Zero dependencies, Python 3.8+ stdlib only. Scans a directory for high-signal<br>secret patterns (AWS keys, GitHub tokens, Slack tokens, Stripe live keys,<br>private-key blocks, generic api_key = "..." assignments) and exits 1 when<br>anything is found, so it drops straight into CI.

Usage

results.sarif # SARIF 2.1.0 for code-scanning dashboards<br>python3 secret_scan.py --exclude fixtures --exclude testdata<br>python3 secret_scan.py --history # also scan git history<br>python3 secret_scan.py --history --history-max-commits 100 # cap history scan<br>python3 secret_scan.py --staged # scan only git-staged changes<br>python3 secret_scan.py --install-hook [path] # install the pre-commit hook">python3 secret_scan.py # scan current directory<br>python3 secret_scan.py ~/code # scan another tree<br>python3 secret_scan.py --json # machine-readable output<br>python3 secret_scan.py --format sarif > results.sarif # SARIF 2.1.0 for code-scanning dashboards<br>python3 secret_scan.py --exclude fixtures --exclude testdata<br>python3 secret_scan.py --history # also scan git history<br>python3 secret_scan.py --history --history-max-commits 100 # cap history scan<br>python3 secret_scan.py --staged # scan only git-staged changes<br>python3 secret_scan.py --install-hook [path] # install the pre-commit hook

Exit codes: 0 clean, 1 findings, 2 bad usage (including a missing or<br>corrupt baseline file, or --history outside a git repository).

Suppressing findings

Inline: any line containing the literal string secret-scan:ignore is<br>skipped, whatever the comment style:

api_key = "not-a-real-secret" # secret-scan:ignore<br># AWS example key, safe: AKIAIOSFODNN7EXAMPLE secret-scan:ignore

Baseline: snapshot the current findings once, then only fail on new ones.<br>Findings are matched by a content hash of the line, so they stay suppressed<br>when line numbers shift:

python3 secret_scan.py --write-baseline .secret-scan-baseline.json # snapshot current findings<br>python3 secret_scan.py --baseline .secret-scan-baseline.json # suppress known findings

Both flags compose with --json, --format sarif, and --exclude.

Scanning git history

--history additionally scans committed file versions, so a secret that was<br>committed and later deleted from the working tree still gets flagged — it<br>still lives in .git and is still exploitable.

How it works: git rev-list --all lists commits (newest first), then each<br>commit's tree is dumped line-by-line with git grep -I -n -e "^" -- .<br>and fed through the same patterns as the working-tree scan. This was chosen<br>over parsing git log -p diffs: log -p skips merge commits and only shows<br>changed lines, so a secret introduced by a merge — or before the capped<br>window but still present in it — would be missed. Scanning each commit's<br>full tree attributes every finding to a commit that actually contains it.

Findings are deduplicated by (file, rule, line content); the reported<br>commit is the newest one whose tree contains the line. A history finding<br>that duplicates a working-tree finding is dropped — the tree finding<br>already covers it.

Text output: file@commit: rule. JSON findings carry a "commit" key;<br>SARIF results carry properties.commit and the commit in the message.

History findings work with --baseline/--write-baseline exactly like<br>working-tree findings (matched on file, rule, and line content hash).

--history-max-commits N (default 500) caps how many of the newest<br>commits are scanned so huge repositories stay tractable. History older<br>than the cap is not scanned.

Requires git on PATH; outside a git repository --history exits 2.

Pre-commit hook mode

--staged scans only what is about to be committed: the added lines in<br>git diff --cached --unified=0 --no-color, attributed to file and new-file<br>line number. Only added lines are scanned — a secret sitting on an untouched<br>or deleted line was already committed and is a job for --history (the two<br>flags are mutually exclusive). Inline secret-scan:ignore, --baseline,<br>--json, --format sarif, and...

history scan secret_scan python3 secret commit

Related Articles