Skip to main content

What You’ll Learn

  • How to configure every security layer in the Declaw SDK in a single SecurityPolicy
  • How transformation rules mask internal hostnames and API key patterns in transit
  • How to inspect the configured security policy programmatically
  • The defense-in-depth model: six independent layers that work together

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 Layers Configured

LayerConfiguration
Network Policyallow_out=['api.github.com'] — all other traffic blocked
PII RedactionEmail, phone, SSN, credit card auto-redacted
Injection DefenseHigh sensitivity, block action
Audit LoggingRequest bodies logged, 72-hour retention
Transformation RulesInternal hostnames and API key patterns masked

Code Walkthrough

1. Define transformation rules

Transformation rules apply regex replacements to HTTP request and response bodies passing through the proxy:
from declaw import TransformationRule

transformation_rules = [
    TransformationRule(
        match=r"internal\.corp\.example\.com",
        replace="api.example.com",
        direction="outbound",
    ),
    TransformationRule(
        match=r"Bearer sk-[a-zA-Z0-9]+",
        replace="Bearer [MASKED]",
        direction="both",
    ),
]

2. Build the full SecurityPolicy

from declaw import (
    SecurityPolicy,
    PIIConfig,
    InjectionDefenseConfig,
    AuditConfig,
)

security = SecurityPolicy(
    pii=PIIConfig(
        enabled=True,
        types=["email", "phone", "ssn", "credit_card"],
        action="redact",
    ),
    injection_defense=InjectionDefenseConfig(
        enabled=True,
        sensitivity="high",
        action="block",
    ),
    audit=AuditConfig(
        enabled=True,
        log_request_body=True,
        log_response_body=False,
        retention_hours=72,
    ),
    transformations=transformation_rules,
)

3. Create the sandbox with network policy and security policy

from declaw import Sandbox

sbx = Sandbox.create(
    template="python",
    timeout=300,
    network={"allow_out": ["api.github.com"]},
    security=security,
)

4. The agent script (runs inside the secured sandbox)

The agent processes PII-like data and tests network connectivity. In a live deployment with the guardrails service active, any email or phone number in HTTP traffic would be redacted before leaving the sandbox:
AGENT_SCRIPT = textwrap.dedent("""\
    import json, socket, subprocess

    # System info
    print("--- System Information ---")
    result = subprocess.run(["uname", "-a"], capture_output=True, text=True)
    print(f"  Kernel: {result.stdout.strip()}")

    # Data processing with PII-like data
    print()
    print("--- Data Processing (PII-like data) ---")
    records = [
        {"name": "Alice Smith", "email": "alice@example.com", "phone": "555-0101"},
        {"name": "Bob Jones",   "email": "bob@example.com",   "phone": "555-0102"},
    ]
    for r in records:
        print(f"  - {r['name']} (email: {r['email']})")
    print("  NOTE: PII in HTTP traffic would be redacted in a live deployment.")

    # Network test
    print()
    print("--- Network Connectivity ---")
    for host, port, label in [("1.1.1.1", 80, "Cloudflare"), ("8.8.8.8", 53, "Google DNS")]:
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.settimeout(3)
            s.connect((host, port))
            s.close()
            print(f"  {label} ({host}:{port}): CONNECTED")
        except Exception:
            print(f"  {label} ({host}:{port}): BLOCKED")

    # Write results
    output = {"status": "completed", "tasks_run": 3, "records_processed": len(records)}
    with open("/tmp/agent_output.json", "w") as f:
        json.dump(output, f, indent=2)
""")

5. Run the agent and inspect results

sbx.files.write("/tmp/agent.py", AGENT_SCRIPT)
result = sbx.commands.run("python3 /tmp/agent.py", timeout=60)
print(result.stdout)

# Read structured output
output_content = sbx.files.read("/tmp/agent_output.json")
agent_output = json.loads(output_content)

Expected Output

--- Configuring Full Security Stack ---

  Security Policy Configuration:
    {"pii": {"enabled": true, "types": ["email","phone","ssn","credit_card"], ...}}

  [PII Redaction]
    enabled:  True
    types:    ['email', 'phone', 'ssn', 'credit_card']
    action:   redact

  [Injection Defense]
    enabled:     True
    sensitivity: high
    action:      block

  [Audit Logging]
    enabled:           True
    log_request_body:  True
    log_response_body: False
    retention_hours:   72

  [Transformation Rules]
    1. match='internal\\.corp\\.example\\.com'  replace='api.example.com'  direction=outbound
    2. match='Bearer sk-[a-zA-Z0-9]+'  replace='Bearer [MASKED]'  direction=both

--- Creating Fully Secured Sandbox ---
  Sandbox created: sbx-abc123
  State: running

--- Running Agent in Secured Sandbox ---
  Agent output:
    --- System Information ---
      Kernel: Linux ... x86_64 GNU/Linux
    --- Data Processing (PII-like data) ---
      - Alice Smith (email: alice@example.com)
      - Bob Jones (email: bob@example.com)
    --- Network Connectivity ---
      Cloudflare (1.1.1.1:80): BLOCKED
      Google DNS (8.8.8.8:53): BLOCKED

Defense-in-Depth Summary

1. Sandbox Isolation    — Agent code in isolated Firecracker microVM, no host access
2. Network Policy       — allow_out=['api.github.com'], all other traffic blocked
3. PII Redaction        — Email, phone, SSN, credit card auto-redacted in HTTP traffic
4. Injection Defense    — High sensitivity, block action, prompt injection attempts stopped
5. Audit Logging        — All proxy traffic logged with 72h retention for compliance
6. Transformation Rules — Internal hostnames and API keys masked in transit
Each layer operates independently. A failure in one layer (for example, a misconfigured transformation rule) does not reduce the protection provided by the others.