How to Configure Network Egress Controls with Specific Policies for Each Sandbox in OpenSandbox

You configure per-sandbox network egress controls in OpenSandbox by defining a networkPolicy object in the CreateSandbox API request, which triggers automatic injection of an egress sidecar that enforces DNS and IP-level rules via nftables without requiring elevated capabilities in the application container.

The alibaba/OpenSandbox repository implements granular outbound traffic filtering through an egress sidecar pattern. When you configure network egress controls, each sandbox can define its own whitelist or blacklist of domains and IPs through the networkPolicy field, enabling zero-trust network security for isolated workloads.

How the Egress Sidecar Enforces Network Policies

OpenSandbox implements outbound restrictions by injecting an egress sidecar into the sandbox’s network namespace. According to the architecture documented in components/egress/README.md, the sidecar operates two enforcement layers:

Layer 1: DNS Proxy Filtering

The sidecar runs a DNS proxy that intercepts all port 53 traffic within the namespace. When OPENSANDBOX_EGRESS_MODE is set to dns (the default), the proxy answers NXDOMAIN for denied domains, preventing resolution of restricted hostnames. This layer handles wildcard domain rules such as *.example.com by inspecting DNS queries before they reach external resolvers.

Layer 2: nftables IP Filtering

When you set OPENSANDBOX_EGRESS_MODE=dns+nft, the sidecar enables IP-level blocking using nftables. As documented in components/egress/README.md, the sidecar dynamically adds resolved IPs of allowed domains to an nftables allow set while dropping all other outbound IP traffic. This provides defense-in-depth when DNS filtering alone is insufficient.

Prerequisites for Enabling Egress Controls

Before you can configure per-sandbox policies, you must enable the egress sidecar in your server configuration.

Configure the Egress Sidecar Image

In your server configuration file (typically ~/.sandbox.toml or a custom config), specify the sidecar image in the [egress] block as shown in server/example.config.toml (lines 34-45):

[egress]
image = "opensandbox/egress:v1.0.1"

The opensandbox/egress image contains the proxy binary and nftables logic required for policy enforcement.

Enable Bridge Network Mode

The egress sidecar requires Docker bridge network mode. Ensure your server configuration sets network_mode = "bridge" as defined in server/example.config.toml. The sidecar runs with CAP_NET_ADMIN capability, while the application container executes without this privilege, maintaining least-privilege security.

Defining Network Policies in the CreateSandbox API

The networkPolicy field in the CreateSandbox request declares your egress rules. As specified in the OpenAPI schema at specs/sandbox-lifecycle.yml (lines 333-353), the policy structure contains:

  • defaultAction: Either allow or deny, setting the baseline behavior for outbound traffic
  • egress: An array of rules containing action (allow or deny) and target (domain or wildcard pattern)

When the server detects a networkPolicy in the request, it validates the configuration against the schema, pulls the sidecar image, and starts the container with --cap-add=NET_ADMIN in the same network namespace as the application container.

Implementation Examples by Platform

Python SDK Configuration

The OpenSandbox Python SDK accepts a NetworkPolicy object via the network_policy parameter. As documented in sdks/sandbox/python/README.md, you construct rules using NetworkRule instances:

from datetime import timedelta
from opensandbox.models.sandboxes import NetworkPolicy, NetworkRule
from opensandbox.sdk import Sandbox, ConnectionConfig

cfg = ConnectionConfig(
    api_key="your-key",
    domain="api.opensandbox.io",
)

policy = NetworkPolicy(
    defaultAction="deny",
    egress=[
        NetworkRule(action="allow", target="pypi.org"),
        NetworkRule(action="allow", target="*.python.org"),
    ],
)

sandbox = await Sandbox.create(
    "python:3.11-slim",
    connection_config=cfg,
    timeout=timedelta(minutes=30),
    resource={"cpu": "2", "memory": "4Gi"},
    network_policy=policy,
)

Raw HTTP API Request

For direct API integration, include the networkPolicy object in your JSON payload to the CreateSandbox endpoint:

