Project notes · creator & maintainer
Building leakferret
I had rotated enough credentials after finding them in Git history. I wanted the check earlier, while someone could still change the code before committing it.
What I built
leakferret combines a Rust scanner with a command-line interface and an MCP server for coding agents. I built the engine, fixture catalog, provider checks, and rewrite handling, then the editor integration and release packages.
CLI and MCP handlers use the same core crate. A new delivery surface doesn't need its own implementation of finding classification or rewrite rules.
A likely credential isn't a verified one.
A pattern match only finds a candidate. Context can suggest a real secret, a fixture, or leave the result unknown. A provider request answers a different question: did this credential authenticate?
Real · Fixture · UnknownVerified · Invalid · InconclusiveI keep those results separate in the finding model. A failed request doesn't prove a credential is harmless, and a heuristic verdict doesn't prove it's live.
Ordinary scan runs without provider verification. verify makes authenticated requests unless verification is disabled. That distinction matters when the check runs in an editor, CI, or an agent session.
A proposal before an edit.
A scanner can point at a line without knowing how to fix it. Rewriting requires the language and surrounding source to support an environment lookup.
− client.token = "…"
+ client.token = ENV.fetch("CLIENT_TOKEN") Rewrite proposals come before file changes. --dry-run-diff shows the proposed diff, while --apply writes it. A dry run can still perform provider verification. It means no source edits, not no network traffic.
I also use HMAC fingerprints to identify findings across scans. A baseline can recognize a previously recorded finding without using the raw credential as its identity.
Testing and releases
People need the same behavior whether they run the CLI or call it through an agent. The workspace includes tests for inconclusive verification and rewrite context boundaries. CI defines test runs for Linux, macOS, and Windows.
Release automation builds the binaries, produces checksums and signing bundles, and creates a draft release. Packaging is part of this project, not an installation note I added at the end.