Compliance & PII Detection¶
FastAgentic includes compliance tools for detecting and handling Personally Identifiable Information (PII).
Quick Start¶
from fastagentic import PIIDetector, PIIMasker
# Detect PII
detector = PIIDetector()
matches = detector.detect("Email me at [email protected]")
for match in matches:
print(f"{match.type}: {match.value}")
# Mask PII
masker = PIIMasker()
safe_text = masker.mask("Call me at 555-123-4567")
print(safe_text) # "Call me at 555-***-****"
PII Detection¶
Supported PII Types¶
from fastagentic import PIIType
# Built-in PII types
PIIType.EMAIL # Email addresses
PIIType.PHONE # Phone numbers
PIIType.SSN # Social Security Numbers
PIIType.CREDIT_CARD # Credit card numbers
PIIType.IP_ADDRESS # IP addresses
PIIType.DATE_OF_BIRTH # Birth dates
PIIType.ADDRESS # Physical addresses
PIIType.NAME # Person names
PIIType.CUSTOM # Custom patterns
Basic Detection¶
from fastagentic import PIIDetector
detector = PIIDetector()
# Detect all PII
text = "Contact: [email protected], Phone: 555-123-4567"
matches = detector.detect(text)
for match in matches:
print(f"Type: {match.type}")
print(f"Value: {match.value}")
print(f"Position: {match.start}-{match.end}")
print(f"Confidence: {match.confidence}")
# Quick checks
has_pii = detector.contains_pii(text)
pii_types = detector.get_pii_types(text)
Configuration¶
from fastagentic import PIIDetector, PIIConfig, PIIType
config = PIIConfig(
# Only detect specific types
enabled_types={PIIType.EMAIL, PIIType.PHONE},
# Minimum confidence threshold
min_confidence=0.8,
# Values to ignore
allowlist={"[email protected]", "1-800-COMPANY"},
# Additional values to flag
blocklist={"internal-secret", "api-key-xyz"},
)
detector = PIIDetector(config=config)
Custom Patterns¶
from fastagentic.compliance.pii import PIIPattern
# Define custom pattern
custom = PIIPattern(
type=PIIType.CUSTOM,
pattern=r"CUST-[0-9]{6}", # Customer ID format
confidence=1.0,
description="Customer ID",
)
config = PIIConfig(custom_patterns=[custom])
detector = PIIDetector(config=config)
matches = detector.detect("Customer ID: CUST-123456")
PII Masking¶
Basic Masking¶
from fastagentic import PIIMasker
masker = PIIMasker()
# Mask PII with asterisks
text = "Email: [email protected]"
masked = masker.mask(text)
# "Email: jo**@*****le.com"
# Show PII type in mask
masked = masker.mask(text, show_type=True)
# "Email: [EMAIL:jo**@*****le.com]"
# Full redaction
redacted = masker.redact(text)
# "Email: [REDACTED]"
Selective Masking¶
from fastagentic import PIIMasker, PIIType
masker = PIIMasker()
text = "Email: [email protected], SSN: 123-45-6789"
# Only mask specific types
masked = masker.mask(text, types={PIIType.SSN})
# "Email: [email protected], SSN: ***-**-****"
Masking Dictionaries¶
masker = PIIMasker()
data = {
"email": "[email protected]",
"phone": "555-123-4567",
"message": "Hello world",
}
masked_data = masker.get_masked_dict(data)
# {
# "email": "jo**@*****le.com",
# "phone": "555-***-****",
# "message": "Hello world",
# }
Nested Data¶
data = {
"user": {
"contact": {
"email": "[email protected]",
}
}
}
masked = masker.get_masked_dict(data)
# Handles nested structures automatically
Compliance Hooks¶
Detection Hook¶
from fastagentic import PIIDetectionHook, PIIType
hook = PIIDetectionHook(
block_on_detect=True,
blocked_types={PIIType.SSN, PIIType.CREDIT_CARD},
)
# Check text
result = hook.check_text("SSN: 123-45-6789")
if result.should_block:
raise ValueError("Sensitive PII detected")
# Check request data
result = hook.check_request({"input": "My SSN is 123-45-6789"})
if result.has_pii:
print(f"PII types found: {result.types}")
# Check response data
result = hook.check_response({"output": "Contact: [email protected]"})
Masking Hook¶
from fastagentic import PIIMaskingHook
hook = PIIMaskingHook(
mask_requests=True,
mask_responses=True,
)
# Mask request before processing
request = {"input": "Email: [email protected]"}
safe_request = hook.mask_request(request)
# Mask response before returning
response = {"output": "Call 555-123-4567"}
safe_response = hook.mask_response(response)
Selective Masking¶
# Only mask responses, not requests
hook = PIIMaskingHook(
mask_requests=False,
mask_responses=True,
)
# Disabled masking passes through unchanged
request = {"email": "[email protected]"}
result = hook.mask_request(request)
# Returns original request unchanged
Integration with App¶
from fastagentic import App
from fastagentic import PIIDetectionHook, PIIMaskingHook
app = App()
# Add PII hooks
detection_hook = PIIDetectionHook(block_on_detect=True)
masking_hook = PIIMaskingHook()
@app.agent_endpoint("/chat")
async def chat(message: str):
# Check input for sensitive PII
result = detection_hook.check_text(message)
if result.should_block:
return {"error": "Cannot process sensitive information"}
# Process message...
response = await process_message(message)
# Mask any PII in response
return masking_hook.mask_response(response)
Audit Logging¶
from fastagentic import PIIDetectionHook, AuditLogger
audit = AuditLogger()
hook = PIIDetectionHook()
async def check_and_log(text: str, user_id: str):
result = hook.check_text(text)
if result.has_pii:
await audit.log(
event_type="pii_detected",
severity="warning",
actor_id=user_id,
details={
"pii_types": [t.value for t in result.types],
"blocked": result.should_block,
},
)
return result
Best Practices¶
- Always mask before logging: Never log raw PII
- Block sensitive types: SSN, credit cards should block by default
- Allowlist known values: Company emails, support numbers
- Audit all detections: Log when PII is found for compliance
- Test with realistic data: Ensure patterns catch real-world formats