curl -X POST http://localhost:8080/v1/sandboxes \
  -H "OPEN-SANDBOX-API-KEY: $OPEN_SANDBOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "image": {"uri": "python:3.11"},
        "timeout": 3600,
        "resourceLimits": {"cpu": "500m", "memory": "512Mi"},
        "networkPolicy": {
          "defaultAction": "allow",
          "egress": [
            {"action": "deny", "target": "bad.example.com"},
            {"action": "deny", "target": "*.tracking.com"}
          ]
        }
      }'

Manual Docker Deployment

For debugging or custom deployments, you can manually run the sidecar container:

docker pull opensandbox/egress:v1.0.1

docker run -d --name sandbox-egress \
  --cap-add=NET_ADMIN \
  opensandbox/egress:v1.0.1

Refer to components/egress/README.md for the complete "Build & Run" command reference.

Kubernetes Helm Configuration

When deploying via the OpenSandbox Helm chart (charts/opensandbox-controller), set the sidecar image in your values.yaml as shown in kubernetes/charts/opensandbox-controller/values.yaml (lines 129-131):

egress:
  image: "opensandbox/egress:v1.0.1"

The controller automatically injects the sidecar into Pods carrying the networkPolicy annotation.

Runtime Configuration Options

The egress sidecar behavior is controlled through environment variables defined in components/egress/README.md:

  • OPENSANDBOX_EGRESS_MODE: Set to dns (default) for DNS-only filtering or dns+nft for additional IP-level nftables enforcement
  • OPENSANDBOX_EGRESS_API_ADDR: HTTP API address for the sidecar
  • OPENSANDBOX_EGRESS_TOKEN: Authentication token for sidecar API access

To enable IP-level blocking, start the server with:

export OPENSANDBOX_EGRESS_MODE=dns+nft
opensandbox-server

Security Considerations and Limitations

As documented in oseps/0001-fqdn-based-egress-control.md, the sidecar implementation provides FQDN-based security without requiring CAP_NET_ADMIN in the application container. However, note that IPv6 traffic is currently disabled when the sidecar is injected, as noted in server/README.md. Additionally, the sidecar is only injected when a sandbox explicitly requests a networkPolicy; sandboxes without this field maintain unrestricted outbound access.

Summary

  • Network egress controls in OpenSandbox rely on an injected sidecar that operates in the sandbox's network namespace with CAP_NET_ADMIN privileges.
  • Configure the sidecar image in [egress] blocks within server/example.config.toml before enabling policies.
  • Define per-sandbox rules using the networkPolicy field in CreateSandbox requests, specifying defaultAction and egress rule arrays.
  • Enforcement occurs at Layer 1 (DNS proxy) by default, with optional Layer 2 (nftables) filtering when OPENSANDBOX_EGRESS_MODE=dns+nft.
  • The application container requires no additional Linux capabilities, maintaining security isolation.

Frequently Asked Questions

What happens if I omit the networkPolicy field when creating a sandbox?

If you do not include the networkPolicy field in your CreateSandbox request, the sandbox runs with unrestricted outbound network access. The egress sidecar is only injected when a policy is explicitly requested, ensuring backward compatibility and minimal overhead for sandboxes that do not require egress filtering.

Does my application container need NET_ADMIN capabilities?

No. According to the injection logic described in server/README.md, the egress sidecar container runs with CAP_NET_ADMIN while sharing the network namespace with the application container. Your application code executes without elevated networking capabilities, adhering to the principle of least privilege while still benefiting from fine-grained egress controls.

How are wildcard domains like *.example.com handled?

The DNS proxy layer resolves wildcard patterns by intercepting all port 53 traffic, as implemented in the sidecar architecture. When Layer 2 nftables enforcement is enabled (dns+nft mode), the sidecar automatically adds the resolved IP addresses of matching domains to the nftables allow set, ensuring that wildcard rules work correctly at both the DNS and IP filtering layers.

Can I use IPv6 with the egress sidecar enabled?

No. As noted in the server documentation at server/README.md, IPv6 traffic is explicitly disabled when the egress sidecar is injected into the sandbox network namespace. This limitation is part of the current implementation and should be considered when architecting network policies for sandboxes requiring egress controls.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →