SAST tools › Secret scanning tools
Secret scanning tools: nine compared, and tested on git history
Secret scanning tools find API keys, tokens and passwords in code and, more importantly, in git history. Gitleaks is the free default for pre-commit hooks and CI. TruffleHog and Kingfisher, also free, check whether a key they find still works. On GitHub, Secret Protection adds push protection to private repos for $19 per committer a month. A SAST tool only reads today's files.
The test: a key that was committed, then deleted
This is the most common leak: someone commits a key, notices, and replaces it with an environment variable in the next commit. The key is gone from the files but still in the history that every clone carries. Winding AI, which publishes this site, made a throwaway repository with two commits. The first added a config.py holding a made-up AWS key pair, a made-up Stripe live key and a Postgres URL with a password. The second replaced all four with os.environ lookups. Four free tools then scanned it.
| Tool and mode | Current files | Git history | Said whether keys work |
|---|---|---|---|
Semgrep CE 1.185.0, p/secrets rules | 0 | Doesn't read history; 3 when pointed at the first commit's file | No |
| Gitleaks 8.30.1 | 0 (gitleaks dir) | 3 (gitleaks git): AWS ID, AWS secret, Stripe | No |
| TruffleHog 3.99.9 | 0 | 2: AWS, Stripe | Yes both "unverified" |
| Kingfisher 2.18.1 | 0 | 3: AWS, Stripe, the Postgres URL | Yes AWS and Stripe "inactive", Postgres "inconclusive" |
Two things stand out. Every tool that read only the current files found nothing, though the keys are one git log -p away. And only Kingfisher caught the password inside the database URL. TruffleHog and Kingfisher sent the AWS and Stripe candidates to the providers to check them, which is how Kingfisher could call them inactive (TruffleHog reported them as unverified). A live key should come back as verified, though this test had none. This is one tiny repository, not a benchmark, but the pattern holds for any leak that was "fixed" by deleting a line.
Nine secret scanners compared
| Tool | What it is | Git history | Validates | Blocks before push | Price |
|---|---|---|---|---|---|
| Gitleaks | Open source (MIT) CLI for repos, directories and stdin | Yes | No | Yes pre-commit hook | Free |
| TruffleHog | Open source (AGPL-3.0), classifies 800+ secret types; also scans S3, GCS and Docker images | Yes | Yes | Yes pre-commit hook | Free; Enterprise by quote |
| Kingfisher | MongoDB's open-source (Apache-2.0) scanner, written in Rust | Yes | Yes and maps what a key can reach | Yes pre-commit hook | Free |
| detect-secrets | Yelp's open-source (Apache-2.0) tool that keeps a baseline and stops new secrets | By design no | No | Yes pre-commit | Free; last release May 2024 |
| GitHub Secret Protection | Secret scanning across history, PRs, issues and wikis, with push protection, validity checks and AI-detected passwords | Yes | Yes for provider patterns | Yes push protection | Free on public repos; $19 per active committer on private |
| GitGuardian | Hosted secrets monitoring for code, CI and more | Free tier: 500 historical detections | Yes | Yes | Free up to 25 developers; Growth and Enterprise by quote |
| Semgrep Secrets | Semantic and entropy analysis inside the Semgrep platform | Beta | Yes | Yes pre-commit hook | $15 per contributor; not on the Free plan |
| Aikido | Secrets detection inside its SAST and SCA platform, in the IDE, CI and Git | Not stated | Yes liveness detection | Yes pre-commit blocking | Free for 2 users; Basic $350 for 10 |
| IonWarp | AI pull-request reviewer whose Security Review flags secrets added in a PR | No the PR's diff only | No | No | Free for 3 seats; Pro $49 for 5 |
Snyk also sells Snyk Secrets, on Enterprise only, at 0.66 credits ($0.66) per active contributor a day, about $20 a month each. For what the rest of GitHub's security add-ons cost, see GitHub Advanced Security pricing.
Does SAST find hardcoded secrets?
Partly. Semgrep's free rules found the AWS pair and the Stripe key as soon as they were pointed at the file from the first commit, and SonarQube lists secrets among the things it detects. So a SAST scan on each pull request will often catch a key on the way in. It falls short in three ways: it reads today's files, not history; its generic rules know fewer provider formats than a dedicated scanner, and neither Semgrep nor Gitleaks recognised the password in the database URL; and it can't tell you whether a key is live, which is the first thing you need to know at 2 a.m. The same split shows up between SAST and SCA: each scanner is built for one kind of risk.
Which one to use
- Code on GitHub, budget for it: Secret Protection, for push protection on every repo. It stops the key before it lands, which is cheaper than any clean-up.
- No budget: Gitleaks as a pre-commit hook and in CI on every push, plus a weekly TruffleHog or Kingfisher run over full history to sort live keys from dead ones.
- Secrets outside Git too (Slack, Jira, CI logs): GitGuardian, or TruffleHog Enterprise.
- Already paying for a platform: check what you have. Aikido includes secrets on its free plan; Semgrep and Snyk charge for them separately.
Found a live key? A filled-in checklist
- Revoke or rotate it at the provider first. GitHub's own guide says this is step one: once the key is revoked, rewriting history may not be needed at all.
- Read the provider's access logs for the time between the commit and the revocation. For an AWS key, CloudTrail records the API calls made with it.
- Replace the value in code with an environment variable or a secrets manager, in a normal pull request.
- Turn on blocking so it doesn't happen again: push protection, or a Gitleaks pre-commit hook.
- Rewrite history only if you must. GitHub warns that anyone with an old clone can push the secret straight back, and forks keep their copy.
Where IonWarp fits, and where it doesn't
IonWarp is an AI pull-request reviewer for GitHub, not a secret scanner. Its Security Review reads the diff of pull requests that touch auth, input, data access or secrets and flags a key written into source, a model prompt, a front-end bundle or a log line, in the same comment as its code review. It never scans git history, doesn't check whether a key is live, and can't block a push. In the test above it would only have seen the keys if the first commit arrived as a pull request, and never again after the second commit deleted them. Use Gitleaks, TruffleHog, Kingfisher or GitHub Secret Protection for secrets; IonWarp is at most an extra reader on new changes. IonWarp's security benchmark covers 13 pull requests, which is small.
Questions
Does a SAST tool find hardcoded secrets?
Partly. Semgrep and SonarQube have secret rules, and Semgrep's free rules found an AWS key pair and a Stripe key in the file that added them. But a SAST scan reads today's files, so it misses a key that was committed and then deleted, and it doesn't tell you whether the key still works. Use a secret scanner that reads git history.
Is GitHub secret scanning free?
On public repositories, yes: secret scanning and push protection are free. On private repositories you need GitHub Secret Protection, $19 per active committer a month, on a GitHub Team or Enterprise plan.
Should I use Gitleaks or TruffleHog?
Gitleaks for a fast, MIT-licensed check in pre-commit hooks and CI. TruffleHog when you want to know which found keys are live: it tries each candidate against the provider. Many teams run Gitleaks on every commit and TruffleHog or Kingfisher on a schedule over full history.
Related
- GitHub Advanced Security pricing Secret Protection and Code Security per committer, and what's free.
- SAST vs SCA Your code or your dependencies: which scanner finds what.
About this page
Published by Winding AI, Inc., the company that makes IonWarp, an AI pull-request reviewer. We earn nothing from links to other tools; links to IonWarp carry a tag so IonWarp can count visits from this site. Visits are counted with Google Analytics. If a price or fact here is wrong, write to support@winding.ai.