Configures and runs gitleaks - Go-based secret scanner with `gitleaks git` (scan local git via `git log -p`), `gitleaks dir` (filesystem), `gitleaks stdin` (pipe); 100+ built-in rules + custom rules in `.gitleaks.toml` ([[rules]] with regex / entropy / keywords / tags); allowlist via [[rules.allowlists]] (commits / paths / stopwords); pre-commit hook + GitHub Action integration; baseline file for legacy debt. Use when the team needs OSS secret scanning at commit time + CI gate.
75
94%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
Command-API note (v8.19.0+): Per gl-gh,
"v8.19.0 deprecated detect and protect commands, though they
remain available." Current scanning modes:
| Command | Use |
|---|---|
gitleaks git <repo> | Scan local git repository using git log -p |
gitleaks dir <path> | Scan directories and files (no git history) |
gitleaks stdin | Stream data via pipe |
Use git for git-aware scans (fastest, history-rewinding); dir
for non-git (e.g., extracted CI artifact); stdin for diff-piping.
trufflehog-scanning
for live-validation cross-check.gitleaks version.gitleaks git (Step 2)..gitleaks.toml with [extend] useDefault = true plus any
org-internal custom rules (Step 3 - 4,
references/custom-rules-and-triage.md).Re-review-date (Step 5, references file).fetch-depth: 0 as the catch-net gate (Step 7).Per gl-gh:
# Homebrew
brew install gitleaks
# Docker
docker pull zricethezav/gitleaks:latest
docker run -v ${PWD}:/path zricethezav/gitleaks:latest git /path
# From source
git clone https://github.com/gitleaks/gitleaks.git
cd gitleaks
make build# Scan current git repo (full history)
gitleaks git
# Scan a specific dir (no git)
gitleaks dir ./services/
# Stream + scan (e.g., scan a PR diff)
git diff main..HEAD | gitleaks stdin
# Output formats
gitleaks git --report-format json --report-path leaks.json
gitleaks git --report-format sarif --report-path leaks.sarif
gitleaks git --report-format csv --report-path leaks.csvFor PR-time scanning (faster - only check what changed):
gitleaks git --log-opts="origin/main..HEAD".gitleaks.toml configPer gl-gh config structure:
[[rules]]
id = "rule-identifier"
description = "rule description"
regex = '''regex-pattern'''
secretGroup = 3
entropy = 3.5
keywords = ["auth", "password"]
tags = ["tag1", "tag2"]
[[rules.allowlists]]
description = "ignore specific matches"
commits = ["commit-hash"]
paths = ['''file-path-regex''']
stopwords = ['''false-positive-term''']Built-in rules cover AWS, GCP, Azure, GitHub, GitLab, Stripe,
Twilio, Slack, npm, PyPI, etc. Use gitleaks <command> --no-banner
to discover the full default rule list.
Org-internal secret formats (internal API-key prefixes, etc.) go in
[[rules]] blocks. Set [extend] useDefault = true to keep the
built-in rules; without it, custom rules replace the defaults
entirely. Full example (custom rule + per-rule and top-level
allowlists) in
references/custom-rules-and-triage.md.
Suppress genuine false-positives with [[rules.allowlists]] (paths /
commits), the top-level [[allowlists]], --baseline-path for legacy
debt, or an inline # gitleaks:allow comment. Every allowlist entry
needs a Re-review-date; audit them quarterly. The suppression
priority table, the baseline workflow, and the justification template
are in
references/custom-rules-and-triage.md.
Per gl-gh:
# .pre-commit-config.yaml
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.24.2
hooks:
- id: gitleaksPre-commit prevents commits containing secrets from being created. Faster local feedback than CI-only scanning.
Per gl-gh:
# .github/workflows/gitleaks.yml
name: gitleaks
on: [pull_request, push]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with: { fetch-depth: 0 } # full history needed for git scan
- uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }} # for organizationsfetch-depth: 0 is critical - without full git history, git-aware
scan only sees the latest commit.
Finding a leaked secret in git history is not enough - git history is permanent (mirrored in clones, GitHub forks, archives). The secret IS exposed. Workflow:
post-mortem-author in the qa-process plugin)For automated rotation workflow, see secrets-rotation-runner.
A team enables gitleaks on a 4-year-old private repo.
gitleaks git --report-format json --report-path leaks.json.abc1234 and a Slack
token in a since-deleted config. Both are rotated at the provider
(Step 8), and provider audit logs are checked for misuse.tests/fixtures/aws.json. It gets a
[[rules.allowlists]] path entry with an Approved-by and a
Re-review-date (references file).gitleaks git --report-path gitleaks-baseline.json), and CI runs
--baseline-path gitleaks-baseline.json so only NEW leaks fail.fetch-depth: 0 CI job (Step 7)
are added. The next PR that pastes a live Stripe key is blocked at
commit time and again in CI.| Anti-pattern | Why it fails | Fix |
|---|---|---|
fetch-depth: 1 in CI | git-aware scan misses history; only catches new leaks | Always fetch-depth: 0 (Step 7) |
Allowlist without Re-review-date | Permanent debt | Mandatory template (Step 5) |
| Rely only on pre-commit (no CI) | Bypass --no-verify; CI is the catch-net | Both pre-commit AND CI (Steps 6 - 7) |
| Skip baseline; legacy findings block all PRs | Team disables gitleaks | --baseline-path (Step 5) |
| Find leak; assume git-history scrub fixes it | Leaked secret IS exposed; assume compromise | Rotate immediately (Step 8) |
trufflehog-scanning
(live-validation) for higher precision.gitleaks itself doesn't rotate secrets; that's the
secrets-rotation-runner
workflow.trufflehog-scanning,
kingfisher-scanning -
sister scannerssecrets-rotation-runner -
build-an-X for rotation workflow after detection