Docs/Guides/PII Detection

PII Detection Guide

Guardrail automatically detects and redacts personally identifiable information (PII) in AI agent outputs before they reach users or get logged to storage systems.

Detected PII Categories

PII TypeBefore (raw AI output)After (redacted_text)
Full Names"John Smith confirmed your appointment.""**** confirmed your appointment."
Email Addresses"Contact us at john.doe@company.com.""Contact us at ****@****.***."
Phone Numbers"Call us at +1 (555) 867-5309.""Call us at +1 (***) ***-****."
Social Security Numbers"Your SSN 078-05-1120 is on file.""Your SSN ***-**-**** is on file."
Credit Card Numbers"Card 4111-1111-1111-1111 was charged.""Card ****-****-****-**** was charged."
Bank Account Numbers"Account 12345678 has been credited.""Account ******** has been credited."
IP Addresses"Request from 192.168.1.104 was blocked.""Request from ***.***.***.*** was blocked."
Passport / National IDs"Passport A12345678 verified.""Passport ******** verified."

Example: Catching Credit Card Leakage

json (request)
{
  "agent_id": "billing-assistant",
  "proposed_text": "Hi Sarah, your card 4111-1111-1111-1111 expiring 09/27 has been charged $149.99."
}
json (response)
{
  "risk_score": 96,
  "status": "rejected",
  "flags": [
    "PII detected: First name (Sarah)",
    "PII detected: Credit card number (4111-1111-1111-1111)",
    "PII detected: Card expiry date (09/27)"
  ],
  "redacted_text": "Hi ****, your card ****-****-****-**** expiring **/** has been charged $149.99."
}

Integration Pattern for GDPR Compliance

Under GDPR and CCPA, logging raw AI outputs containing PII is a compliance risk. Use the redacted_text field exclusively for storage and logging.

python
def process_agent_reply(agent_id: str, raw_reply: str):
    result = guardrail.check(agent_id, raw_reply)
    
    # Always log the redacted version — never the raw PII-containing text
    audit_log.write({
        "agent_id": agent_id,
        "risk_score": result["risk_score"],
        "safe_text": result["redacted_text"],   # ← GDPR-safe
        "flags": result["flags"],
    })
    
    if result["status"] == "approved":
        return result["redacted_text"]
    else:
        return "I'm sorry, I cannot share that information."