betterleaks
betterleaks is a next-generation SAST tool for detecting and preventing secrets like passwords, API keys, and tokens in git repositories and filesystems. Created by the author of gitleaks, betterleaks delivers significantly higher recall (98.6% vs 70.4% on the CredData benchmark), lower false-positive rates, and 4–5× faster scanning.
Key Features:
- BPE-based detection using cl100k_base tokenization instead of Shannon entropy, dramatically reducing false positives on UUIDs, Base64 strings, and hashes
- Full git history scanning including all branches and commits, plus filesystem-only mode
- Live secret validation via CEL-based async HTTP requests per rule
- Custom rule support using CEL (Common Expression Language) filter expressions
- Automatic encoding handling — recursively decodes base64, hex, unicode, and nested archives
- Multiple output formats including JSON, SARIF, and custom Go templates
- Backward compatible — reads existing
.gitleaks.tomland.gitleaksignorefiles - Pre-commit hook integration to prevent secrets from being committed
- Baseline support to ignore known secrets while catching new ones
- Pure Go — no CGO or Hyperscan dependency, runs on any modern OS/arch
Scan only Pull Request commits
VALIDATE_ALL_CODEBASE: false doesn't make betterleaks analyze only updated files. To analyze only commits on a Pull Request, set VALIDATE_ALL_CODEBASE: false together with REPOSITORY_BETTERLEAKS_PR_COMMITS_SCAN: true; this only works for select platforms:
- GitHub Actions
- Azure Pipelines
- GitLab Pipelines (Merge Requests and External Pull Requests — Premium/Ultimate only)
You can also set the following MegaLinter environment variables manually:
PULL_REQUEST=trueREPOSITORY_BETTERLEAKS_PR_COMMITS_SCAN: trueREPOSITORY_BETTERLEAKS_PR_SOURCE_SHAwith the last commit SHA from your PRREPOSITORY_BETTERLEAKS_PR_TARGET_SHAwith the target branch commit SHA
Migration from gitleaks
betterleaks is fully compatible with your existing .gitleaks.toml configuration and .gitleaksignore files — no changes needed to migrate. Simply disable REPOSITORY_GITLEAKS and enable REPOSITORY_BETTERLEAKS.
betterleaks documentation
- Version in MegaLinter: 1.5.0
- Visit Official Web Site
- See How to configure betterleaks rules
- See How to disable betterleaks rules in files
- See How to ignore files and directories with betterleaks
- You can define a
.betterleaksignorefile to ignore files and folders
- You can define a
Configuration in MegaLinter
- Enable betterleaks by adding
REPOSITORY_BETTERLEAKSin ENABLE_LINTERS variable - Disable betterleaks by adding
REPOSITORY_BETTERLEAKSin DISABLE_LINTERS variable
| Variable | Description | Default value |
|---|---|---|
| REPOSITORY_BETTERLEAKS_PR_COMMITS_SCAN | Scan only commits in the current Pull Request/Merge Request | false |
| REPOSITORY_BETTERLEAKS_PR_SOURCE_SHA | Source commit SHA of the Pull Request/Merge Request | `` |
| REPOSITORY_BETTERLEAKS_PR_TARGET_SHA | Target commit SHA of the Pull Request/Merge Request | `` |
| REPOSITORY_BETTERLEAKS_ARGUMENTS | User custom arguments to add in linter CLI call Ex: -s --foo "bar" |
|
| REPOSITORY_BETTERLEAKS_COMMAND_REMOVE_ARGUMENTS | User custom arguments to remove from command line before calling the linter Ex: -s --foo "bar" |
|
| REPOSITORY_BETTERLEAKS_CLI_LINT_MODE | Override default CLI lint mode ⚠️ As default value is project, overriding might not work - file: Calls the linter for each file- list_of_files: Call the linter with the list of files as argument- project: Call the linter from the root of the project |
project |
| REPOSITORY_BETTERLEAKS_PRE_COMMANDS | List of bash commands to run before the linter | None |
| REPOSITORY_BETTERLEAKS_POST_COMMANDS | List of bash commands to run after the linter | None |
| REPOSITORY_BETTERLEAKS_UNSECURED_ENV_VARIABLES | List of env variables explicitly not filtered before calling REPOSITORY_BETTERLEAKS and its pre/post commands | None |
| REPOSITORY_BETTERLEAKS_CONFIG_FILE | betterleaks configuration file name Use LINTER_DEFAULT to let the linter find it |
.betterleaks.toml |
| REPOSITORY_BETTERLEAKS_RULES_PATH | Path where to find linter configuration file | Workspace folder, then MegaLinter default rules |
| REPOSITORY_BETTERLEAKS_DISABLE_ERRORS | Run linter but consider errors as warnings | false |
| REPOSITORY_BETTERLEAKS_DISABLE_ERRORS_IF_LESS_THAN | Maximum number of errors allowed | 0 |
| REPOSITORY_BETTERLEAKS_CLI_EXECUTABLE | Override CLI executable | ['betterleaks'] |
MegaLinter Flavors
This linter is available in the following flavors
| Flavor | Description | Embedded linters | Info | |
|---|---|---|---|---|
![]() |
all | Default MegaLinter Flavor | 137 | |
| c_cpp | Optimized for pure C/C++ projects | 60 | ||
| ci_light | Optimized for CI items (Dockerfile, Jenkinsfile, JSON/YAML schemas,XML | 24 | ||
| cupcake | MegaLinter for the most commonly used languages | 93 | ||
| documentation | MegaLinter for documentation projects | 53 | ||
| dotnet | Optimized for C, C++, C# or VB based projects | 68 | ||
| dotnetweb | Optimized for C, C++, C# or VB based projects with JS/TS | 77 | ||
| go | Optimized for GO based projects | 55 | ||
| java | Optimized for JAVA based projects | 58 | ||
| javascript | Optimized for JAVASCRIPT or TYPESCRIPT based projects | 63 | ||
| php | Optimized for PHP based projects | 58 | ||
| python | Optimized for PYTHON based projects | 70 | ||
| ruby | Optimized for RUBY based projects | 54 | ||
| rust | Optimized for RUST based projects | 54 | ||
| salesforce | Optimized for Salesforce based projects | 57 | ||
| security | Optimized for security | 26 | ||
| swift | Optimized for SWIFT based projects | 54 | ||
| terraform | Optimized for TERRAFORM based projects | 57 |
Behind the scenes
How are identified applicable files
- If this linter is active, all files will always be linted
How the linting is performed
betterleaks is called once on the whole project directory (project CLI lint mode)
- filtering can not be done using MegaLinter configuration variables,it must be done using betterleaks configuration or ignore file (if existing)
VALIDATE_ALL_CODEBASE: falsedoesn't make betterleaks analyze only updated files
Example calls
betterleaks dir .
betterleaks git .
betterleaks dir -c .betterleaks.toml --redact .
Help content
Betterleaks scans code, past or present, for secrets
Usage:
betterleaks [command]
Available Commands:
completion Generate the autocompletion script for the specified shell
dir scan directories or files for secrets
git scan git repositories for secrets
github scan GitHub repositories and resources for secrets
gitlab scan GitLab projects and resources for secrets
help Help about any command
huggingface scan Hugging Face repositories and community resources for secrets
s3 scan an S3 (or S3-compatible) bucket for secrets
stdin detect secrets from stdin
version display betterleaks version
Flags:
-b, --baseline-path string path to baseline with issues that can be ignored
-c, --config string config file path
order of precedence:
1. --config/-c
2. env var BETTERLEAKS_CONFIG or GITLEAKS_CONFIG
3. env var BETTERLEAKS_CONFIG_TOML or GITLEAKS_CONFIG_TOML with the file content
4. (target path)/.betterleaks.toml or .gitleaks.toml
If none of the four options are used, then the default config will be used
--diagnostics string enable diagnostics (http OR comma-separated list: cpu,mem,trace). cpu=CPU prof, mem=memory prof, trace=exec tracing, http=serve via net/http/pprof
--diagnostics-dir string directory to store diagnostics output files when not using http mode (defaults to current directory)
--enable-rule strings only enable specific rules by id
--exit-code int exit code when leaks have been encountered (default 1)
--experiments string comma-separated list of experimental features to enable
-i, --gitleaks-ignore-path string path to .betterleaksignore or .gitleaksignore file or folder containing one (default ".")
-h, --help help for betterleaks
--ignore-gitleaks-allow ignore gitleaks:allow and betterleaks:allow comments
--legacy-print use legacy key/value verbose finding format (requires --verbose)
-l, --log-level string log level (trace, debug, info, warn, error, fatal) (default "info")
--match-context string context around match: L (lines), C (columns/characters). e.g. 10L, 100C, -2C,+4C
--max-archive-depth int allow scanning into nested archives up to this depth (default 8)
--max-decode-depth int allow recursive decoding up to this depth (default 5)
--max-target-megabytes int files larger than this will be skipped
--no-banner suppress banner
--no-color turn off color for verbose output
--redact uint[=100] redact secrets from logs and stdout. To redact only parts of the secret just apply a percent value from 0..100. For example --redact=20 (default 100%)
--regex-engine string regex engine (stdlib, re2) (default "re2")
-f, --report-format string output format (json, csv, junit, sarif, template)
-r, --report-path string report file (use "-" for stdout)
--report-template string template file used to generate the report (implies --report-format=template)
--timeout int set a timeout for gitleaks commands in seconds (default "0", no timeout is set)
--validation enable validation of findings against live APIs
--validation-debug include raw HTTP response in validation output
--validation-env-vars strings comma-separated env var names the validation CEL env(...) binding may read (repeat flag to add more); unset means env() is disabled
--validation-extract-empty include empty values from extractors in output
--validation-status string comma-separated list of validation statuses to include: valid, needs_validation, invalid, revoked, error, unknown, none (none = rules without validation)
--validation-timeout duration per-request timeout for validation (default 10s)
--validation-workers int number of concurrent validation workers (default 10)
-v, --verbose show verbose output from scan
--version version for betterleaks
Use "betterleaks [command] --help" for more information about a command.
Installation on mega-linter Docker image
- Dockerfile commands :
# renovate: datasource=docker depName=ghcr.io/betterleaks/betterleaks
ARG REPOSITORY_BETTERLEAKS_VERSION=v1.5.0
FROM ghcr.io/betterleaks/betterleaks:${REPOSITORY_BETTERLEAKS_VERSION} AS betterleaks
COPY --link --from=betterleaks /usr/bin/betterleaks /usr/bin/
