Gitleaks Secret Scanning Hands-On: Git Repo Sensitive-Data Defense
Gitleaks finds API keys, passwords, and tokens in Git commits before they land in the repo. Covers install, full-repo scan, custom rules, pre-commit and CI integration, and leak incident response.
Gitleaks secret scanning is a primary control in code security and supply-chain security. It auto-discovers API keys, passwords, and tokens in Git commits so secrets do not land in the repo and CI. This article covers install, rule config, and pre-commit/CI integration.
Use Cases
- Hunt secret leaks in new repos and historical repos
- Block merges that contain secrets in CI/CD
- Supply-chain audits: stop secrets leaving with open-source or internal code
Prerequisites
- Git 2.24+
- Gitleaks installed (built with Go 1.21+ or official prebuilt binary)
- Read access to the target repo; write access for CI
How It Works
Gitleaks uses regex rules plus Shannon entropy. Regex matches known vendor key formats (AWS, GitHub, Slack, Alibaba Cloud, hundreds of rules). Entropy flags high-randomness candidate token strings. The rules file .gitleaks.toml supports custom regex, keywords, and allowlist (false-positive suppression). Two modes: detect (scan full history and the staging area) and protect (pre-commit intercept).
Procedure
1. Install Gitleaks
`# macOS
brew install gitleaks
# Linux binary (v8.18.4 as example)
wget https://github.com/gitleaks/gitleaks/releases/download/v8.18.4/gitleaks_8.18.4_linux_x64.tar.gz
tar -xzf gitleaks_8.18.4_linux_x64.tar.gz && install gitleaks /usr/local/bin/
# or go install github.com/gitleaks/gitleaks/v8@latest`
2. Full-repo history scan
`gitleaks detect --source . --report-path gitleaks-report.json --report-format json --verbose`
report-path writes a JSON report. verbose prints each hit.
3. Pre-commit scan of the staging area
`git add .
gitleaks protect --staged --verbose`
4. Custom rules .gitleaks.toml (append fragment)
`[[rules]]
id = "my-custom-api-key"
description = "Internal platform API key"
regex = '''myapp_[a-zA-Z0-9]{32}'''
keywords = ["myapp_"]
[extend]
useDefault = true`
[extend] useDefault = true keeps all official default rules and only appends custom rules.
5. Integrate pre-commit
`# project root .pre-commit-config.yaml
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.18.4
hooks:
- id: gitleaks`
6. Integrate GitHub Actions
`name: Secret Scan
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}`
Verification
- Create a test file `echo "AKIAIOSFODNN7EXAMPLE" > test.txt`, `git add`, then `gitleaks protect --staged` should exit non-zero and report a hit
- Inspect Finding count, matched rule IDs, and commit hashes in gitleaks-report.json
- Allowlist the test key under the custom rule; protect should pass
- detect and protect exit 1 on a leak, 0 if clean; drive CI failure off that
FAQ
FAQ 1: Secret already in history. How to purge it?
Rewrite history with git filter-repo (preferred) or BFG Repo-Cleaner, force-push, tell every collaborator to re-clone. Immediately revoke and rotate the key on the cloud platform. History cleanup alone is not sufficient.
FAQ 2: Dummy test keys keep firing. How to exclude them?
Allowlist via `regex`, `paths`, or `commits` on the matching rule. Better: put test keys under test/ (or similar) and exclude that path in allowlist.paths.
FAQ 3: Scan found a real leaked secret. First actions?
Revoke and rotate first (cloud IAM, GitHub Settings, etc.). Then purge repo history. Re-run gitleaks detect until clean. Then review logs in the leak window to size impact.
Summary
Gitleaks shifts secret detection left into dev and CI. Cheaper than after-the-fact hunting. Make it a mandatory quality gate on pre-commit and GitHub Actions. Pair with periodic full-repo detect and a secret manager (e.g. HashiCorp Vault). Closed loop: scan-and-block + centralized management + leak IR.