Anthropic Data Handling
Overview
Anthropic's data policies: API inputs/outputs are NOT used for model training (commercial API). Zero-day retention is available. This skill covers PII redaction before sending to Claude and compliance patterns.
Anthropic Data Policies
| Policy |
Details |
| Training data |
API data is NOT used for training (commercial API) |
| Data retention |
30-day default; 0-day available via agreement |
| Encryption |
TLS 1.2+ in transit, AES-256 at rest |
| SOC 2 Type II |
Certified |
| HIPAA BAA |
Available for eligible customers |
PII Redaction Before API Calls
import re
import anthropic
def redact_pii(text: str) -> tuple[str, dict]:
"""Redact PII before sending to Claude, return redaction map for restoration."""
redaction_map = {}
patterns = [
(r'\b\d{3}-\d{2}-\d{4}\b', 'SSN', '[SSN-REDACTED-{}]'),
(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b', 'EMAIL', '[EMAIL-REDACTED-{}]'),
(r'\b\d{3}[-.]?\d{3}[-.]?\d{4}\b', 'PHONE', '[PHONE-REDACTED-{}]'),
(r'\b\d{4}[- ]?\d{4}[- ]?\d{4}[- ]?\d{4}\b', 'CARD', '[CARD-REDACTED-{}]'),
]
counter = 0
for pattern, label, replacement in patterns:
for match in re.finditer(pattern, text):
counter += 1
placeholder = replacement.format(counter)
redaction_map[placeholder] = match.group()
text = text.replace(match.group(), placeholder, 1)
return text, redaction_map
def restore_pii(text: str, redaction_map: dict) -> str:
"""Restore redacted PII in Claude's response."""
for placeholder, original in redaction_map.items():
text = text.replace(placeholder, original)
return text
# Usage
user_input = "Contact John at john@example.com or 555-123-4567"
safe_input, redactions = redact_pii(user_input)
# safe_input: "Contact John at [EMAIL-REDACTED-1] or [PHONE-REDACTED-2]"
client = anthropic.Anthropic()
msg = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=256,
messages=[{"role": "user", "content": safe_input}]
)
final_output = restore_pii(msg.content[0].text, redactions)
Audit Logging
import json
import logging
from datetime import datetime, timezone
audit_logger = logging.getLogger("claude.audit")
def audited_request(client, user_id: str, purpose: str, **kwargs):
"""Wrap Claude API calls with audit logging."""
# Log request metadata (never log content)
audit_logger.info(json.dumps({
"event": "claude.request",
"timestamp": datetime.now(timezone.utc).isoformat(),
"user_id": user_id,
"purpose": purpose,
"model": kwargs.get("model"),
"max_tokens": kwargs.get("max_tokens"),
}))
response = client.messages.create(**kwargs)
audit_logger.info(json.dumps({
"event": "claude.response",
"request_id": response._request_id,
"input_tokens": response.usage.input_tokens,
"output_tokens": response.usage.output_tokens,
"stop_reason": response.stop_reason,
}))
return response
Data Handling Checklist
Error Handling
| Risk |
Mitigation |
| PII in prompts |
Pre-call redaction pipeline |
| PII in responses |
Post-call output scanning |
| Audit log gaps |
Centralized logging with alerting |
| Data subject access request |
Searchable audit trail by user_id |
Resources
Next Steps
For enterprise access control, see anth-enterprise-rbac.
1---2name: anth-data-handling3description: |4 Implement data privacy, PII handling, and compliance patterns for Claude API.5 Use when handling sensitive data, implementing PII redaction,6 or configuring data retention for GDPR/CCPA compliance with Claude.7 Trigger with phrases like "anthropic data privacy", "claude PII",8 "anthropic gdpr", "claude data handling", "redact data claude".9allowed-tools: Read, Write, Edit, Grep10version: 1.0.011license: MIT12author: Jeremy Longshore <jeremy@intentsolutions.io>13tags: [saas, ai, anthropic]14compatible-with: claude-code15---1617# Anthropic Data Handling1819## Overview2021Anthropic's data policies: API inputs/outputs are NOT used for model training (commercial API). Zero-day retention is available. This skill covers PII redaction before sending to Claude and compliance patterns.2223## Anthropic Data Policies2425| Policy | Details |26|--------|---------|27| Training data | API data is NOT used for training (commercial API) |28| Data retention | 30-day default; 0-day available via agreement |29| Encryption | TLS 1.2+ in transit, AES-256 at rest |30| SOC 2 Type II | Certified |31| HIPAA BAA | Available for eligible customers |3233## PII Redaction Before API Calls3435```python36import re37import anthropic3839def redact_pii(text: str) -> tuple[str, dict]:40 """Redact PII before sending to Claude, return redaction map for restoration."""41 redaction_map = {}42 patterns = [43 (r'\b\d{3}-\d{2}-\d{4}\b', 'SSN', '[SSN-REDACTED-{}]'),44 (r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b', 'EMAIL', '[EMAIL-REDACTED-{}]'),45 (r'\b\d{3}[-.]?\d{3}[-.]?\d{4}\b', 'PHONE', '[PHONE-REDACTED-{}]'),46 (r'\b\d{4}[- ]?\d{4}[- ]?\d{4}[- ]?\d{4}\b', 'CARD', '[CARD-REDACTED-{}]'),47 ]4849 counter = 050 for pattern, label, replacement in patterns:51 for match in re.finditer(pattern, text):52 counter += 153 placeholder = replacement.format(counter)54 redaction_map[placeholder] = match.group()55 text = text.replace(match.group(), placeholder, 1)5657 return text, redaction_map5859def restore_pii(text: str, redaction_map: dict) -> str:60 """Restore redacted PII in Claude's response."""61 for placeholder, original in redaction_map.items():62 text = text.replace(placeholder, original)63 return text6465# Usage66user_input = "Contact John at john@example.com or 555-123-4567"67safe_input, redactions = redact_pii(user_input)68# safe_input: "Contact John at [EMAIL-REDACTED-1] or [PHONE-REDACTED-2]"6970client = anthropic.Anthropic()71msg = client.messages.create(72 model="claude-sonnet-4-20250514",73 max_tokens=256,74 messages=[{"role": "user", "content": safe_input}]75)76final_output = restore_pii(msg.content[0].text, redactions)77```7879## Audit Logging8081```python82import json83import logging84from datetime import datetime, timezone8586audit_logger = logging.getLogger("claude.audit")8788def audited_request(client, user_id: str, purpose: str, **kwargs):89 """Wrap Claude API calls with audit logging."""90 # Log request metadata (never log content)91 audit_logger.info(json.dumps({92 "event": "claude.request",93 "timestamp": datetime.now(timezone.utc).isoformat(),94 "user_id": user_id,95 "purpose": purpose,96 "model": kwargs.get("model"),97 "max_tokens": kwargs.get("max_tokens"),98 }))99100 response = client.messages.create(**kwargs)101102 audit_logger.info(json.dumps({103 "event": "claude.response",104 "request_id": response._request_id,105 "input_tokens": response.usage.input_tokens,106 "output_tokens": response.usage.output_tokens,107 "stop_reason": response.stop_reason,108 }))109110 return response111```112113## Data Handling Checklist114115- [ ] PII redacted before sending to Claude API116- [ ] Audit logs capture who accessed what and when117- [ ] Logs never contain message content or PII118- [ ] Data retention policy matches your compliance needs119- [ ] Zero-day retention enabled if required (contact Anthropic)120- [ ] HIPAA BAA in place if handling PHI121- [ ] User consent obtained for AI processing122- [ ] Data deletion procedures documented123124## Error Handling125126| Risk | Mitigation |127|------|------------|128| PII in prompts | Pre-call redaction pipeline |129| PII in responses | Post-call output scanning |130| Audit log gaps | Centralized logging with alerting |131| Data subject access request | Searchable audit trail by user_id |132133## Resources134135- [Anthropic Privacy Policy](https://www.anthropic.com/privacy)136- [Anthropic Security](https://www.anthropic.com/security)137- [Usage Policy](https://www.anthropic.com/usage-policy)138139## Next Steps140141For enterprise access control, see `anth-enterprise-rbac`.142