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)
DECLAW_API_KEY and DECLAW_DOMAIN set in your environment
This example is available in Python. TypeScript support coming soon.
Code Walkthrough
1. Create the sandbox with a network allow-list
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 for full details.
2. The agent script — testing connectivity
The agent script runs inside the sandbox and tests TCP connectivity to several hosts:
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
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
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 │
│ │
│ iptables 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:
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, log_request_body=True),
),
)
See the Secured Agent example for the full security stack.