Skip to main content
NetworkPolicy provides fine-grained control over what network destinations a sandbox can reach. It operates at two layers: kernel-level IP filtering via iptables and application-level domain filtering via the per-namespace TCP proxy.

NetworkPolicy model

from declaw import NetworkPolicy, SecurityPolicy, ALL_TRAFFIC

policy = SecurityPolicy(
    network=NetworkPolicy(
        allow_out=["*.openai.com", "pypi.org", "1.1.1.1"],
        deny_out=[ALL_TRAFFIC],
        allow_public_traffic=False,
        mask_request_host="internal-proxy.corp.com",
    )
)
FieldTypeDefaultDescription
allow_outlist[str][]Domains, IPs, or CIDRs to allow outbound
deny_outlist[str][]Domains, IPs, or CIDRs to deny outbound
allow_public_trafficbool | NoneTrueWhether inbound connections to sandbox ports are open
mask_request_hoststr | NoneNoneOverride the Host header on outbound requests

Domain-based rules

Domain entries in allow_out and deny_out are matched against the TLS SNI field (HTTPS) or HTTP Host header (HTTP).

Exact match

NetworkPolicy(allow_out=["api.openai.com"])  # matches only api.openai.com

Wildcard subdomains

NetworkPolicy(allow_out=["*.openai.com"])
# Matches: api.openai.com, platform.openai.com, files.openai.com
# Does not match: openai.com (no subdomain)

Regex patterns

Prefix the entry with ~ to use a regex:
NetworkPolicy(allow_out=["~.*\\.anthropic\\.com"])
# Matches any subdomain or path at anthropic.com

IP and CIDR rules

IP and CIDR entries bypass the domain proxy and are applied directly as iptables rules in the kernel — zero userspace overhead.
NetworkPolicy(
    allow_out=["1.1.1.1", "8.8.8.0/24", "10.0.0.0/8"],
    deny_out=[ALL_TRAFFIC],
)
ALL_TRAFFIC is equivalent to "0.0.0.0/0".

Priority rules

Allow rules always take precedence over deny rules, regardless of the order they are listed.
# This allows 1.1.1.1 even though 0.0.0.0/0 is denied
NetworkPolicy(
    allow_out=["1.1.1.1"],
    deny_out=[ALL_TRAFFIC],
)

Metadata service blocking

The cloud instance metadata endpoint (169.254.169.254) is always blocked in all sandboxes, regardless of the network policy. This prevents SSRF attacks where agent code could exfiltrate cloud credentials.
result = sbx.commands.run("curl -s http://169.254.169.254/latest/meta-data/")
# Always fails — blocked at iptables level before any proxy
Do not attempt to allow 169.254.169.254 — it is blocked by a hardcoded DROP rule that cannot be overridden by the sandbox network policy.

DNS auto-allowlist

When domain-based filtering is active, DNS queries must succeed for the domain filter to work. Declaw automatically allows outbound UDP and TCP traffic to 8.8.8.8 (Google DNS) when any domain entries appear in allow_out or deny_out. You do not need to add 8.8.8.8 manually.

How the TCP proxy works

The proxy runs in the host network namespace for the sandbox’s network namespace. All TCP traffic from the VM is redirected to the proxy via iptables REDIRECT rules applied to the per-sandbox veth interface. For HTTPS connections, the proxy peeks at the TLS ClientHello (without decrypting) to extract the SNI hostname. For HTTP connections, it reads the first line of the request to find the Host header. If the hostname is in the allowlist and no body scanning is required, the proxy connects to the real destination and forwards the TCP stream directly without any TLS interception. This means there is no TLS overhead for pure network policies.

Combine with SecurityPolicy for full control

NetworkPolicy as a field inside SecurityPolicy integrates with PII scanning and audit logging:
from declaw import Sandbox, SecurityPolicy, NetworkPolicy, PIIConfig, ALL_TRAFFIC

sbx = Sandbox.create(
    security=SecurityPolicy(
        network=NetworkPolicy(
            allow_out=["*.openai.com", "*.anthropic.com"],
            deny_out=[ALL_TRAFFIC],
        ),
        pii=PIIConfig(enabled=True, types=["ssn", "email"], action="redact"),
        audit=True,
    )
)
In this configuration:
  1. iptables drops all non-DNS outbound traffic by default
  2. TCP proxy intercepts connections to *.openai.com and *.anthropic.com
  3. PII scanner activates TLS interception on those allowed domains
  4. All events are logged to the audit trail

GCP and AWS firewall hardening

At the infrastructure level, the deploy scripts configure cloud firewalls to restrict SSH access to your deployer IP only. The sandbox-level network policies provide defense-in-depth on top of the cloud firewall.
LayerEnforced byControls
Cloud firewallGCP/AWS security groupsSSH access, inbound ports to the Declaw node
Sandbox network namespaceiptables rules per-vethIP/CIDR outbound policies
TCP proxyPer-namespace Go processDomain-level outbound policies
TLS interceptionSecurity proxy MITM CABody-level PII and injection scanning