pii-scrubber
Skill0 starsChanged 41 days agoMITView on GitHub
Detects and redacts personally identifiable information from text, logs, datasets, and LLM prompts using layered pattern, checksum, and NER detection, then picks the right redaction mode for each downstream use. Use when someone asks "scrub PII from these logs", "redact personal data before sending it to the LLM", "is this dataset safe to share", or is wiring up logging, analytics, or third-party exports that might carry user data. Do NOT use for leaked API keys, tokens, or credentials - use secrets-hygiene instead.
In this repository6 other files it gives its agents.
- dependency-risk-auditSkill
- secrets-hygieneSkill
- secure-code-reviewSkill
- soc2-evidence-helperSkill
- threat-model-strideSkill
- vulnerability-triageSkill
The file
We split this skill into the rules it gives an agent
9 rules. About 0 are common, 9 are distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈9
Distinctive · estimate
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 46
Remove: drop the field entirely when nothing downstream needs it.
- Distinctive: line 48
Default to the most aggressive mode that still serves the downstream need.
- Distinctive: line 92
Do not scrub after the data lands in the destination - backups and replicas have already copied it.
- Distinctive: line 93
Do not run a blocklist of "bad fields".
- Distinctive: line 94
Do not log the raw value next to the redacted one, even at DEBUG level.
- Distinctive: line 95
Do not hash when records need to join later and tokenization was the requirement - and do not tokenize without a secret salt, or the …
- Distinctive: line 96
Do not treat structured-field scrubbing as coverage for free-text fields.
- Distinctive: line 97
Do not rotate the tokenization salt casually - it silently breaks every downstream join.
- Distinctive: line 101
Every field in the output is on the allowlist with a named downstream reason, or absent.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
PII Scrubber
Personal data that reaches logs, analytics, prompts, or exports is a liability that outlives the feature that leaked it - retention systems copy it, backups preserve it, and deletion requests cannot find it. The outcome of this skill is a scrubbing setup that catches PII at the boundary and redacts it in the least destructive mode that still protects the person. The costly mistake it prevents is redacting so naively that either PII slips through in free text or the data becomes useless for the job it was collected for.
Operating procedure
Detection precedes mode selection because the right redaction depends on what the downstream consumer needs from each field - decide per field, not per dataset.
Step 1: Gather inputs
- The data source: logs, database export, chat transcripts, prompt payloads, analytics events.
- Downstream use: debugging, analytics joins, support lookups, model training, third-party sharing. This decides the redaction mode.
- Whether records must remain joinable after scrubbing (tokenize) or only comparable for equality (hash) or neither (mask or remove).
- Jurisdictions and regimes in play (GDPR, CCPA, HIPAA). Default to the strictest plausible; label the assumption a guess.
- Locales in the data - phone, postal, and ID formats vary by country.
Step 2: Inventory the categories to detect
Names, emails, phone numbers, postal addresses, government IDs (SSN, passport), dates of birth, credit card and bank account numbers, IP addresses, MAC addresses, geolocation, biometric references, medical record numbers, vehicle plates, usernames, device IDs, URLs with embedded tokens, and free-text quasi-identifiers.
Step 3: Detect in layers
- Deterministic patterns for structured PII (regex plus checksums).
- Validate wherever possible - Luhn for cards, format checks for SSN and IBAN - to cut false positives.
- Named-entity recognition for names, locations, and organizations in free text.
- Context rules: a 9-digit number near the word "SSN" is higher confidence than one standing alone.
email: [^\s@]+@[^\s@]+\.[^\s@]+
card: \b(?:\d[ -]?){13,16}\b then Luhn-validate
ipv4: \b\d{1,3}(\.\d{1,3}){3}\bStep 4: Choose the redaction mode per field
- Mask: j***@example.com, --****-1234 (keep last 4 for support workflows).
- Tokenize: replace with a stable pseudonym so records still join (USER_a1b2). Make tokenization deterministic with a secret salt so the same value maps consistently - and rotate that salt carefully, because rotation breaks joins.
- Hash: one-way, for analytics that only need equality.
- Remove: drop the field entirely when nothing downstream needs it.
Default to the most aggressive mode that still serves the downstream need. If nobody can say why a field is needed, remove it.
Step 5: Apply at the boundary
Scrub before logging, before sending to third parties, before LLM prompts - never after the data is already at rest in the destination. Maintain an allowlist of fields safe to emit rather than a blocklist of bad ones: blocklists fail open when a new field appears; allowlists fail closed.
Step 6: Verify with sampling
Pull a random sample of at least 100 scrubbed records (or 1% of the dataset, whichever is larger) and review for false negatives - typos, unusual formats, and free-text leaks that patterns miss. Combine NER with patterns and repeat sampling after any format change in the source.
Worked artifact: log line, bad vs good
Bad - raw PII straight into the log store:
INFO payment failed for jane.doe@example.com card 4111111111111111 from 203.0.113.42Good - tokenized user, masked card, generalized IP, still debuggable and joinable:
INFO payment failed user=USER_a1b2 card=****1111 ip=203.0.113.0/24 error=insufficient_fundsThe good line supports the two real jobs - joining this user's events (stable token) and support lookup (last 4) - while carrying no recoverable PII. Never log the raw value alongside the redacted one; that pattern silently defeats the entire pipeline.
Compliance notes
- GDPR/CCPA: support deletion and access requests - deterministic tokenization is what lets you find all of a person's records to honor them.
- Minimize: do not collect or retain PII that is not needed for a stated purpose.
- Audit: log that redaction ran and what rules fired - never what it redacted.
Edge cases
- False negatives in free text (typos, unusual formats): patterns alone are insufficient; layer NER and review samples.
- Quasi-identifiers: combinations like zip + date of birth + gender can re-identify individuals; for shared datasets, generalize until each combination matches at least a handful of records (k-anonymity, commonly k of 5 or more).
- Internationalization: use locale-aware validators for phone numbers and national IDs; a US-only SSN regex misses every other country's equivalents.
Deliverable
Produce a scrubbing specification containing: the field inventory with a PII category per field, the detection layer and validation applied to each, the chosen redaction mode per field with the downstream justification, the boundary points where scrubbing executes, and the sampling verification plan with its false-negative findings.
Do NOT
- Do not scrub after the data lands in the destination - backups and replicas have already copied it.
- Do not run a blocklist of "bad fields"; new fields ship unreviewed and leak. Allowlist what may be emitted.
- Do not log the raw value next to the redacted one, even at DEBUG level.
- Do not hash when records need to join later and tokenization was the requirement - and do not tokenize without a secret salt, or the pseudonyms are reversible by anyone who can guess inputs.
- Do not treat structured-field scrubbing as coverage for free-text fields; free text is where the misses live.
- Do not rotate the tokenization salt casually - it silently breaks every downstream join.
Quality bar
- Every field in the output is on the allowlist with a named downstream reason, or absent.
- Structured PII is validated (Luhn, format checks), not just pattern-matched.
- Free text passed through NER plus context rules, and a sample of at least 100 records was human-reviewed for false negatives.
- The mode per field is the most aggressive that still serves the stated need.
- The audit trail records that redaction ran without containing redacted values.
Escalation
This skill is not legal advice; for regime-specific obligations (GDPR lawful basis, HIPAA de-identification standards, CCPA service-provider terms) involve privacy counsel or a compliance officer. Credentials and API keys found while scrubbing route to secrets-hygiene immediately. If scrubbed datasets feed model training or evaluation, pair with llm-evaluation for the downstream quality checks.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

