Skip to main content
OpenSandbox provides comprehensive networking capabilities for sandboxes, including ingress routing to access services running inside sandboxes and egress control to restrict outbound network access.

Architecture

OpenSandbox networking consists of two main components:

Ingress Gateway

Routes external traffic to sandbox services via HTTP/HTTPS endpoints

Egress Control

Enforces network policies to restrict outbound traffic from sandboxes

Ingress routing

The Ingress Gateway provides HTTP/HTTPS access to services running inside sandboxes.

How it works

  1. Service binding: When you create a sandbox, you can expose ports
  2. Dynamic routing: The gateway creates routes based on sandbox ID and port
  3. Endpoint generation: Get public URLs via sandbox.get_endpoint(port)
  4. Traffic forwarding: Requests are proxied to the sandbox container

Getting endpoints

Retrieve the public URL for a service running in a sandbox:
# Start a web server in the sandbox
await sandbox.commands.run_background(
    "python -m http.server 8000",
    working_dir="/workspace"
)

# Get the public endpoint
endpoint = await sandbox.get_endpoint(8000)
print(f"Access at: {endpoint}")
# https://api.opensandbox.io/sandboxes/sb-abc123/port/8000

Routing modes

The Ingress Gateway supports multiple routing strategies:
Routes based on URL path:Format: https://domain/sandboxes/{sandboxId}/port/{port}Configuration:
[ingress]
mode = "uri"
domain = "api.opensandbox.io"
Example: https://api.opensandbox.io/sandboxes/sb-123/port/8000

WebSocket support

The Ingress Gateway supports WebSocket connections for real-time applications:
# Start a WebSocket server
await sandbox.commands.run_background(
    "python websocket_server.py",
    working_dir="/workspace"
)

endpoint = await sandbox.get_endpoint(8080)
# ws://api.opensandbox.io/sandboxes/sb-123/port/8080
Use cases:
  • VNC access for desktop environments
  • Real-time collaboration tools
  • Live terminal sessions
  • Interactive debugging

Egress control

The Egress Control component restricts outbound network access from sandboxes using FQDN-based policies.

Network policies

Define allowed or denied domains when creating a sandbox:
from opensandbox.models import NetworkPolicy, EgressRule

sandbox = await Sandbox.create(
    "python:3.11",
    network_policy=NetworkPolicy(
        egress=[
            EgressRule(domain="*.pypi.org", action="allow"),
            EgressRule(domain="github.com", action="allow"),
            EgressRule(domain="*", action="deny")
        ]
    )
)
This sandbox can only access PyPI and GitHub.

Policy rules

domain
string
required
Domain pattern with wildcard support:
  • example.com - Exact match
  • *.example.com - All subdomains
  • * - All domains (catch-all)
action
string
required
Action to take: allow or deny
priority
number
Rule priority (lower = higher priority). Defaults to order in array.

How egress control works

The egress sidecar intercepts DNS queries and network traffic:
1

DNS interception

The sidecar runs a DNS proxy that intercepts all DNS queries from the sandbox
2

Policy evaluation

Each DNS query is matched against the network policy rules
3

Traffic filtering

Allowed domains are resolved normally; denied domains return NXDOMAIN
4

nftables enforcement

IP-based rules are configured using nftables for additional enforcement

Deployment modes

The egress sidecar runs as a separate container sharing the network namespace:
[docker]
enable_egress_sidecar = true
egress_sidecar_image = "opensandbox/egress:v1.0.0"
Resource impact:
  • CPU: ~10m (0.01 core)
  • Memory: ~50 MiB

Network isolation

Docker networking modes

Sandbox uses the host’s network stack:
[docker]
network_mode = "host"
Pros: Better performance, simpler port access Cons: No network isolation, port conflictsUse case: Single-tenant environments, development

Kubernetes network policies

In Kubernetes, use NetworkPolicy for pod-level isolation:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: sandbox-isolation
spec:
  podSelector:
    matchLabels:
      sandbox.opensandbox.io/managed: "true"
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: opensandbox-system
  egress:
  - to:
    - namespaceSelector: {}
    ports:
    - protocol: TCP
      port: 53  # DNS

Security considerations

Important: Network policies are enforced at the DNS and IP layers. Sandboxes with root access can potentially bypass these restrictions. For maximum security:
  1. Drop Linux capabilities (CAP_NET_RAW, CAP_NET_ADMIN)
  2. Use read-only root filesystems
  3. Apply seccomp profiles
  4. Run containers as non-root users
from opensandbox.models import NetworkPolicy, SecurityContext

sandbox = await Sandbox.create(
    "python:3.11",
    network_policy=NetworkPolicy(
        egress=[
            EgressRule(domain="*.pypi.org", action="allow"),
            EgressRule(domain="*", action="deny")
        ]
    ),
    security_context=SecurityContext(
        capabilities_drop=["NET_RAW", "NET_ADMIN"],
        read_only_root_filesystem=True,
        run_as_non_root=True
    )
)

Common use cases

Expose web apps for manual or automated testing:
await sandbox.commands.run_background("npm start")
endpoint = await sandbox.get_endpoint(3000)
# Run Playwright tests against endpoint
Access VS Code Server or Jupyter Lab:
await sandbox.commands.run_background(
    "code-server --bind-addr 0.0.0.0:8080"
)
endpoint = await sandbox.get_endpoint(8080)
# Open in browser
Allow AI-generated code to install packages but block other network access:
sandbox = await Sandbox.create(
    "python:3.11",
    network_policy=NetworkPolicy(
        egress=[
            EgressRule(domain="pypi.org", action="allow"),
            EgressRule(domain="*.pypi.org", action="allow"),
            EgressRule(domain="*", action="deny")
        ]
    )
)
Access full desktop environments via VNC:
await sandbox.commands.run_background(
    "vncserver -geometry 1920x1080 -depth 24"
)
endpoint = await sandbox.get_endpoint(5900)
# Connect with VNC client

Troubleshooting

Symptoms: 502 Bad Gateway or connection refusedSolutions:
  1. Verify the service is running: await sandbox.commands.run("curl localhost:8000")
  2. Check the port number is correct
  3. Ensure the service binds to 0.0.0.0, not 127.0.0.1
  4. Wait for service startup (add health check)
Symptoms: Sandbox can access blocked domainsSolutions:
  1. Verify egress sidecar is enabled in config
  2. Check sidecar container is running: docker ps
  3. Review policy rule order (first match wins)
  4. Drop NET_RAW capability to prevent raw socket access
Symptoms: WebSocket upgrade failsSolutions:
  1. Ensure ingress gateway supports WebSocket (OpenSandbox does)
  2. Check for proxies that don’t support WebSocket
  3. Verify the application listens on the correct port

Ingress component

Deep dive into ingress gateway architecture

Egress component

Learn about egress control implementation

Security

Security best practices for networking

Configuration

Configure networking options

Build docs developers (and LLMs) love