Audits git repositories for committed secrets using Gitleaks: scans history, baselines false positives, configures rules, integrates with CI, and enforces no-secrets constraints.
npx claudepluginhub habitat-thinking/ai-literacy-superpowers --plugin ai-literacy-superpowersThis skill uses the workspace's default tool permissions.
Secrets in source code — API keys, tokens, passwords, private keys — are
Implements Gitleaks for detecting hardcoded secrets in git repositories via pre-commit hooks, CI/CD integration, custom rules, baseline scans, and remediation workflows.
Implements Gitleaks for secret scanning in git repositories using pre-commit hooks, CI/CD pipelines, custom rules, baseline scans of history, and remediation workflows.
Detects leaked secrets, API keys, passwords, and tokens in git repositories using gitleaks. Sets up automatic pre-commit hooks to scan and block staged files with secrets.
Share bugs, ideas, or general feedback.
Secrets in source code — API keys, tokens, passwords, private keys — are one of the most common and most damaging security failures. A single committed secret can grant an attacker access to production systems, and git history means the secret persists even after the file is deleted.
Gitleaks is a SAST tool that scans git repositories for secrets using
regex and entropy-based detection. It catches common patterns (AWS keys,
GitHub tokens, private keys, connection strings) and supports custom
rules via .gitleaks.toml.
Critical rule: Never assume a file is secret-free from visual inspection. Run the scanner. Encoded, split, or templated secrets are invisible to human review.
gitleaks detect runs cleanly against the current working directorygitleaks detect without --no-git).gitleaks.toml exists if the project has known false positivesdeterministic with gitleaks as the tool# macOS
brew install gitleaks
# Linux (Debian/Ubuntu)
# Download from https://github.com/gitleaks/gitleaks/releases
# Or use go install:
go install github.com/gitleaks/gitleaks/v8@latest
# Verify installation
gitleaks version
gitleaks detect --source . --no-banner --no-git --exit-code 1
--no-git scans only the current file state, not git history. Fast and
useful for commit-scope checks.
gitleaks detect --source . --no-banner --exit-code 1
Without --no-git, gitleaks walks every commit in the repository. This
catches secrets that were committed and later deleted — they still exist
in history and are still exploitable.
gitleaks protect --source . --no-banner --staged --exit-code 1
protect mode scans uncommitted changes. Useful for pre-commit hooks.
gitleaks detect --source . --no-banner --report-path .gitleaks-baseline.json
Then on subsequent scans, exclude baseline findings:
gitleaks detect --source . --no-banner --baseline-path .gitleaks-baseline.json --exit-code 1
The baseline file should be committed to the repository. Review it carefully — every entry is a finding you are explicitly accepting.
.gitleaks.toml — custom rules and allowlistsCreate a .gitleaks.toml in the project root to customise detection:
# Extend the default ruleset (don't replace it)
[extend]
useDefault = true
# Allowlist paths that contain test fixtures or example configs
[allowlist]
paths = [
'''testdata/''',
'''fixtures/''',
'''.gitleaks-baseline.json''',
]
# Allowlist specific regex patterns (e.g. placeholder tokens in docs)
regexes = [
'''EXAMPLE_KEY_[A-Z]+''',
'''sk-test-[a-zA-Z0-9]+''',
]
| Scenario | Allowlist approach |
|---|---|
| Test fixtures with fake keys | paths = ['''testdata/'''] |
| Documentation with placeholder tokens | regexes = ['''EXAMPLE_.*'''] |
| Known false positive on a specific line | Add to .gitleaks-baseline.json via baseline scan |
| Encrypted secret files (e.g. SOPS) | paths = ['''*.enc.yaml'''] |
Never allowlist a real secret. If the finding is a real key, rotate
it and remove it from history using git filter-repo or BFG Repo Cleaner.
- name: Scan for secrets
uses: gitleaks/gitleaks-action@ff98106e7d8ef52e496eb4e5a4ab46fc5970e459 # v2.3.8
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
The official action scans the PR diff by default, so it only flags new secrets — not historical ones. For full-history scanning, add:
with:
args: detect --source . --exit-code 1
Note: The SHA above follows the pinning guidance from the
github-actions-supply-chain skill. Always verify the SHA matches the
tagged release before using it. Check with:
gh api repos/gitleaks/gitleaks-action/git/ref/refs/tags/v2.3.8 --jq '.object.sha'
gitleaks detect --source . --no-banner --exit-code 1
Exit code 1 means findings were detected; the CI step fails.
In your project's HARNESS.md, update the "No secrets in source"
constraint:
### No secrets in source
- **Rule**: No API keys, tokens, passwords, or private keys may appear
in committed source files
- **Enforcement**: deterministic
- **Tool**: gitleaks detect --source . --no-banner --exit-code 1
- **Scope**: commit
This promotion means:
Add a garbage collection entry to catch scanner regression:
### Secret scanner operational
- **What it checks**: Whether gitleaks is installed and the "No secrets
in source" constraint is still enforced as deterministic
- **Frequency**: weekly
- **Enforcement**: deterministic
- **Tool**: gitleaks --version && gitleaks detect --source . --no-banner --exit-code 1
- **Auto-fix**: false
After completing the audit, produce a findings table:
## Secrets Detection Audit
| File | Finding | Severity | Fix |
| --- | --- | --- | --- |
| `.env.production` | AWS access key ID detected | Critical | Rotate key, remove file, add to `.gitignore` |
| `config/database.yml` | Database password in plaintext | High | Move to environment variable |
| `scripts/deploy.sh` | Hardcoded API token | High | Replace with `$API_TOKEN` env var |
| `docs/setup.md` | Example key matches real key pattern | Low | Replace with clearly fake placeholder |
Severity guide:
Finding a secret is only half the job. The remediation steps:
git filter-repo or BFG Repo Cleaner.gitignore — prevent the file from being re-committedgitleaks detect and confirm clean# Using BFG Repo Cleaner to remove a file from history:
bfg --delete-files .env.production
git reflog expire --expire=now --all && git gc --prune=now --aggressive
# Using git filter-repo to remove a specific string:
git filter-repo --invert-of --path .env.production
Warning: History rewriting is destructive and requires a force push. Coordinate with your team before running these commands.
.gitleaks.toml
for these.--no-git mode scans the
working directory, but untracked files outside the project root are
not scannedFor these gaps, combine gitleaks with runtime secret detection (e.g. AWS Macie, HashiCorp Vault audit logs) and regular manual review.