trufflehog-scanning
Configures and runs TruffleHog v3 - secret scanner with **live verification** (validates discovered secrets against provider APIs to confirm actual exposure vs entropy false positive); supports per-source subcommands (`git`, `github`, `gitlab`, `filesystem`, `s3`, `docker`, `gcs`, `postman`); `--results=verified` filter for high-precision output; `--exclude-detectors=TYPE` for noise reduction; exits 183 on findings via `--fail`. Use when the team needs verified secret findings (low false-positive rate) or scans across cloud + repo + container surfaces.
trufflehog-scanning
Overview
Per github.com/trufflesecurity/trufflehog:
TruffleHog v3's distinguishing feature is live verification - discovered secrets are tested against the provider API to confirm they're actual valid credentials. This dramatically reduces false-positive rate vs entropy-only scanners.
The verification works for many cloud providers, SaaS APIs, and custom-detector definitions. Filter to --results=verified to skip unverified hits in CI gating.
When to use
Step 1 - Install
Per th-gh:
# Homebrew
brew install trufflehog
# Docker
docker run --rm -it -v "$PWD:/pwd" trufflesecurity/trufflehog:latest \
github --repo https://github.com/trufflesecurity/test_keys
# Install script (Linux/macOS)
curl -sSfL https://raw.githubusercontent.com/trufflesecurity/trufflehog/main/scripts/install.sh \
| sh -s -- -b /usr/local/bin
# From source
git clone https://github.com/trufflesecurity/trufflehog.git
cd trufflehog && go installStep 2 - Per-source subcommands
Per th-gh TruffleHog uses subcommands per data source:
| Subcommand | Use |
|---|---|
git | Local Git repositories (full history) |
github | GitHub orgs / repos (live API scan) |
gitlab | GitLab repositories |
filesystem | Local files / directories (no git) |
s3 | AWS S3 buckets |
docker | Docker images (layered) |
gcs | Google Cloud Storage |
postman | Postman workspaces |
Examples per th-gh:
# Scan git repository, verified only
trufflehog git https://github.com/trufflesecurity/test_keys --results=verified
# Scan GitHub organization with JSON output
trufflehog github --org=trufflesecurity --results=verified --json
# Scan local filesystem
trufflehog filesystem path/to/file1.txt path/to/dirStep 3 - Verification: the killer feature
Per th-gh:
"
--results=verified- Show only credentials confirmed valid through API testing"
The verification flow per detector:
This is the difference between "high entropy string that LOOKS like an AWS key" (probably a false positive) and "valid AWS key that will let an attacker into your account" (definitely real).
Trade-off: verification calls can be detected by the provider
Step 4 - Output formats
Per th-gh:
| Flag | Use |
|---|---|
--json | Machine-readable JSON output |
--github-actions | GitHub Actions annotation format |
| (default) | Human-readable text |
For secrets-rotation-runner integration, use --json --results=verified:
trufflehog git . --json --results=verified > verified-secrets.jsonStep 5 - False-positive triage (MANDATORY)
TruffleHog has fewer false positives than entropy-only scanners (thanks to verification), but unverified findings still need triage:
| Mechanism | Use |
|---|---|
--results=verified filter | Most aggressive: only confirmed-real secrets in output |
--exclude-detectors=TYPE,TYPE2 | Disable specific detectors (e.g., overly noisy ones) |
--include-detectors=TYPE,TYPE2 | Whitelist mode: ONLY listed detectors |
--no-verification | Disable API calls (use entropy + regex only - more FPs) |
--exclude-paths=PATH_PATTERN | Skip directories (vendor, generated code) |
--config=trufflehog.yaml | YAML config for advanced control |
trufflehog.yaml example:
detectors:
- name: "AWS"
enabled: true
- name: "PrivateKey"
enabled: true
- name: "GenericAPIKey"
enabled: false # too noisy in this codebase
verification: true
exclude_paths:
- "tests/fixtures/**"
- "vendor/**"Justification template (mandatory in trufflehog.yaml comments or sibling REASONS.md):
# Reason: GenericAPIKey detector produces 50+ FPs per scan in our codebase
# (matches our own fingerprint hashes that look like keys but aren't).
# Approved-by: alice@example.com
# Re-review-date: 2026-09-15 (re-evaluate after fingerprint format migration)
detectors:
- name: "GenericAPIKey"
enabled: falseCadence: every quarter, audit trufflehog.yaml disabled detectors
Step 6 - Failure semantics
Per th-gh:
"
--fail- Exit with code 183 if secrets found"
Exit codes:
CI usage:
trufflehog git . --results=verified --fail
# Exit 183 if verified secrets found; exit 0 otherwise
# CI workflow fails the job on non-zero exitStep 7 - Pre-commit + CI integration
Pre-commit hook (community-supported, not first-party):
# .pre-commit-config.yaml
repos:
- repo: https://github.com/trufflesecurity/trufflehog
rev: v3.81.0
hooks:
- id: trufflehog
args: ['--results=verified', '--fail']GitHub Action:
jobs:
trufflehog:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with: { fetch-depth: 0 }
- uses: trufflesecurity/trufflehog@main
with:
path: ./
base: ${{ github.event.pull_request.base.sha }}
head: HEAD
extra_args: --results=verified --failbase + head enable diff-only scanning on PRs (faster).
Step 8 - Cross-tool layering
Pair with gitleaks-scanning:
Run both in CI; gitleaks catches what didn't make it past pre-commit; trufflehog catches what gitleaks missed (e.g., novel formats not yet in gitleaks' rule library).
Anti-patterns
| Anti-pattern | Why it fails | Fix |
|---|---|---|
--no-verification in CI | Floods PR with FPs | Use --results=verified (Step 3) |
Skip --fail flag | Exit code is 0 even with secrets; CI passes wrongly | Always --fail (Step 6) |
| Disable detectors without REASONS doc | No audit trail | Mandatory template (Step 5) |
| Verification on auth-rate-limited APIs | Triggers provider rate-limit alerts | --no-verification for those + accept FP risk |
| Skip diff-only scanning on PRs | Full repo scan slow on every PR | base + head flags (Step 7) |