> ## Documentation Index
> Fetch the complete documentation index at: https://docs.declaw.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# PII Redaction

> Configure automatic PII detection and redaction for outbound HTTP traffic from a Declaw sandbox.

## 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 TLS proxy that intercepts HTTP traffic between the sandbox and external APIs (e.g., OpenAI, Anthropic). It does **not** scan `stdout`.

1. Code inside the sandbox makes an HTTP request containing PII
2. The proxy intercepts the request and scans for configured PII types
3. Detected PII is replaced with redaction tokens (e.g., `[REDACTED_EMAIL]`)
4. The sanitized request is forwarded to the external API

<Note>
  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.
</Note>

## Prerequisites

<Snippet file="snippets/env-setup.mdx" />

## Code Walkthrough

<Tabs>
  <Tab title="Python">
    Build a `SecurityPolicy` with `PIIConfig` and pass it at sandbox creation:

    ```python theme={null}
    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:

    ```python theme={null}
    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:

    ```python theme={null}
    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:

    ```python theme={null}
    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}")
    ```
  </Tab>

  <Tab title="TypeScript">
    Use `createSecurityPolicy()` and `createPIIConfig()` helpers:

    ```typescript theme={null}
    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:

    ```typescript theme={null}
    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)}`);
    }
    ```
  </Tab>
</Tabs>

## 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]"
```
