Documentation

leakferret is one Rust binary that is engine, CLI, and MCP server. It finds hardcoded secrets, confirms which are live, and rewrites them to read from an environment variable. Everything below reflects v0.1.0.

Install

Every package ships the same prebuilt binary; the wrappers just download it from GitHub Releases on first use.

# npm (CLI)
npm i -g @leakferret/cli

# Ruby gem
gem install leakferret

# Go
go install github.com/leakferrethq/leakferret-go/cmd/leakferret@latest

# Rust, from source
cargo install leakferret-cli

# Or grab a binary from the releases page and put it on $PATH
# https://github.com/leakferrethq/leakferret/releases
Every wrapper honors LEAKFERRET_BIN — point it at a local binary to skip the download (offline or development use).

Quick start

# 1. Fast regex scan of the working tree
$ leakferret scan .

# 2. Scan + classify + verify which keys are actually live
$ leakferret verify .

# 3. See the env-var rewrite as a diff, without touching files
$ leakferret rewrite . --dry-run-diff

# 4. Apply the rewrites in place
$ leakferret rewrite . --apply

scan respects .gitignore and also reads dotfiles such as .env. Add --git to walk commit history instead of the working tree.

CLI reference

Global options apply to every command: -q/--quiet, -v/-vv/-vvv (verbosity), -h/--help, -V/--version.

leakferret scan [PATH]

Regex pre-filter only — no classifier, no verifier. Fastest mode.

FlagMeaning
--gitScan git history instead of the working tree.
--since <REV> / --until <REV>History window for --git (e.g. HEAD~10, a tag, a SHA).
--max-depth <N>Cap on commits walked (safety valve for huge histories).
-f, --formatpretty (default), json, sarif.
--show-fixturesInclude FIXTURE-classified findings in output.
--exclude [<GLOB>…]Extra glob excludes, on top of .gitignore.
--only [<PATH>…]Limit to specific files (pre-commit-hook mode).
--only-verifiedEmit only findings the verifier confirms live (forces the verifier to run).

leakferret verify [PATH]

Scan + offline-heuristic classify + provider verification. Inherits all scan flags, plus:

FlagMeaning
--verify-modenone, best-effort (default), only-verified, ever-verified.
--verifier-timeout-secs <N>Per-verifier timeout (default 10).

leakferret rewrite [PATH]

Scan + classify, then propose ENV-fetch rewrites for REAL findings. Inherits all scan flags, plus:

FlagMeaning
--applyApply rewrites in place (default is dry-run).
--dry-run-diffPrint the unified diff per file without writing.
--checkCI mode: like --dry-run-diff but exits 1 if any rewrites are pending.
--backendSeed-command target: env (default), vault, doppler, aws-secrets-manager, infisical.

leakferret baseline <init|show|ignore>

Manage .leakferret-baseline.json — one-way HMAC fingerprints of acknowledged findings, so CI fails only on new leaks. init creates it, show prints it, ignore --fingerprint <fp> acknowledges a finding.

leakferret catalog <info|list|test|refresh>

info prints catalog metadata; list dumps entries as JSON; test <value> prints the verdict for a value; refresh fetches a fresh catalog from the CDN and verifies its Ed25519 signature before persisting it.

leakferret mcp

Start the MCP server on stdio. See Editors & agents.

Output formats

FormatUse
prettyColored terminal output (default).
jsonStructured findings for scripting and pipelines.
sarifFor GitHub Code Scanning; the Action uploads it for you.

Allowlisting false positives

Suppress a single finding with an inline comment pragma, kept next to the value it concerns:

API_KEY = "AKIA…"  # leakferret:allow aws_access_key reason="tutorial fixture"

Editors & coding agents (MCP)

MCP (Model Context Protocol) lets a coding agent call leakferret's pipeline itself — so it self-checks before committing. The server exposes scan_repository, classify_candidates, verify_finding, propose_rewrite, and baseline_diff, plus a classify prompt.

The shared config block (works for Claude Desktop, Cursor, and Continue):

{
  "mcpServers": {
    "leakferret": {
      "command": "npx",
      "args": ["@leakferret/mcp"]
    }
  }
}

If you installed the native binary, point at it directly instead:

{
  "mcpServers": {
    "leakferret": { "command": "leakferret", "args": ["mcp"] }
  }
}

Claude Code

$ claude mcp add leakferret -- npx -y @leakferret/mcp

