How to Write Regex Rules to Block PII in Claude/GPT Prompts (With Copy-Paste Examples)

Deterministic prompt firewall PII rules for engineers routing LLM traffic.

Resource guide · Updated 2026 · 12 min read

Teams routing user inputs to Claude, GPT, or other LLM APIs face a predictable control gap: how to stop PII and secrets from entering the prompt context before the model processes them.

LLM-native PII detectors add latency, cost tokens, and still miss structured identifiers. For deterministic, sub-millisecond filtering, regex remains the most reliable first line of defense. This guide defines how to regex block SSN in prompt payloads, catch exposed API keys, package them as prompt firewall PII rules, and deploy via lightweight JSON/YAML configs — code, config, and copy-paste patterns for production pipelines. For the full developer workflow (classification, pre-commit, policy), see how to prevent source code leaks to AI coding tools.

Legal disclaimer

Operational guidance only. This guide supports technical prompt filtering. It is not legal advice. Regex detects format, not legal status of data. Engage qualified security engineering for production hardening.

Key findings

• For structured identifiers (SSNs, API keys), regex filtering is typically sub‑5ms, $0, and deterministic compared to LLM-based detection.
• Block or redact before the LLM call to avoid token spend on payloads you would reject anyway, and to keep raw secrets out of prompt logs.
• Treat regex as a first line control: pair it with allowlists, validation, and testing to manage false positives and bypass attempts.

Why Regex Still Wins for Prompt Filtering

ApproachLatencyCostDeterminismBest for
LLM-based PII detection300–1500ms$/1k tokensProbabilisticUnstructured text, context-aware scans
Regex + prompt firewall<5ms$0DeterministicStructured PII (SSN, CC, IDs, secrets), edge routing

Regex is not a silver bullet for context-heavy PII, but it excels at catching high-entropy identifiers that follow strict formatting rules. Paired with prompt firewall middleware, it enables immediate rejection or redaction before API calls, zero token waste on blocked payloads, and tunable false-positive rates.

The Anatomy of a Production-Ready SSN Regex

A naive pattern like \d{3}-\d{2}-\d{4} will match any text that follows the same numeric structure, including test data, placeholder identifiers, and unrelated numeric strings. To safely regex block SSN in prompt inputs, implement:

  1. Negative lookarounds to avoid partial matches inside longer numbers
  2. Invalid range exclusion (SSNs don’t start with 000, 666, or 900–999)
  3. Flexible separators (hyphens, spaces, or none)
  4. Boundary anchors to prevent mid-string false positives

Copy-paste pattern

(?<!\d)(?!000|666|9\d{2})\d{3}[- ]?(?!00)\d{2}[- ]?(?!0000)\d{4}(?!\d)

Breakdown:

  • (?<!\d) — no digit precedes the match
  • (?!000|666|9\d{2}) — excludes invalid area groups
  • \d{3}[- ]?(?!00)\d{2}[- ]?(?!0000)\d{4} — area, group, serial with optional separators
  • (?!\d) — no digit follows the match
Validation vs. detection

This pattern validates format, not issuance. It will catch historically unissued numbers like 078-05-1120. For compliance scoping, treat matches as potential PII and escalate to the DLP pipeline rather than assuming legal SSN status. Test against representative prompt corpora on regex101 before deploying.

Catching Secrets & API Keys in Prompt Inputs

A large share of prompt firewall triggers involve exposed credentials rather than personal identifiers. For developer queries, code completion, or support logs, add these patterns to the rule set:

# OpenAI-style keys (?i)\bsk-[A-Za-z0-9]{20,}\b # GitHub Personal Access Tokens \bgithub_pat_[A-Za-z0-9_]{20,}\b # AWS Access Keys \bAKIA[0-9A-Z]{16}\b # Generic high-entropy base64 (optional catch-all) (?<![A-Za-z0-9+/])[A-Za-z0-9+/]{40,}(?![A-Za-z0-9+/=])

Combine these with PII patterns to create a single inspection layer that catches both user data and leaked infrastructure secrets. The AI-010 kit includes additional DLP patterns (cards, private keys, internal IPs) and prompt-injection rules in a companion JSON file.

