AppSecNews
Secret Scanning comparison

Gitleaks vs detect-secrets: History Sweeps or a Baseline You Hold

Gitleaks digs through git history with TOML rules; detect-secrets gates new commits against a baseline. How each fits pre-commit, CI and legacy repos.

AppSecNews editors 7 min read

At a glance

Gitleaks and detect-secrets side by side
Fact Gitleaks Gitleaks detect-secrets Yelp
Best for Scanning git history and working trees for committed credentials Stopping new secrets at commit time without drowning in existing ones
License Open source Open source
Maturity Established Established
Deployment 2 in common
  • CLI (both)
  • Ci Cd (both)
  • CLI (both)
  • Ci Cd (both)
Languages Not recorded Not recorded
Integrations 3 in common
  • GitHub Actions (both)
  • Gitlab Ci (both)
  • Pre Commit (both)
  • Docker
  • Pre Commit (both)
  • GitHub Actions (both)
  • Jenkins
  • Gitlab Ci (both)
Profile Full Gitleaks profile Some details still being confirmed Full detect-secrets profile Some details still being confirmed

From the structured catalog records. Highlighted entries are shared by both tools. No scores or rankings: see the editorial policy.

Contents
  1. The short answer
  2. How they differ
  3. Detection approach and reach
  4. Adopting on a repository that already has secrets
  5. Pre-commit versus CI placement
  6. Extending and tuning
  7. Where each one falls short
  8. Pick Gitleaks if / Pick detect-secrets if
  9. Frequently asked questions

These two land on the same shortlist because they answer the same request from leadership: stop credentials getting into our repositories, with an open-source tool we can run ourselves and no code leaving the network. Both are single command line tools, both run as a pre-commit hook and as a CI step, and both mix provider patterns with entropy checks. On a feature grid they look interchangeable.

The difference is what each tool treats as the unit of work. Gitleaks treats the repository's entire commit graph as the thing to inspect, and it wants to tell you about every secret that was ever committed, including the ones deleted years ago. detect-secrets treats the current state of the code as a line in the sand: it records what is already there in a baseline file and only complains about what is new. One is built to find your past. The other is built to let you ignore it, deliberately, while you stop the bleeding.

The short answer #

Pick Gitleaks if you need to know what is already exposed in history, want one rule file shared across many repositories, and have someone who will triage and baseline the first sweep. Pick detect-secrets if your repositories already contain findings you cannot clean up soon and your priority is blocking new credentials at commit time from tomorrow morning. Running both is reasonable and common: detect-secrets as the developer-facing gate on new changes, Gitleaks as a scheduled history sweep owned by security. What you should not do is run both as competing pre-commit hooks and make developers satisfy two sets of rules for the same line.

How they differ #

Detection approach and reach #

Gitleaks reads a repository as a stream of git patches and matches each added line against a TOML rule set. Every rule carries a regular expression, optional keywords that cheaply prescreen lines, an optional entropy threshold on a capture group, and allow-list conditions. Because it reconstructs every diff in the commit graph, a key that was committed and then removed still shows up, which matters because the object is still fetchable by anyone with a clone.

detect-secrets runs files through pluggable detectors: keyword detectors looking for assignments to names like password, provider expressions for recognizable formats such as AWS access key IDs and private key headers, and entropy detectors over base64 and hex strings. By default it inspects the working tree, not deep history. A secret removed from the current files but still reachable in old commits is outside its view unless you add another approach.

This axis favors Gitleaks for anyone who needs an answer to "what has already leaked". It favors neither for day-to-day detection of fresh commits, where both find the obvious formats.

Adopting on a repository that already has secrets #

This is where detect-secrets earns its place. You run it once, it writes a .secrets.baseline file holding a hashed fingerprint of every current finding, and from then on scans fail only on findings not in that file. The hashing means the baseline records that a secret exists at a location without storing the secret. An interactive audit command walks a reviewer through entries to mark them true or false positive, and that verdict persists. Blocking starts on day one and cleanup becomes a separate, schedulable project.

Gitleaks can be baselined too. Findings carry a fingerprint of file, rule, commit and line, and you can suppress accepted ones through a .gitleaksignore file or a baseline report. But the workflow is built around the scan, not the baseline, and the first history sweep of an old repository produces enough findings to stall a rollout unless you baseline immediately. Because fingerprints include line position, unrelated edits can also bring an accepted finding back.

