Skip to content

Back to the catalog

Betterleaks
github.comrepo

Betterleaks

Betterleaks is a configurable secrets scanner built by the original Gitleaks author and team as its spiritual successor. It scans git history, local filesystems, GitHub/GitLab orgs, projects, PRs and MRs, Hugging Face repos, and S3-compatible buckets (including Cloudflare R2 and Common Crawl), and supports live credential validation via HTTP checks defined in its TOML config. Detection logic is expressed through prefilters and filters written in Expr (with legacy CEL compatibility), letting users tune regex matching, entropy thresholds, and multipart rule correlation for lower false positives.

TL;DR A configurable, Gitleaks-successor secrets scanner covering git, GitHub, GitLab, Hugging Face, and S3 sources with built-in credential validation.
Document

What it is

Betterleaks, the secrets scanner from the Gitleaks maintainers. The summary covers its scan targets and engine; what it doesn't carry is the concrete config model and the evaluation order that determines when each stage runs — the part you need to actually write or tune rules.

How it works

Detection runs in stages, and where a check lives decides what data it can see:

  • prefilter runs before any regex and can only read the attributes map (e.g. attributes["path"], attributes["git.author_name"]). Use it to bail out of expensive scans early — skip binaries, node_modules, vendor, or renovate[bot] commits.
  • filter runs after a regex match, for every candidate, and additionally sees finding["secret"] / finding["match"]. Filters exist at global and rule level.
  • validate runs after match-and-filter, async, and can make live calls (e.g. http.get to api.github.com/user, checking r.status == 200) returning valid/invalid/validate.unknown(r).

Logic is written in Expr; older CEL configs are still accepted but new configs should use Expr. Multipart rules read sibling matches via components["rule-id"]?.secret ?? ""; primary named groups via finding["captures"].

flowchart LR
  A[resource / attributes] --> P{prefilter}
  P -->|match| X[skip, no scan]
  P -->|pass| R[regex match]
  R --> F{filter}
  F -->|match| D[drop finding]
  F -->|pass| V[validate: live API call]
  V --> Res[valid / invalid / unknown]

What to do

Standalone credential revalidation without running detection:

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

Parallelize Git history scans:

betterleaks git /path/to/repo -v --source-workers=16

Scope a GitHub/GitLab scan to specific surfaces with --include (e.g. issues,prs,actions,releases,gists).

Caveats

The page states a production recommendation directly: do not extend the upstream default config directly. Maintain your own config so your rule set stays stable across upgrades and you can review new upstream rules before adopting them. Note also that validate rules make outbound authenticated requests with the candidate secret — a deliberate side effect to weigh before enabling in CI.

Techniques named here