Packaging as Prompt Firewall PII Rules (JSON + YAML)

Raw regex is hard to maintain at scale. Wrapping it in structured configs turns patterns into reusable prompt firewall PII rules that can be versioned, audited, and hot-reloaded.

JSON template

{ “version”: “1.2”, “engine”: “regex-v2”, “default_action”: “pass”, “rules”: [ { “id”: “rule-ssn-01”, “name”: “block-us-ssn”, “pattern”: “(?<!\\\\d)(?!000|666|9\\\\d{2})\\\\d{3}[- ]?(?!00)\\\\d{2}[- ]?(?!0000)\\\\d{4}(?!\\\\d)”, “action”: “block”, “severity”: “critical”, “response_message”: “Input contains blocked PII pattern. Please remove sensitive identifiers.” }, { “id”: “rule-email-01”, “name”: “redact-email”, “pattern”: “\\\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\\\.[A-Z|a-z]{2,}\\\\b”, “action”: “redact”, “replacement”: “[EMAIL_REDACTED]” } ] }

YAML alternative

rules: – id: block-us-ssn action: block severity: critical pattern: ‘(?<!\d)(?!000|666|9\d{2})\d{3}[- ]?(?!00)\d{2}[- ]?(?!0000)\d{4}(?!\d)’ response_message: “Input contains blocked PII pattern.” – id: block-openai-key action: block severity: critical pattern: ‘(?i)\bsk-[A-Za-z0-9]{20,}\b’ response_message: “API key detected in prompt. Remove secrets before routing.”

Why this structure works: default_action dictates behavior when no rules match; action supports block, redact, alert, or log; id + version enable CI validation and rollback; extend the same schema for PCI, PHI, or internal token formats.

How to Deploy in Your Prompt Pipeline

Deploy a lightweight middleware layer in the route handler or proxy. Pre-compile regex at startup to avoid per-request compilation overhead.

Python (FastAPI / LiteLLM proxy)

import re import json from fastapi import Request, HTTPException with open(“pii_rules.yaml”) as f: import yaml CONFIG = yaml.safe_load(f) RULES = [] for rule in CONFIG[“rules”]: rule[“_compiled”] = re.compile(rule[“pattern”]) RULES.append(rule) def evaluate_prompt(prompt: str) -> str: for rule in RULES: if rule[“_compiled”].search(prompt): if rule[“action”] == “block”: raise HTTPException( status_code=400, detail=rule.get(“response_message”, “Blocked by prompt firewall”), ) elif rule[“action”] == “redact”: prompt = rule[“_compiled”].sub( rule.get(“replacement”, “[REDACTED]”), prompt ) return prompt

Node.js (Express / custom proxy)

const fs = require(‘fs’); const yaml = require(‘js-yaml’); const config = yaml.load(fs.readFileSync(‘pii_rules.yaml’, ‘utf8’)); const RULES = config.rules.map(rule => ({ …rule, _regex: new RegExp(rule.pattern, ‘g’) })); function filterPrompt(prompt) { for (const rule of RULES) { if (rule._regex.test(prompt)) { if (rule.action === ‘block’) { throw new Error(rule.response_message || ‘Blocked by prompt firewall’); } else if (rule.action === ‘redact’) { prompt = prompt.replace(rule._regex, rule.replacement || ‘[REDACTED]’); rule._regex.lastIndex = 0; } } } return prompt; }

Performance tip: Order rules by expected match frequency. Put high-hit patterns (emails, generic keys, SSNs) first. Short-circuiting on the first match often cuts evaluation time materially under real traffic.

Testing & Validation Before Production

Regex for PII fails silently if untested. Follow this validation loop:

  1. Synthetic payloads: dashes, spaces, no separators, embedded in sentences, adjacent digits
  2. False positive sweep: run against real prompt logs (anonymized)
  3. Load test: benchmark with k6 or ab; confirm regex is compiled once
  4. Tune boundaries: adjust lookarounds based on failures