Then ask Claude to scan before it commits. Use claude mcp list to confirm it registered.

Cursor

Create .cursor/mcp.json in the project (or the global one) with the shared block above. Cursor shows the server under Settings → MCP.

Continue

Add the shared block to ~/.continue/config.json (the mcpServers key). Restart the IDE panel to load it.

Claude Desktop

Edit claude_desktop_config.json and add the shared block, then restart the app:

OSPath
macOS~/Library/Application Support/Claude/claude_desktop_config.json
Windows%APPDATA%\Claude\claude_desktop_config.json

VS Code extension

Install leakferret from the VS Code Marketplace (or Open VSX for VSCodium/Cursor). It bundles the binary and surfaces findings inline.

CI

GitHub Actions

# .github/workflows/secrets.yml
name: secrets
on: [push, pull_request]
jobs:
  scan:
    runs-on: ubuntu-latest
    permissions:
      security-events: write   # for SARIF upload
    steps:
      - uses: actions/checkout@v4
      - uses: leakferrethq/leakferret-action@v1
        with:
          verify-mode: only-verified
          fail-on: any

Inputs: version (default latest), path, verify-mode, format (default sarif), fail-on (low|medium|high|critical|any), baseline-path, upload-sarif, category, github-token. Outputs: findings-count, verified-count, sarif-path.

Any other CI

Install the binary and run a command — exit code 1 means action needed:

$ leakferret verify . --verify-mode only-verified --format json
$ leakferret rewrite . --check   # exits 1 if rewrites are pending

Baselines

Commit a baseline so CI fails only on new leaks:

$ leakferret baseline init
$ leakferret baseline ignore --fingerprint <fp>   # acknowledge a known finding

How it works

  1. Scan — regex pre-filter over files (respects .gitignore, reads dotfiles, optionally walks history).
  2. Catalog — candidates checked against a signed database of known-public examples; matches are marked FIXTURE.
  3. Classify — verdict per candidate: REAL, FIXTURE, or UNKNOWN. Runs offline by default.
  4. Verify — one harmless API call confirms a key is LIVE. The call goes straight to the provider.
  5. Rewrite — swaps the literal for an env-var lookup, appends to .env.example, prints secret-manager seed commands.

Verifiers

Around 15 providers are verified natively: AWS (SigV4), GitHub, GitLab, Stripe, OpenAI, Anthropic, Slack, Twilio, SendGrid, Mailgun, Datadog, Heroku, npm, PyPI, DigitalOcean.

For providers without a native verifier, leakferret falls back to a trufflehog binary if it's on your PATH (or pointed at by LEAKFERRET_TRUFFLEHOG_BIN). Without it, those findings stay UNKNOWN rather than failing.

Each verification is a single least-privilege call (e.g. AWS STS GetCallerIdentity). Set --verifier-timeout-secs to bound slow networks. --verify-mode ever-verified fails on keys that were ever live, even if revoked now.

Fixture catalog

A signed database of documented-public example credentials (Stripe test keys, AKIAIOSFODNN7EXAMPLE, jwt.io samples, RFC examples). It is bundled into the binary, so a fresh install already suppresses these. Refresh and signature-verify an update with leakferret catalog refresh; inspect with leakferret catalog info.

Privacy & security

The full secret value lives only on disk. It is never serialized, logged, or sent in any report, log, network message, or model prompt. Only a redacted first-4 + last-4 preview (e.g. AKIA…4XYZ) ever leaves the process — a dedicated test enforces this. Verification calls go straight from your machine to the provider; leakferret has no servers and collects nothing. Baselines store one-way HMAC fingerprints, never the raw secret.

Platforms & caveats

Prebuilt binaries for v0.1.0:

aarch64 Linux is not in v0.1.0 (it lands in v0.1.1). On that platform, install with cargo install leakferret-cli from source, or set LEAKFERRET_BIN.

Troubleshooting

SymptomFix
Install can't download the binarySet LEAKFERRET_BIN to a local binary, or install via cargo install leakferret-cli.
A documented example key is flaggedRun leakferret catalog refresh, or add a leakferret:allow pragma.
A key shows UNKNOWN instead of LIVENo native verifier for that provider and no trufflehog on PATH, or the verifier timed out.
CI doesn't fail on a known leakCheck --verify-mode / fail-on, and that the finding isn't in the baseline.

Source & issues on GitHub →