What You’ll Learn
- Creating a sandbox with a
SecurityPolicy containing PIIConfig
- Configuring specific PII types to detect (
email, phone, ssn, credit_card)
- Setting the redaction action (
redact replaces PII with tokens like [REDACTED_EMAIL])
- Understanding that PII redaction operates on HTTP traffic, not stdout
- Listing all available
PIIType and RedactionAction enum values
How PII Redaction Works
PII redaction operates via a MITM TLS proxy that intercepts HTTP traffic between the sandbox and external APIs (e.g., OpenAI, Anthropic). It does not scan stdout.
- Code inside the sandbox makes an HTTP request containing PII
- The proxy intercepts the request and scans for configured PII types
- Detected PII is replaced with redaction tokens (e.g.,
[REDACTED_EMAIL])
- The sanitized request is forwarded to the external API
PII scanning via the guardrails service is rolling out. This example demonstrates the SDK API for configuring PII policies — sandbox creation with the policy works today and the policy is stored and returned on the sandbox object.
Prerequisites
Code Walkthrough
Build a SecurityPolicy with PIIConfig and pass it at sandbox creation:from declaw import Sandbox, SecurityPolicy, PIIConfig, PIIType, RedactionAction
policy = SecurityPolicy(
pii=PIIConfig(
enabled=True,
types=["email", "phone", "ssn", "credit_card"],
action="redact",
)
)
print(f"Security policy to apply:\n{policy.to_json()}")
sbx = Sandbox.create(template="python", timeout=300, security=policy)
Verify the sandbox info to confirm it was created with the policy:info = sbx.get_info()
print(f" Sandbox ID: {info.sandbox_id}")
print(f" Template: {info.template_id}")
print(f" State: {info.state.value}")
Running a script that prints PII to stdout does NOT trigger redaction — the proxy only watches HTTP traffic:pii_script = """\
import json
data = {
"name": "Jane Doe",
"email": "jane.doe@example.com",
"phone": "555-867-5309",
"ssn": "123-45-6789",
"credit_card": "4111-1111-1111-1111",
}
print(json.dumps(data, indent=2))
"""
sbx.files.write("/tmp/pii_demo.py", pii_script)
result = sbx.commands.run("python3 /tmp/pii_demo.py")
# stdout will show the original PII — only HTTP requests are intercepted
List all available PII types and redaction actions:for pii_type in PIIType:
print(f" {pii_type.name:15s} = {pii_type.value!r}")
for action in RedactionAction:
print(f" {action.name:10s} = {action.value!r}")
Use createSecurityPolicy() and createPIIConfig() helpers:import {
Sandbox,
createSecurityPolicy,
createPIIConfig,
PIIType,
RedactionAction,
} from "@declaw/sdk";
const policy = createSecurityPolicy({
pii: createPIIConfig({
enabled: true,
types: [PIIType.Email, PIIType.Phone, PIIType.SSN, PIIType.CreditCard],
action: RedactionAction.Redact,
}),
});
console.log("Security policy to apply:");
console.log(JSON.stringify(policy, null, 2));
const sbx = await Sandbox.create({
template: "python",
timeout: 300,
security: policy,
});
List all available enum values:for (const [name, value] of Object.entries(PIIType)) {
console.log(` ${name.padEnd(15)} = ${JSON.stringify(value)}`);
}
for (const [name, value] of Object.entries(RedactionAction)) {
console.log(` ${name.padEnd(10)} = ${JSON.stringify(value)}`);
}
Available PII Types
| PIIType | Detects |
|---|
email | Email addresses |
phone | Phone numbers |
ssn | US Social Security Numbers |
credit_card | Credit card numbers |
Available Redaction Actions
| Action | Behavior |
|---|
redact | Replaces PII with a placeholder token; request is forwarded |
block | Rejects the entire request if PII is detected |
log_only | Logs the detection but passes the request unchanged |
When PII Is Redacted
"jane.doe@example.com" -> "[REDACTED_EMAIL]"
"555-867-5309" -> "[REDACTED_PHONE]"
"123-45-6789" -> "[REDACTED_SSN]"
"4111-1111-1111-1111" -> "[REDACTED_CREDIT_CARD]"