> ## 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.

# Custom transformation rules

> Regex-based directional rewrites applied at the sandbox's edge proxy. End-to-end proof that outbound bodies are rewritten before the request leaves the VM.

## Use case

Redact internal identifiers, credentials, or any structured pattern
from outbound HTTP bodies before they reach third-party services.
Rules run at the sandbox's edge proxy — they don't require any
scanner model, just a regex, and fire on every request to allowed
destinations.

Three common rule shapes:

| Pattern            | Replacement              | Direction     |
| ------------------ | ------------------------ | ------------- |
| `INTERNAL-\d+`     | `[TICKET_REDACTED]`      | outbound only |
| `AKIA[0-9A-Z]{16}` | `***AWS_KEY_REDACTED***` | outbound only |
| `password=\w+`     | `password=[FILTERED]`    | both          |

## Template

`python` — any template works; this recipe uses python for the
verification probe.

## Run it

```bash theme={null}
export DECLAW_API_KEY=dcl_...
export DECLAW_DOMAIN=api.declaw.ai

python cookbook/examples/openai-agents-transformations/main.py
```

## Security policy

```python theme={null}
SecurityPolicy(
    transformations=[
        TransformationRule(
            match=r"INTERNAL-\d+",
            replace="[TICKET_REDACTED]",
            direction="outbound",
        ),
        TransformationRule(
            match=r"AKIA[0-9A-Z]{16}",
            replace="***AWS_KEY_REDACTED***",
            direction="outbound",
        ),
        TransformationRule(
            match=r"password=\w+",
            replace="password=[FILTERED]",
            direction="both",
        ),
    ],
    network=NetworkPolicy(allow_out=["httpbin.org"]),
)
```

## How the proof works

1. Python script inside the sandbox POSTs a JSON payload to
   `httpbin.org/post`. The payload contains all three trigger
   patterns in raw form (`INTERNAL-4242`, `AKIAIOSFODNN7EXAMPLE`,
   `password=hunter2`).
2. The edge proxy rewrites every rule with `direction="outbound"`
   or `"both"` before the request leaves the VM.
3. httpbin.org echoes back what it received. The sandbox reads the
   echo, prints it as `DEST_SAW:`, and the Python driver reads it
   back through `run_command`.
4. Three assertions run — each rule must remove the original and
   insert the replacement.

## Expected output

```
== original payload ==
{"ticket": "INTERNAL-4242", "aws_key": "AKIAIOSFODNN7EXAMPLE", ...}

== what httpbin.org received (after outbound transformations) ==
{"ticket": "[TICKET_REDACTED]", "aws_key": "***AWS_KEY_REDACTED***", ...}

== assertions ==
  PASS INTERNAL-4242 redacted  removed_original=True  replacement_present=True
  PASS AWS key redacted  removed_original=True  replacement_present=True
  PASS password filtered  removed_original=True  replacement_present=True
```

## Direction reference

| `direction=` | Applies when                          |
| ------------ | ------------------------------------- |
| `outbound`   | Sandbox -> internet (request bodies)  |
| `inbound`    | Internet -> sandbox (response bodies) |
| `both`       | Both request and response bodies      |

Use `inbound` or `both` when your concern is *received* content —
e.g. if an upstream service might leak credentials in its response
and you want them stripped before the sandbox code sees them.

## Full source

See `cookbook/examples/openai-agents-transformations/main.py` in the repo.
