Skip to content

Back to the catalog

Betterleaks — secrets scanner from the Gitleaks creator
github.comrepo

Betterleaks — secrets scanner from the Gitleaks creator

Betterleaks is a configurable, fast secrets scanner maintained by the original Gitleaks author and team, capable of scanning git history, local filesystems, stdin, GitHub/GitLab orgs and specific PRs/MRs, Hugging Face models/datasets, and public S3/R2 buckets. Detection rules use regex plus an Expr (with legacy CEL compatibility) based prefilter/filter/validate pipeline, allowing entropy checks, keyword gating, and live API validation of found credentials (e.g. checking a GitHub PAT against api.github.com). It's used in production by projects like Aikido Security and shipped inside MegaLinter.

TL;DR A fast, expressively-configurable secrets scanner from the Gitleaks creator that scans git, filesystems, GitHub/GitLab, Hugging Face and S3, with live credential validation.
Document

What it is

Betterleaks is the CLI secrets scanner from the Gitleaks team. The summary covers its scan targets and detection model; what it can't carry is the concrete invocation surface, the prefilter-vs-filter distinction that governs performance, the validate subcommand, and the explicit production-config guidance.

Install and invoke

brew install betterleaks/tap/betterleaks
sudo dnf install betterleaks        # Fedora
docker pull ghcr.io/betterleaks/betterleaks:latest
go install github.com/betterleaks/betterleaks@latest

Scan scope is controlled per-target with --include, e.g. github <user> --include issues,prs,actions,releases,gists or gitlab <project> --include issues,mrs,releases,ci-jobs. Git scans parallelize with --source-workers=16. A specific PR/MR is scannable by URL (.../pull/113, .../-/merge_requests/42).

Revalidate a credential you already hold, skipping detection entirely:

printf '%s\n' "$GITHUB_TOKEN" | betterleaks validate --rule-id github-pat --simple

This prints only the status (e.g. VALID) — useful for triage or monitoring a known token, not just for scanning.

Prefilter vs filter — the mechanism that matters

Two evaluation stages, and the difference is a performance boundary, not a naming one:

  • prefilter runs before any regex and sees only attributes (path, git.author_name, etc.). Use it to bail out early — skip node_modules, binary extensions, renovate[bot] commits — before expensive scanning.
  • filter runs after a regex match and additionally sees finding["secret"] / finding["match"], so it can apply filter.entropy(...), keyword suppression, or path/author gating on the candidate.

Filters exist globally and per-rule. validate blocks run last and do live checks (an http.get against api.github.com/user, returning valid/invalid/validate.unknown). Logic is Expr; legacy CEL configs still parse but new configs should be Expr. Multipart rules read sibling rules via components["rule-id"]?.secret.

What to do

If you deploy this in CI, follow the page's own recommendation: maintain your own config rather than extending the upstream default directly. This keeps your ruleset stable across upgrades and lets you review new upstream rules before adopting them — an upstream rule change otherwise lands silently in your pipeline. Test rules against the Betterleaks Playground before shipping.

Techniques named here