This axis favors detect-secrets, clearly, for legacy codebases and for teams that want commit-time enforcement before any cleanup has happened.

Pre-commit versus CI placement #

Both tools integrate with the pre-commit framework. detect-secrets was designed for that spot: the hook compares staged changes against the baseline, and a CI job re-runs the check to catch anyone who skipped the hook or let the baseline drift. The developer operates the hook, and security owns the baseline policy.

Gitleaks also works as a hook on staged changes, but its distinctive value is in CI and on a schedule. An incremental scan on each pull request catches new leaks, and a periodic full-history sweep catches what incremental scans never revisit. On a large monorepo that sweep is a scheduled job, not something you run on every push. SARIF and JSON output let findings flow into existing code scanning views rather than a bespoke report.

This axis favors detect-secrets at the developer's keyboard and Gitleaks in the pipeline and the nightly job.

Extending and tuning #

Gitleaks rules are plain TOML, so an application team can add a pattern for an internal token, review it in a pull request and ship the same file to every repository. detect-secrets plugins are ordinary Python classes, which is more powerful when a check needs logic rather than a pattern, and easy to unit test, but it asks for Python comfort. Both need path and value filters for lockfiles, minified assets and fixtures, because both run entropy checks that fire on them.

This axis favors Gitleaks for organizations standardizing one config across many repositories, and detect-secrets for Python-heavy teams who want custom detectors with real logic.

Where each one falls short #

Gitleaks reports matches, not live credentials. It does not call the provider, so separating an expired test key from an active production one is manual work, and on a mature repository the first full sweep hands someone a long list with no ordering by risk. Entropy rules fire on generated clients and committed blobs, the allow-list grows, and by month three the question is whether anyone still reviews what goes into it.

detect-secrets fails through its best feature. Regenerating the baseline is one command, auditing it is tedious, and under deadline pressure developers regenerate to turn a red build green, silently accepting whatever new secret triggered the failure. By month three an unreviewed baseline can contain real credentials that the tool now treats as approved. It also leaves history unexamined, so a team can feel protected while the old key that caused the incident is still sitting in an early commit. Treat baseline changes as reviewed artifacts, approved by someone outside the committing team, or the tool stops meaning anything.

Pick Gitleaks if / Pick detect-secrets if #

Pick Gitleaks if:

  • You are responding to a leak and need to find every credential ever committed, including deleted ones.
  • You want one version-controlled rule file applied identically across a large repository estate.
  • Your findings need to land in an existing code scanning view through SARIF.
  • Security has an engineer who will own the rule file, the ignore file and the scheduled sweep.
  • Your repositories are relatively clean and the first history scan will be manageable.

Pick detect-secrets if:

  • Your repositories already hold findings you cannot remediate before you need a control in place.
  • The immediate goal is a pre-commit gate that blocks new credentials without a cleanup project first.
  • You want a persistent true or false positive verdict on each existing finding through an audit step.
  • Your team writes Python and wants custom detectors with logic beyond a regular expression.
  • You can enforce review on baseline changes rather than letting developers regenerate at will.

Frequently asked questions #

Can detect-secrets replace a history scan?

No. It is built to watch the working tree and new changes, not to reconstruct past commits. If a credential was committed and later deleted, you need a history scanner such as Gitleaks, or a one-off sweep, to find it.

Does Gitleaks have a baseline, or is that only detect-secrets?

Gitleaks can suppress accepted findings through a .gitleaksignore file or a baseline report, so you are not forced to fix everything before enabling it. The difference is emphasis: detect-secrets makes the baseline and its audit the core of the workflow, while in Gitleaks it is a suppression mechanism around the scan.

Will either tool tell me whether a found key still works?

Gitleaks does not validate credentials against providers. Whether any detect-secrets plugins verify live credentials depends on the plugin set you run, so confirm against its current plugin list before relying on it. Plan on a separate validation step or a platform that verifies if triage speed matters.

Should both run as pre-commit hooks?

Usually not. Two hooks mean two rule sets and two suppression files for developers to satisfy on the same change. Pick one for the commit gate and use the other, if at all, in CI or on a schedule.

Full profiles: Gitleaks and detect-secrets.