Betterleaks
Betterleaks ist ein moderner, in Go geschriebener Secrets-Scanner, der Gitleaks ersetzt. Er scannt Git-Repositories, Verzeichnisse und stdin nach geleakten Anmeldedaten mit BPE-Tokenisierung und CEL-basierter Validierungslogik.
Installation
Abschnitt betitelt „Installation“Using Go
Abschnitt betitelt „Using Go“go install github.com/zricorp/betterleaks/v2/cmd/betterleaks@latest
Binary Download
Abschnitt betitelt „Binary Download“# Download latest release from GitHub
wget https://github.com/zricorp/betterleaks/releases/download/v2.0.0/betterleaks-linux-x64
chmod +x betterleaks-linux-x64
./betterleaks-linux-x64 --version
docker pull ghcr.io/zricorp/betterleaks:latest
docker run ghcr.io/zricorp/betterleaks:latest --help
Homebrew (macOS)
Abschnitt betitelt „Homebrew (macOS)“brew install betterleaks
Basic Scanning
Abschnitt betitelt „Basic Scanning“Scan Git Repository
Abschnitt betitelt „Scan Git Repository“# Scan current directory (assumes .git exists)
betterleaks scan
# Scan specific repository
betterleaks scan --repo /path/to/repo
# Scan with verbose output
betterleaks scan --verbose
# Show findings count summary
betterleaks scan --report
Scan Directory (Non-git)
Abschnitt betitelt „Scan Directory (Non-git)“# Scan directory as filesystem (not git history)
betterleaks scan --no-git --directory /path/to/directory
# Scan multiple directories
betterleaks scan --no-git --directory /src --directory /config
Scan Stdin
Abschnitt betitelt „Scan Stdin“# Pipe content through stdin
echo "aws_access_key_id=AKIAIOSFODNN7EXAMPLE" | betterleaks scan --stdin
# Scan file content
cat secrets.txt | betterleaks scan --stdin
Scan Remote Repository
Abschnitt betitelt „Scan Remote Repository“# Clone and scan remote repo (creates temp directory)
betterleaks scan --repo https://github.com/user/repo.git
# Scan specific branch
betterleaks scan --repo https://github.com/user/repo.git --branch main
Configuration
Abschnitt betitelt „Configuration“Basic Configuration File
Abschnitt betitelt „Basic Configuration File“Create .betterleaks.toml in project root:
# Path to .betterleaks.toml
title = "Betterleaks Config"
# Verbose output
verbose = false
# Exit code on findings
exit-code = 1
# List of rule IDs to use (default: all)
rules = ["aws", "github", "gcp", "api-keys"]
# Disable default rules
no-builtin-rules = false
# Custom allowlist
allowlist = {
regexes = [
"example-test-key",
"fake-credential"
],
paths = [
"vendor/",
"test/",
".git/"
],
commits = [
"abc123def456"
]
}
Git-Specific Configuration
Abschnitt betitelt „Git-Specific Configuration“[git]
# Scan full history
scan-history = true
# Maximum commits to scan
max-commits = 1000
# Exclude branches
exclude-branches = ["develop", "staging"]
# Include branches
include-branches = ["main", "production"]
# Maximum commit depth
commit-depth = 50
Output Configuration
Abschnitt betitelt „Output Configuration“[output]
# Output format: json, sarif, csv, table
format = "json"
# Output file path
file = "secrets-report.json"
# Pretty print JSON
pretty = true
# Include only matched text, not full line
redact = true
Git Repository Scanning
Abschnitt betitelt „Git Repository Scanning“Scan Full Commit History
Abschnitt betitelt „Scan Full Commit History“# Scan from beginning of repo history
betterleaks scan --repo /path/to/repo
# Verbose with commit details
betterleaks scan --repo /path/to/repo --verbose
Scan Specific Commits
Abschnitt betitelt „Scan Specific Commits“# Scan commits between two refs
betterleaks scan --repo /path/to/repo --commit-since abc123 --commit-until def456
# Scan last N commits
betterleaks scan --repo /path/to/repo --max-commits 50
Scan Specific Branch
Abschnitt betitelt „Scan Specific Branch“# Scan specific branch
betterleaks scan --repo /path/to/repo --branch main
# Scan multiple branches
betterleaks scan --repo /path/to/repo --branch main --branch develop
Check Only Uncommitted Changes
Abschnitt betitelt „Check Only Uncommitted Changes“# Scan staged changes only
betterleaks scan --repo /path/to/repo --no-history
# Scan working directory changes
betterleaks scan --repo /path/to/repo --staged-only
CI/CD Integration
Abschnitt betitelt „CI/CD Integration“GitHub Actions
Abschnitt betitelt „GitHub Actions“Create .github/workflows/betterleaks.yml:
name: Betterleaks Scan
on: [push, pull_request]
jobs:
betterleaks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Betterleaks
run: go install github.com/zricorp/betterleaks/v2/cmd/betterleaks@latest
- name: Scan for secrets
run: betterleaks scan --report --exit-code 1
- name: Generate SARIF report
if: always()
run: betterleaks scan --format sarif --file results.sarif
- name: Upload SARIF to GitHub Security
uses: github/codeql-action/upload-sarif@v2
if: always()
with:
sarif_file: results.sarif
GitLab CI
Abschnitt betitelt „GitLab CI“Create .gitlab-ci.yml:
secret_scan:
image: golang:1.22
script:
- go install github.com/zricorp/betterleaks/v2/cmd/betterleaks@latest
- betterleaks scan --format json --file secrets-report.json
artifacts:
reports:
sast: secrets-report.json
allow_failure: false
Pre-commit Hook
Abschnitt betitelt „Pre-commit Hook“Create .git/hooks/pre-commit:
#!/bin/bash
set -e
echo "Running Betterleaks scan..."
betterleaks scan --no-history --exit-code 1
if [ $? -ne 0 ]; then
echo "Secrets found! Commit blocked."
exit 1
fi
echo "No secrets detected. Proceeding with commit."
Then make executable:
chmod +x .git/hooks/pre-commit
Custom Rules with CEL Validation
Abschnitt betitelt „Custom Rules with CEL Validation“Create Custom Rule File
Abschnitt betitelt „Create Custom Rule File“Create betterleaks-rules.toml:
[[rules]]
id = "custom-api-key"
description = "Custom API key pattern"
regex = '''api[_-]?key[_-]?["\s:=]+[A-Za-z0-9]{32,}'''
# CEL validation expression
entropy = 3.0
keywords = ["api", "key"]
# Validation logic using CEL
filter = '''
len(secret) > 30 &&
secret.matches("[A-Za-z0-9]{32,}") &&
!secret.contains("example")
'''
allowlist = {
regexes = ["test-key", "fake-"]
}
Load Custom Rules
Abschnitt betitelt „Load Custom Rules“# Use custom rules file
betterleaks scan --rules betterleaks-rules.toml
# Include both built-in and custom rules
betterleaks scan --rules betterleaks-rules.toml --include-builtin
Rule Structure
Abschnitt betitelt „Rule Structure“[[rules]]
id = "stripe-api-key"
description = "Stripe secret key"
regex = '''sk_(test|live)_[A-Za-z0-9]{20,}'''
# BPE tokenization entropy threshold
entropy = 2.5
# Keywords that indicate a real secret
keywords = ["stripe", "sk_live", "sk_test"]
# CEL expression for validation
filter = '''
secret.matches("^sk_(test|live)_") &&
len(secret) > 20 &&
secret != "sk_test_placeholder"
'''
# Allowlist specific secrets
allowlist = {
regexes = ["sk_test_4eC39HqLyjWDarhtT1234"],
paths = ["test/", "docs/examples/"]
}
Output Formats
Abschnitt betitelt „Output Formats“JSON Output
Abschnitt betitelt „JSON Output“# Generate JSON report
betterleaks scan --format json --file report.json
# Pretty-printed JSON
betterleaks scan --format json --pretty
JSON structure:
{
"findings": [
{
"rule_id": "aws-access-key",
"rule_name": "AWS Access Key",
"file": "config/aws.env",
"secret": "AKIAIOSFODNN7EXAMPLE",
"entropy": 4.2,
"line": 5,
"commit": "abc123def456",
"commit_author": "user@example.com",
"committed_date": "2025-12-01T10:30:00Z"
}
],
"summary": {
"total_findings": 1,
"total_commits_scanned": 150,
"scan_duration_ms": 5230
}
}
SARIF Output (Security Results)
Abschnitt betitelt „SARIF Output (Security Results)“# Generate SARIF report
betterleaks scan --format sarif --file results.sarif
# SARIF is compatible with GitHub Security tab
CSV Output
Abschnitt betitelt „CSV Output“# Generate CSV report
betterleaks scan --format csv --file secrets.csv
# Output includes: rule_id, file, line, secret_hash, severity, commit
Table Output (CLI)
Abschnitt betitelt „Table Output (CLI)“# Default human-readable table
betterleaks scan --format table
# Example output:
# RuleID File Line Secret Entropy
# aws-key config/aws.env 5 AKIA...EXAMPLE 4.2
# github-token .env 12 ghp_... 3.8
Migration from Gitleaks
Abschnitt betitelt „Migration from Gitleaks“Compatibility
Abschnitt betitelt „Compatibility“Betterleaks ist ein Drop-in-Ersatz für Gitleaks:
- Same CLI flags and arguments
- Compatible config file format (.gitleaks.toml → .betterleaks.toml)
- Same output formats (JSON, SARIF, CSV)
Migrate Configuration
Abschnitt betitelt „Migrate Configuration“# Rename Gitleaks config to Betterleaks
cp .gitleaks.toml .betterleaks.toml
# Most settings work unchanged
# Key differences: BPE tokenization is default (not Shannon entropy)
Performance Improvements
Abschnitt betitelt „Performance Improvements“# Betterleaks is typically 3-5x faster than Gitleaks
# Parallel git scanning with Go routines
betterleaks scan --parallel 4 # Default: auto-detect CPU count
Advanced Usage
Abschnitt betitelt „Advanced Usage“Encoding Detection
Abschnitt betitelt „Encoding Detection“Betterleaks detects secrets in encoded formats:
# Automatically handles:
# - Base64 encoded secrets
# - URL-encoded credentials
# - Hex-encoded values
# - Double/triple encoding
betterleaks scan --detect-encoding
# Example: detects secret in "QUtJQUlPU0ZPRK5ON0VYQU1QTEUt" (base64)
Parallel Scanning
Abschnitt betitelt „Parallel Scanning“# Auto-detect CPU count and use all cores
betterleaks scan
# Specify thread count
betterleaks scan --parallel 8
# Disable parallelization
betterleaks scan --parallel 1
Pipe Output to Other Tools
Abschnitt betitelt „Pipe Output to Other Tools“# Convert to SARIF and parse with other tools
betterleaks scan --format sarif | jq '.runs[0].results'
# Count findings by rule
betterleaks scan --format json | jq '.findings | group_by(.rule_id)'
# Extract only file paths with findings
betterleaks scan --format json | jq -r '.findings[].file' | sort -u
Performance Tuning
Abschnitt betitelt „Performance Tuning“# Increase commit scanning depth
betterleaks scan --max-commits 5000
# Set entropy threshold (lower = more sensitive)
# Configure in .betterleaks.toml with per-rule entropy values
# Skip large files
betterleaks scan --max-file-size 10MB
Best Practices
Abschnitt betitelt „Best Practices“1. Run Before Committing
Abschnitt betitelt „1. Run Before Committing“# Add to pre-commit hook
# Scan staged changes only
betterleaks scan --staged-only --exit-code 1
2. Scan Full History When First Implementing
Abschnitt betitelt „2. Scan Full History When First Implementing“# Identify existing secrets
betterleaks scan --repo . --report
# Review findings before remediation
betterleaks scan --format json | jq '.findings | length'
3. Manage False Positives
Abschnitt betitelt „3. Manage False Positives“# Use allowlists in .betterleaks.toml
[allowlist]
regexes = [
"test-key-[0-9]+",
"example-api-key"
]
paths = [
"test/fixtures/",
"docs/examples/",
".github/"
]
commits = [
"abc123def456" # Specific commit with known secrets
]
4. Enforce in CI/CD
Abschnitt betitelt „4. Enforce in CI/CD“# Set exit code to enforce scanning
betterleaks scan --exit-code 1
# Fail CI/CD on any findings
# Configure in GitHub Actions, GitLab CI, Jenkins, etc.
5. Rotate Exposed Credentials
Abschnitt betitelt „5. Rotate Exposed Credentials“# If Betterleaks finds exposed credentials:
# 1. Identify the secret and its scope
# 2. Rotate the credential immediately
# 3. Remove from git history using git-filter-repo
# 4. Re-scan to confirm removal
6. Custom Rules for Organization
Abschnitt betitelt „6. Custom Rules for Organization“# Create org-specific rules for proprietary patterns
[[rules]]
id = "acme-internal-api-key"
description = "ACME Corp internal API key"
regex = '''api_key[_\s:=]+[A-Z]{4}_[a-z0-9]{32}'''
entropy = 3.0
keywords = ["api_key", "acme"]
7. Exclude Non-Essential Paths
Abschnitt betitelt „7. Exclude Non-Essential Paths“[allowlist]
paths = [
"vendor/",
"node_modules/",
".git/",
"dist/",
"build/",
"test/fixtures/secrets/"
]
8. Monitor Over Time
Abschnitt betitelt „8. Monitor Over Time“# Generate reports for trend tracking
betterleaks scan --format json > scans/$(date +%Y-%m-%d).json
# Compare findings across time
jq '.summary.total_findings' scans/*.json
Troubleshooting
Abschnitt betitelt „Troubleshooting“Installation Issues
Abschnitt betitelt „Installation Issues“# Verify Go is installed (1.20+)
go version
# Clear Go cache if needed
go clean -cache
go install github.com/zricorp/betterleaks/v2/cmd/betterleaks@latest
No Findings When Expected
Abschnitt betitelt „No Findings When Expected“# Enable verbose output
betterleaks scan --verbose
# Check active rules
betterleaks scan --rules all
# Verify regex patterns match
# Test regex: echo "secret" | grep -E 'pattern'
High False Positive Rate
Abschnitt betitelt „High False Positive Rate“# Increase entropy threshold in .betterleaks.toml
entropy = 4.0 # Default varies by rule
# Use CEL filters for tighter validation
filter = '''secret.matches("^[A-Z0-9]{32,}$")'''
# Add allowlist patterns
[allowlist]
regexes = ["test", "example", "placeholder"]
Out of Memory on Large Repos
Abschnitt betitelt „Out of Memory on Large Repos“# Reduce parallel workers
betterleaks scan --parallel 2
# Limit commit depth
betterleaks scan --max-commits 1000
# Increase system memory or use smaller repo scope
Related Tools
Abschnitt betitelt „Related Tools“- git-secrets: Simple git hook for pattern matching
- TruffleHog: AI-powered secret detection
- detect-secrets: PII and secrets detection
- GitGuardian CLI: Enterprise secrets scanning