secretgate
A zero-dependency secret scanner for git repos. One file, Python 3.9+, stdlib only.
1 file 0 dependencies no network calls MIT
secretgate finds leaked API keys, tokens, private keys, database connection strings, and high-entropy random strings in your working tree, your staged diff, or your entire git history — and exits non-zero so CI can block the push.
Fastest start (no install)
curl -fsSL https://raw.githubusercontent.com/tianzhicdev/secretgate/v1.2.7/secretgate.py -o secretgate.py
python3 secretgate.py scan # working tree
python3 secretgate.py scan --staged # pre-commit style: staged diff only
python3 secretgate.py scan --history # audit every blob ever committed
Or drop it in a repo and make it a hook permanently:
python3 secretgate.py install # writes .git/hooks/pre-commit
GitHub Actions users get a one-liner from the companion repo:
- uses: tianzhicdev/secretgate-action@f5d399b2b232241af124de0f21ecad9d23e27cf5
Common questions
How do I scan git history for secrets without installing anything?
Download the single secretgate.py file and run
python3 secretgate.py scan --history. It walks every blob in all
branches (git rev-list --all), deduplicates by blob SHA, and reports
findings as path@rev. No pip, no binary, no VM.
Is there a zero-dependency alternative to gitleaks or trufflehog?
That is exactly the gap secretgate fills. gitleaks and trufflehog are excellent but ship per-platform binaries you must install and keep current. secretgate is one Python file using only the standard library — designed for air-gapped machines, minimal CI images, and anywhere a package install is a policy problem.
What does it detect?
Provider patterns for AWS, GitHub (classic + fine-grained), OpenAI, Anthropic,
Stripe, Slack (tokens + webhooks), Hugging Face, npm, Twilio, Google API keys, JWT
bearer tokens, PEM private-key blocks, and DB connection strings with embedded
credentials — plus a generic key = value rule and a Shannon-entropy sweep
(≥4.35 bits/char over 24+ char tokens) for random secrets no pattern covers.
Run secretgate rules for the live list.
Will it print my secrets in full?
No. Findings are shown as previews like ghp_…abc (40 chars); short
values show only a masked prefix. Secrets never leave your machine — secretgate makes
zero network calls and never phones home.
How do I silence a false positive?
Add a comment on the same line as the finding: # secretgate: allow
(also honors nosec, pragma: allowlist and do not flag;
any comment style works — #, //, <!-- -->.
The annotation applies to that line only — on the line above or below it does
nothing). Placeholders like
changeme, <your-key>, or {{ vault }}
are ignored automatically. For whole files or directories (e.g. checked-in
signed receipts), list them in .secretgateignore at the repo
root — gitignore-style globs. --history stays strict.
Is the release signed / how do I verify the file I downloaded?
Yes. The release attaches a self-contained signed receipt,
secretgate-v1.2.7-proof.md, with the exact release file embedded
(base64). One command verifies everything:
python3 ethkey.py verify secretgate-v1.2.7-proof.md --require
0xFD4090e27C1f946Ff01a265cAa7d4ACA662acC15 exits 0 only when payload
hash, EIP-191 signature, and signer all match — or paste the receipt into the
browser
verifier (the link pre-fills the address).
The legacy .sig.txt asset is still attached too.
Links
- Source & issues: github.com/tianzhicdev/secretgate
- GitHub Action: secretgate-action
- Ships as the
secretscanhook in hookpack - Related reading: how to vet a GitHub bounty payout rail (the other thing our agents build)