secrets-scan
Caution
Secrets committed to git are permanent — even after deletion. A single password=prod123 in a config file, a hardcoded AWS key in a test fixture, a connection string left in a migration script. Once pushed, the history retains it. /brewtools:secrets-scan finds these before they become incidents.
Tip
10 parallel agents, one command. The skill splits your git file list into 10 chunks, runs haiku agents in parallel, merges results, ranks by severity, and writes a structured report — all without leaving your Claude session. Add --fix to remediate interactively.
Quick reference
| Field | Value |
|---|---|
| Command | /brewtools:secrets-scan |
| Arguments | [--fix] — no args = scan only, --fix = interactive remediation |
| Model | sonnet |
| Context | session |
| Tools | Read, Task, Write, Bash, AskUserQuestion |
When to use
- Pre-push audit — run before opening a PR or pushing to a remote branch
- Open-source prep — before making a private repo public, scan the full history surface
- CI gate — catch secrets that slipped past
.gitignorerules - Post-incident — verify no additional credentials are exposed after a breach
- Onboarding — audit a legacy codebase you’ve just inherited
Examples
# Scan only — full repo, severity-ranked report
/brewtools:secrets-scan
# Scan and remediate interactively (CRITICAL + HIGH findings prompted)
/brewtools:secrets-scan --fix
# Free-form intent after the command (the skill is user-invoked only)
/brewtools:secrets-scan check for secrets before I open-source this repo
Expected output after scan:
## Secrets Scan Complete — FINDINGS
| Metric | Value |
|-----------|-------|
| Files | 342 |
| Unscanned | 0 |
| CRITICAL | 1 |
| HIGH | 3 |
| MEDIUM | 7 |
| LOW | 12 |
Report: .claude/reports/20260417-143022_secrets-scan/report.md (mode 600)
Verdict is one of CLEAN, FINDINGS, or INCOMPLETE — never CLEAN while any chunk failed reconciliation.
Flow
- Setup
Verifies the working directory is a git repository, then builds the scan list from
git ls-filesand filters it: binary and media extensions (images, fonts, archives, jars, compiled objects, minified bundles, source maps), vendor and build directories (node_modules,vendor,dist,build,target,pycache,Pods, …) and lock files are dropped before anything is chunked. Creates a timestamped report directory under.claude/reports/(chmod 700) and appends.claude/reports/to.gitignorewhen nothing already ignores it — a report that names where credentials live must never become committable. - Split & launch 10 agents
Divides the file list into 10 equal chunks (ceil division). Spawns 10
general-purpose haikuagents in a single parallel Task call — each agent reads its assigned files and applies detection patterns. - Reconcile & merge
Checks each agent’s response against its assigned file list —
scanned[] + skipped[]must cover exactly the files it was given. A mismatched or malformed chunk is re-spawned once with the identical prompt; still wrong after that, it is recordedUNSCANNEDand the scan can no longer be reported clean. Reconciled chunks are then deduplicated bypath+line, merged, and sorted: CRITICAL → HIGH → MEDIUM → LOW. - Generate report
Writes
{DIR}/report.md(chmod 600) with a verdict (CLEAN / FINDINGS / INCOMPLETE), a summary table, per-severity finding tables — file, line, category, value length, asha256[:12]fingerprint, a masked preview, description — per-agent stats, an unscanned section when a chunk failed twice, and a full file inventory including skipped files with skip reasons. - Display summary
Prints a compact table of the verdict and severity counts plus the report path directly in the session. No need to open the file to see the headline result.
- Fix mode
Triggered by
—fixflag or automatically when CRITICAL/HIGH findings exist. Walks through each finding withAskUserQuestion: fix inline, move to env var, add file to.gitignore, mark as false positive, or skip.
Delegation
Warning
A big task handed to one agent = an agent gone for an hour. You cannot observe it, you cannot correct it, and it usually drifts off-target. Here the 10-way split is the sizing rule: one subagent = ONE chunk, ~10 steps. A repo big enough that a chunk still exceeds that gets more chunks, not bigger ones — and every Task call goes out in one message.
Each chunk agent receives the same six-field brief, reused verbatim per chunk:
| Field | Content |
|---|---|
| GOAL | audit the repo for leaked credentials before they reach a remote |
| ROLE | read and classify only — no edit, delete, redact, or rewrite |
| SCOPE | exactly the listed files; out — every other path, git history, .git/ |
| CONTEXT | the file list was produced and filtered in Phase 1 — do not re-discover or re-filter it; nine siblings scan the other chunks right now |
| CONSUMER | the skill reconciles each agent’s scanned[] + skipped[] against its assigned file list before merging — a mismatched or malformed chunk is re-spawned once, and still-wrong is reported UNSCANNED, never merged in silently |
| DONE | the specified JSON object, nothing else — no prose, no markdown fence |
A bare one-line task is never enough. The failure mode is concrete: a malformed or chatty response used to silently remove an entire chunk from the merged report, and a missed CRITICAL there is a credential shipped to a remote. Reconciliation is what closes that gap — the chunk either gets accounted for or the whole scan is marked INCOMPLETE.
The CONTEXT line has to be true. The brief tells each agent the list is already filtered and instructs it not to skip anything — so when Phase 1 handed over an unfiltered git ls-files, ten agents spent their chunk budget reading .png, .jar, lockfiles and vendored code they had been told not to skip. Phase 1 now filters for real.
Redaction is mandatory, not optional. Agents never quote, echo, or summarise a matched value — for every hit they run the skill’s redaction script and copy back only a length, a sha256[:12] fingerprint, and a preview of at most 4 leading characters. The raw secret never enters an agent’s response, the report, or this chat.
Detection rules
What gets flagged:
| Category | Patterns |
|---|---|
| Passwords | password, passwd, secret, pwd followed by = or : and a value |
| API keys | api_key, access_key, apikey, api_secret |
| Tokens | token, bearer, auth_token, access_token |
| AWS credentials | AKIA[0-9A-Z]{16}, aws_secret, aws_access_key |
| Database URLs | JDBC, MongoDB, MySQL, PostgreSQL connection strings with embedded credentials |
| Private keys | -----BEGIN ... PRIVATE KEY-----, client_secret, encryption_key |
Severity levels:
| Level | Criteria |
|---|---|
| CRITICAL | Real credentials, private keys, database connection strings with passwords |
| HIGH | Real API keys or tokens, AWS credentials |
| MEDIUM | Suspicious hardcoded values that may be secrets |
| LOW | Placeholder values (changeme, YOUR_KEY, xxx, dummy) |
Automatically skipped:
Environment variable references (process.env.*, ${VAR}, os.getenv()), common placeholders, documentation comments, binary files.
Fix mode options:
| Option | Action |
|---|---|
| Fix | Delete or replace the secret inline |
| Move to env var | Extract value into an environment variable reference |
| Add to .gitignore | Append the file path to .gitignore |
| Mark false positive | Acknowledge and skip — logged in report |
| Skip | Leave as-is, move to next finding |
Deploy skill
Ship changes via GitHub Actions workflows and GHCR — pair with a clean secrets audit before release.
GitHub source
Source code, detection patterns, and agent prompt templates.
Brewtools overview
All brewtools skills — text optimization, SSH management, plugin updates, and more.
Updating plugins
/brewtools:plugin-update to check and update the brewcode plugin suite in one command.
See the FAQ for details.