Scan for leaked secrets
gnaw's output goes straight into a chat box, so a hard-coded API key in your
source is one paste away from leaking. --secret-scan checks every file's
content for likely secrets and lets you decide what happens when one is found โ
warn, redact it in place, or refuse outright.
gnaw . --secret-scan redact -O context.mdChoose what happens on a hit
--secret-scan takes one of four policies. The default is warn.
| Policy | Behavior |
|---|---|
off | Don't scan at all |
warn (default) | Include content unchanged; report findings on stderr |
redact | Replace each detected secret with [REDACTED: <rule>], then include |
block | Abort the run with a non-zero exit if any secret is found |
gnaw . --secret-scan warn # just tell me (default)
gnaw . --secret-scan redact # scrub it, keep the rest
gnaw . --secret-scan block # fail the run โ good for CI / pre-commit
Scanning runs after compression and before token counting, so when you redact, the reported token total reflects the scrubbed output, and a secret buried in a Rust function body that compression already stripped never reaches the scanner in the first place.
Reading the report
For warn and redact, findings print to stderr (your prompt stays clean on
stdout), one line per hit with the rule that matched, location, and a redacted
preview โ never the full secret:
[!] secret scan: 1 potential secret(s)
src/config.rs:12 [github-pat] ghp_โฆ (40 chars) (entropy 5.2)
For block, the same detail appears in the abort message and the process exits
non-zero, which is what makes it useful as a pre-commit or CI gate.
Skipping test fixtures
Test files often contain deliberately fake tokens that you don't want flagged.
--secret-scan-allow takes path fragments (substring match) to skip; it's
repeatable and overrides the config file:
gnaw . --secret-scan redact --secret-scan-allow tests/ --secret-scan-allow fixtures/
If you set nothing, gnaw still skips a built-in set of common test locations
(/tests/, /test/, /fixtures/, /testdata/, /__tests__/, and _test.
filenames). The moment you pass your own fragments, you take full control and
those built-in defaults no longer apply.
Make it the default
Set the policy and allowlist once in .gnawconfig (local, or global at
~/.config/gnaw/.gnawconfig):
secret_scan = "redact"
secret_scan_allow_paths = ["tests/", "fixtures/", "examples/"]
Precedence is CLI flag โ config file โ built-in default (warn), so a
project can default to redact while a one-off run overrides it with
--secret-scan off.
What it catches โ and what it can't
gnaw matches known secret shapes with a regex-plus-entropy ruleset (AWS keys, GitHub tokens, Slack, Google, Anthropic, OpenAI, Stripe, JWTs, PEM private-key blocks, crates.io tokens, and keyword-anchored assignments). The full list and how to reason about coverage is in the secret-scan reference.