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

# Agent in Sandbox with Network Policy

> Run an autonomous agent inside a Declaw sandbox that has a network allow-list. Only traffic to explicitly permitted domains is allowed; all other outbound connections are blocked.

## What You'll Learn

* How to create a sandbox with `network={"allow_out": [...]}` to restrict outbound access
* How to write an agent that tests TCP connectivity from inside the sandbox
* How to verify that non-allowlisted destinations are blocked
* The pattern of combining agent execution with network-level isolation

## Prerequisites

* Declaw running locally or in the cloud (see [Deployment](/deployment/overview))
* `DECLAW_API_KEY` and `DECLAW_DOMAIN` set in your environment

<Note>
  This example is available in Python. TypeScript support coming soon.
</Note>

## Code Walkthrough

### 1. Create the sandbox with a network allow-list

```python theme={null}
from declaw import Sandbox

allowed_domain = "api.github.com"

sbx = Sandbox.create(
    template="python",
    timeout=300,
    network={"allow_out": [allowed_domain]},
)
```

The `network` parameter accepts an object with `allow_out` (list of allowed domains) or `deny_out` (list of denied domains). When `allow_out` is specified, all traffic except to listed domains is blocked. See [Network Policies](/security/network-policies) for full details.

### 2. The agent script — testing connectivity

The agent script runs inside the sandbox and tests TCP connectivity to several hosts:

```python theme={null}
AGENT_SCRIPT = textwrap.dedent("""\
    import socket
    import json

    def test_connection(host, port, timeout=5):
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.settimeout(timeout)
            s.connect((host, port))
            s.close()
            return {"host": host, "port": port, "status": "CONNECTED"}
        except Exception as e:
            return {"host": host, "port": port, "status": f"BLOCKED: {e}"}

    with open("/tmp/test_plan.json") as f:
        test_plan = json.load(f)

    results = []
    for test in test_plan["targets"]:
        result = test_connection(test["host"], test["port"])
        status_icon = "OK" if result["status"] == "CONNECTED" else "XX"
        print(f"  [{status_icon}] {result['host']}:{result['port']} -> {result['status']}")
        results.append(result)

    with open("/tmp/results.json", "w") as f:
        json.dump(results, f, indent=2)
""")
```

### 3. Upload the test plan and run the agent

```python theme={null}
test_plan = {
    "targets": [
        {"host": "1.1.1.1", "port": 80, "note": "Cloudflare DNS - not in allow list"},
        {"host": "8.8.8.8", "port": 53, "note": "Google DNS - not in allow list"},
        {"host": "93.184.216.34", "port": 80, "note": "example.com - not in allow list"},
    ],
}

sbx.files.write("/tmp/agent.py", AGENT_SCRIPT)
sbx.files.write("/tmp/test_plan.json", json.dumps(test_plan, indent=2))

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

### 4. Read and analyze results

```python theme={null}
result_content = sbx.files.read("/tmp/results.json")
results = json.loads(result_content)

blocked = sum(1 for r in results if "BLOCKED" in r["status"])
connected = sum(1 for r in results if r["status"] == "CONNECTED")
print(f"Blocked: {blocked} / {len(results)}")
```

## Expected Output

```
--- Creating Sandbox with Network Policy ---
  Policy: allow_out=['api.github.com']
  All other outbound traffic will be blocked.
  Sandbox created: sbx-abc123

--- Running Network Test Agent ---

  Agent output:
    === Network Connectivity Test Results ===
      [XX] 1.1.1.1:80 -> BLOCKED: [Errno 110] Connection timed out
      [XX] 8.8.8.8:53 -> BLOCKED: [Errno 110] Connection timed out
      [XX] 93.184.216.34:80 -> BLOCKED: [Errno 110] Connection timed out

    Tested 3 targets.

--- Analyzing Results ---
  Total targets tested: 3
  Blocked:              3
  Connected:            0

  [PASS] Network policy is blocking non-allowlisted traffic.
```

## How Network Policy + Agent Isolation Work Together

```
Agent process (inside sandbox)
        │
        │  TCP connect to 8.8.8.8:53
        ▼
  ┌─────────────────────────────────────┐
  │  Declaw Network Namespace           │
  │                                     │
  │  Firewall REDIRECT → TCP Proxy      │
  │                                     │
  │  Proxy checks: 8.8.8.8 not in       │
  │  allow_out=['api.github.com']        │
  │                                     │
  │  Action: RST (connection refused)   │
  └─────────────────────────────────────┘
```

The proxy enforces network policy at the TCP layer, not the application layer. This means the restriction applies to all processes inside the sandbox — not just the primary agent — regardless of what language or library they use.

## Combining with SecurityPolicy

For defense-in-depth, combine network policies with a full `SecurityPolicy`:

```python theme={null}
from declaw import Sandbox, SecurityPolicy, PIIConfig, AuditConfig

sbx = Sandbox.create(
    template="python",
    timeout=300,
    network={"allow_out": ["api.github.com"]},
    security=SecurityPolicy(
        pii=PIIConfig(enabled=True, types=["email", "ssn"], action="redact"),
        audit=AuditConfig(enabled=True),
    ),
)
```

See the [Secured Agent](/cookbook/agent-in-sandbox/secured) example for the full security stack.
