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
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.
| Flag | Meaning |
|---|---|
--git | Scan 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, --format | pretty (default), json, sarif. |
--show-fixtures | Include 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-verified | Emit 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:
| Flag | Meaning |
|---|---|
--verify-mode | none, 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:
| Flag | Meaning |
|---|---|
--apply | Apply rewrites in place (default is dry-run). |
--dry-run-diff | Print the unified diff per file without writing. |
--check | CI mode: like --dry-run-diff but exits 1 if any rewrites are pending. |
--backend | Seed-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
| Format | Use |
|---|---|
pretty | Colored terminal output (default). |
json | Structured findings for scripting and pipelines. |
sarif | For 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"
- A pragma on the same line, or the line immediately above, suppresses that finding.
- With a
pattern_idit only suppresses that pattern; without one it suppresses all patterns on the line. #,//, and/* */comment markers all work.
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/mcpThen 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:
| OS | Path |
|---|---|
| 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
- Scan — regex pre-filter over files (respects
.gitignore, reads dotfiles, optionally walks history). - Catalog — candidates checked against a signed database of known-public examples; matches are marked FIXTURE.
- Classify — verdict per candidate: REAL, FIXTURE, or UNKNOWN. Runs offline by default.
- Verify — one harmless API call confirms a key is LIVE. The call goes straight to the provider.
- 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.
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:
x86_64-unknown-linux-gnux86_64-apple-darwin,aarch64-apple-darwinx86_64-pc-windows-msvc,aarch64-pc-windows-msvc
cargo install leakferret-cli from source, or set LEAKFERRET_BIN.- Classification is offline by default; there is no built-in LLM call in the CLI.
- The
trufflehogfallback is optional and only used if the binary is present. - Git-history scanning (
--git) and--only-verifiedare mutually exclusive for now.
Troubleshooting
| Symptom | Fix |
|---|---|
| Install can't download the binary | Set LEAKFERRET_BIN to a local binary, or install via cargo install leakferret-cli. |
| A documented example key is flagged | Run leakferret catalog refresh, or add a leakferret:allow pragma. |
| A key shows UNKNOWN instead of LIVE | No native verifier for that provider and no trufflehog on PATH, or the verifier timed out. |
| CI doesn't fail on a known leak | Check --verify-mode / fail-on, and that the finding isn't in the baseline. |