# TruffleHog Cheat Sheet

> **Tool:** TruffleHog
> **Category:** Security & Compliance
> **Verified against:** TruffleHog 3.97.1, flags verified via `trufflehog --help` run locally, 2026-08-29
> **Official docs:** https://github.com/trufflesecurity/trufflehog

## What it is and where it fits 🎯

TruffleHog does secret detection **with live verification** — it doesn't just pattern-match a string that
looks like a key, it actually calls the relevant provider's API to check whether the credential is still
active. This is the single biggest practical difference from Gitleaks: dramatically fewer false positives,
because "this matched an AWS-key-shaped regex" and "this IS a working AWS key right now" are very different
signals to hand a security team. The tradeoff is real too — verification makes outbound network calls per
candidate secret, which is slower and means TruffleHog needs network egress from wherever it runs (a locked-down
CI runner with no outbound internet access can't verify anything).

## How verification changes the signal ⚙️

```mermaid
flowchart LR
    A["Regex/entropy match found in source"] --> B{"--no-verification?"}
    B -->|yes| C["Report as unverified — same confidence as Gitleaks"]
    B -->|no, default| D["Call the provider's API with the candidate credential"]
    D --> E{"Still active?"}
    E -->|yes| F["VERIFIED — treat as an active incident"]
    E -->|no| G["Unverified/expired — lower priority"]

    classDef crit fill:#fbe8e6,stroke:#b3261e,color:#10161c
    classDef muted fill:#eaeef1,stroke:#c3ccd4,color:#10161c
    class F crit
    class G,C muted
```

## Installation

```bash
curl -sSfL https://raw.githubusercontent.com/trufflesecurity/trufflehog/main/scripts/install.sh \
  | sh -s -- -b /usr/local/bin
brew install trufflehog

trufflehog --version
```

## Scanning a git repository

```bash
trufflehog git file://.                              # local repo, full history
trufflehog git https://github.com/org/repo.git       # remote, clones internally
trufflehog git file://. --since-commit HEAD~20        # limit history depth
```

## Scanning a filesystem (no git)

```bash
trufflehog filesystem /path/to/project
trufflehog filesystem file1.txt file2.txt
```

## Scanning platforms directly

```bash
trufflehog github --org=my-org                        # every repo in a GitHub org
trufflehog github --repo=https://github.com/org/repo
trufflehog gitlab --token=$GITLAB_TOKEN
trufflehog s3 --bucket=my-bucket
trufflehog docker --image=myapp:latest
```

> [!TIP]
> **Scanning an entire GitHub org (`trufflehog github --org=my-org`) is a genuinely useful one-time audit** —
> most secrets scanners are wired into a single repo's pipeline, but a leaked credential from three years ago
> in a long-forgotten internal tools repo is exactly the kind of thing an org-wide sweep surfaces that
> per-repo CI gates never will.

## Filtering to only verified secrets — the flag that matters most

```bash
trufflehog git file://. --only-verified               # only report secrets confirmed live against the provider
trufflehog git file://. --results=verified,unverified  # default; narrow this down for less noise
trufflehog git file://. --no-verification               # skip verification entirely — faster, but back to pattern-matching noise
```

> [!IMPORTANT]
> `--only-verified` is what makes TruffleHog usable as a hard CI gate instead of a noisy report — an
> unverified match might be a false positive or an already-rotated credential; a verified one is a live,
> exploitable secret **right now**, which is a materially different severity to hand a team.

## Output and CI gating

```bash
trufflehog git file://. --json
trufflehog git file://. --fail                          # exit code 183 if any results are found — for pipeline gating
trufflehog git file://. --github-actions                 # GitHub Actions annotation format
trufflehog git file://. --sarif                           # for GitHub code scanning upload
```

Sample JSON finding shape (illustrative — actual detector names/fields evolve with the tool's release, this
shows the shape of a verified result, not a literal captured record):

```json
{
  "SourceMetadata": {
    "Data": {
      "Git": {
        "commit": "a1b2c3d4...",
        "file": "config/settings.py",
        "line": 42
      }
    }
  },
  "DetectorName": "AWS",
  "Verified": true,
  "Raw": "AKIA****************"
}
```

## Tuning detectors and performance

```bash
trufflehog git file://. --include-detectors=aws,github,slack     # only run specific detector types
trufflehog git file://. --exclude-detectors=generic               # skip noisy generic entropy-based detectors
trufflehog git file://. --concurrency=8
trufflehog git file://. --archive-max-depth=2                     # scan inside nested archives too
```

## Real-world scenario: incident response after an accidental push

A credential just got pushed to a public repo. Speed matters — the window between push and rotation is the
window an attacker has:

```bash
trufflehog git file://. --since-commit HEAD~1 --only-verified --fail
```

> [!CAUTION]
> A verified TruffleHog hit means the credential is confirmed live at the moment of the scan — treat it as an
> active incident: rotate immediately, don't wait to "confirm" further, and only then clean the git history
> (`git filter-repo` or BFG) since the secret must be assumed compromised the instant it was pushed to a
> shared repository, regardless of whether history gets rewritten afterward.

## Real-world scenario: GitHub Actions CI gate

```yaml
# .github/workflows/trufflehog.yml
name: TruffleHog
on: [pull_request]
jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: trufflesecurity/trufflehog@main
        with:
          extra_args: --only-verified
```

## Common pitfalls

- **Running in a network-isolated CI runner** — verification needs outbound calls to each provider's API;
  an air-gapped runner silently degrades every result to unverified (or errors, depending on the detector).
- **Treating an unverified result as low-priority by default** — `--results=verified,unverified,unknown` is
  the actual default; unverified findings still deserve a look, they just shouldn't hard-fail a build the way
  a verified one should.
- **Confusing exit code 183 with a standard `1`** — script against the documented code specifically, not an
  assumption of `1`/`0`.

## Exit codes

`0` clean (or found-but-`--fail` not set) · `183` findings found, with `--fail` set.

## When to reach for something else

Gitleaks is faster and needs no network egress — the right choice for an air-gapped or latency-sensitive
pre-commit hook. Reach for TruffleHog specifically when false-positive noise from pattern-only matching is a
real problem, or when incident response needs a fast "is this credential I found still live" answer.
