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