import re pattern = re.compile( r”(?<!\d)(?!000|666|9\d{2})\d{3}[- ]?(?!00)\d{2}[- ]?(?!0000)\d{4}(?!\d)” ) tests = [ (“My SSN is 123-45-6789”, True), (“Date: 2023-12-25”, False), (“Card: 1234 5678 9012 3456”, False), (“Invalid SSN: 000-12-3456”, False), (“Adjacent digits: 123-45-67899”, False), (“ITIN format: 912-70-1234”, False), (“Historical: 078-05-1120″, True), ] for text, expected in tests: assert bool(pattern.search(text)) == expected, f”Failed on: {text}” print(“All validation tests passed”)

Limitations of Regex-Based PII Detection

Regex performs well on structured identifiers but cannot reliably detect names, unstructured addresses, context-dependent sensitive data, or SSNs spoken in natural language. Production systems combine deterministic regex with ML- or LLM-based classifiers: regex for the first, sub-millisecond filter; escalate only when structured patterns are insufficient.

Regex Filters vs. Prompt Injection Protection

PII filtering and prompt injection defense solve different problems. A robust LLM firewall typically combines both:

ControlPurpose
PII/secret regex rulesBlock SSNs, cards, emails, API keys before tokenization
Prompt injection detectionPrevent instruction override, jailbreaks, role leakage
Output filteringStop sensitive model responses reaching clients
DLP policiesGovern data movement and retention end-to-end

Regex alone won’t stop injection. Injection filters won’t catch PII. Deploy them as complementary layers. The AI-010 reference doc ships both DLP and injection pattern families in one ruleset.

Where This Fits in AI-010 DLP & Prompt Firewall

Organizations implementing AI-010 DLP & Prompt Firewall controls typically deploy these rules at the API gateway or middleware layer before prompts reach external model providers. This aligns with standard architecture:

  • Input inspection layer: regex runs before tokenization and routing
  • Deterministic policy engine: JSON/YAML configs enforce consistent dev/stage/prod behavior
  • Audit-ready logging: blocked/redacted events emit rule.id + action
  • Developer-first workflow: version-control policies alongside application code

Register approved systems in AI-006, classify data with AI-002, and pair technical blocks with AI-003 input-handling standards.

Get the AI-010 DLP & Prompt Firewall Pack

Production rule spec + companion JSON from the AI Governance Toolkit.

  • DLP patterns (SSN, cards, emails, keys, private keys, internal IPs)
  • Prompt injection rule pack (OWASP LLM01-aligned)
  • Machine-readable JSON for gateway import
  • Human-readable implementation and testing guidance
Download rules pack (.zip) Get the AI Governance Toolkit →

FAQ: Prompt PII regex in practice

Can regex block SSN in prompt inputs without breaking valid numeric data?
Yes, if you use negative lookarounds and exclude invalid SSN ranges (000, 666, 900–999). Always test against your actual prompt corpus for invoice numbers, timestamps, and IDs.
How do I maintain prompt firewall PII rules across teams?
Store rules in version-controlled JSON/YAML. Use CI to validate syntax and deploy via config reload instead of hardcoding in route handlers.
Does this work with streaming prompts?
Streaming needs chunk-aware filtering. Buffer until a logical boundary, or evaluate assembled prompts post-stream for logging. Regex works best on full payloads or assembled chunks.
Should I replace regex with an LLM PII detector later?
Use regex for structured identifiers (fast, cheap, deterministic). Reserve LLM-based scanners for unstructured context or output filtering. They complement each other.

Implementation checklist

  • Pre-compile regex at startup, not per-request
  • Order rules by match frequency to short-circuit early
  • Log rule.id + action on every match for auditability
  • Add a test_mode flag to run rules silently before enforcing block
  • Rotate rule versions; never edit live configs without validation
  • Monitor false-positive rate weekly; tune or exclude noisy patterns

Deploy prompt routing with regex-based PII and secret filters before the first token leaves the server — this is the baseline control for production LLM middleware.

Disclaimer: This guide provides technical implementation guidance for prompt filtering. It is not legal advice. Regex patterns detect format, not legal status of data. Test thoroughly in your environment before production enforcement. Patterns in the AI-010 kit are illustrative starting points — engage qualified security engineering for production hardening.