Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Pre-publish PII and secrets scrubbing automation for repositories being prepared for open source. Runs regex-based sweeps for email addresses, phone numbers, API keys, spreadsheet IDs, internal URLs, physical addresses, and known team member names. Reports findings with file and line numbers, guides the user through review and replacement with safe sample data, then verifies all patterns are cleared. Triggered when the user asks to scrub PII, prepare a repo for open source, make a repo public, c
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-08 | ✗→✓ | ▲ Improved | 39% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 37% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 29% | 0% |
| case-16 | ✗→✓ | ▲ Improved | 23% | 0% |
| case-19 | ✗→✓ | ▲ Improved | 71% | 0% |
Automated PII and secrets detection for repositories being prepared for public release.
Activate this skill when the user:
Always skip these paths during scanning:
.git/ -- repository internalsnode_modules/ -- third-party dependenciesvendor/ -- third-party dependencies*.min.js, *.min.css -- minified bundlespackage-lock.json, bun.lockb, yarn.lock -- lockfilesregex[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}
Exclude safe patterns: @example.com, @example.org, @your-domain.com, @users.noreply.github.com, noreply@
Flag everything else as a potential real email.
US formats:
regex\b\d{3}[-.]?\d{3}[-.]?\d{4}\b
International formats:
regex\+\d{1,3}[-.\s]?\(?\d{1,4}\)?[-.\s]?\d{1,4}[-.\s]?\d{1,9}
Exclude: Numbers that are clearly not phones (port numbers like 3000, 8080, 5432; hex values; timestamps).
| Pattern | Service | |---------|---------| | sk_live_[a-zA-Z0-9]+ | Stripe live key | | sk_test_[a-zA-Z0-9]+ | Stripe test key | | ghp_[a-zA-Z0-9]+ | GitHub PAT | | gho_[a-zA-Z0-9]+ | GitHub OAuth token | | sntryu_[a-zA-Z0-9]+ | Sentry user token | | xnd_[a-zA-Z0-9]+ | Xendit API key | | Bearer [a-zA-Z0-9._-]+ | Bearer tokens | | token:\s*"[^"]+" | Generic token assignments | | AKIA[0-9A-Z]{16} | AWS access key | | AIza[0-9A-Za-z_-]{35} | Google API key | | xoxb-[0-9a-zA-Z-]+ | Slack bot token | | xoxp-[0-9a-zA-Z-]+ | Slack user token |
regexspreadsheetId.*['\"][a-zA-Z0-9_-]{20,}['\"]
Google Sheets URLs:
regexdocs\.google\.com/spreadsheets/d/[a-zA-Z0-9_-]+
Also check for SHEET_ID, DOC_ID, SPREADSHEET_ID with hardcoded values.
Flag domains that are NOT in the safe list:
Safe list: example.com, example.org, localhost, 127.0.0.1, 0.0.0.0, github.com, npmjs.com, vercel.app, shields.io, img.shields.io, creativecommons.org, opensource.org, keepachangelog.com, semver.org
Any other https?:// URL with a real-looking domain should be flagged for review.
Basic US address pattern:
regex\d{1,5}\s+[A-Z][a-z]+(\s+[A-Z][a-z]+)*\s+(St|Ave|Blvd|Dr|Rd|Ln|Way|Ct|Pl|Cir)\b
Also check for:
\b\d{5}(-\d{4})?\b[A-Z][a-z]+,\s*[A-Z]{2}\s+\d{5}Ask the user for a list of real names to search for. Search case-insensitively across all text files. Common locations where names hide:
// Author: ...)author and contributors fields.git/ and are excluded from file sweep, but warn the user about git log)When replacing PII, use these safe substitutes:
| Data Type | Replacement | Rationale | |-----------|-------------|-----------| | Phone numbers | 555-XXX-XXXX (e.g., 555-012-3456) | FCC reserved range | | Email addresses | user@example.com, admin@example.com | IANA reserved domain | | Business names | Generic descriptors: "Sample Cabinet Shop", "Metro Kitchen & Bath", "Acme Corp" | Clearly fictional | | Person names | "Jane Doe", "John Smith", "Alex Johnson" | Obvious placeholders | | Physical addresses | "123 Main St, Anytown, CA 90210" | Recognizable fake | | Spreadsheet IDs | your-sheet-id with note (set SHEET_ID in .env) | Guides user to configure | | API keys | your-api-key-here with note (set in .env) | Guides user to configure | | Internal URLs | https://your-app.example.com | Safe placeholder |
Run all patterns across the repository. For each finding, report:
[CATEGORY] file/path:line_number
Matched: <the matched text, truncated if long>
Context: <surrounding line for review>Group findings by category. Show a summary count:
Sweep Results:
Emails: 3 findings (2 files)
Phone numbers: 1 finding (1 file)
API keys: 2 findings (1 file)
Spreadsheet IDs: 0 findings
Internal URLs: 4 findings (3 files)
Addresses: 0 findings
Names: 1 finding (1 file)
--------------------------------
Total: 11 findingsPresent each finding and ask the user to classify:
Do NOT auto-replace anything. Wait for explicit user confirmation on each finding or batch.
For true positives:
.env, add the variable to .env (gitignored) and .env.example (with placeholder)process.env.VARIABLE_NAME or equivalentFor each replacement, show a before/after diff.
Re-run all sweep patterns. The goal is zero findings (excluding acknowledged false positives).
If new findings appear (e.g., a replacement introduced a new pattern match), flag and resolve.
If the project uses .env:
.env is listed in .gitignore.env.example exists with all required variables (placeholder values only).env file is tracked in git: git ls-files .envPII Sweep Complete
==================
Files scanned: 142
Patterns checked: 7 categories
Findings: 11 total
True positives: 8 (replaced)
False positives: 3 (acknowledged)
Moved to .env: 2
Replacements made:
- src/config.ts:14 email -> user@example.com
- src/config.ts:15 api_key -> moved to .env
- README.md:45 phone -> 555-012-3456
...
Remaining warnings:
- Git history contains real names in commit messages
(consider: git filter-branch or BFG Repo Cleaner)
- 2 false positives acknowledged by user
Status: READY FOR PUBLIC RELEASE| Rule | Rationale | |------|-----------| | Never auto-replace without user confirmation | Automated replacement can break functionality or remove intentional data | | Never delete content -- always replace | Deletions can break code; replacements keep the app functional | | Exclude .git/, node_modules/, binaries | These are managed externally and would produce false positives | | Warn about git history | git log and reflog retain PII even after file-level scrubbing | | Run verification pass after all replacements | Ensures no PII was missed or reintroduced | | Check .env is gitignored | Prevents secrets from being committed in the future |
File-level scrubbing does not clean git history. If the repository previously contained real PII in committed files, warn the user about these options:
This is outside the scope of pii-sweep (destructive git operations require explicit user action) but must always be mentioned in the final report if any true positives were found in tracked files.
Other measured skills in the registry, with their headline benchmark lift.