# Network

`SandboxNetworkPolicy` controls outbound traffic for a sandbox.

Use `mode` as the default fallback, and use `egress.trafficRules` for explicit ordered allow and deny behavior.

## Policy Shape

| Field | Description |
|-------|-------------|
| `mode` | Default fallback for unmatched traffic: `allow-all` or `block-all` |
| `egress.trafficRules` | Ordered allow/deny rules. First matching rule wins |
| `egress.protocolRules` | Protocol-aware operation controls for allowed traffic. See [Protocol Controls](/docs/sandbox/protocol-controls) |
| `egress.credentialRules` | Destination-scoped outbound auth rules, optionally constrained by HTTP request matchers. See [Credential / Egress Auth](/docs/credential/egress-auth) |
| `egress.proxy` | Customer-managed SOCKS5 route for allowed TCP traffic. See [Egress Proxy](/docs/sandbox/proxy) |
| `network.credentialBindings` | Local bindings used by `credentialRules`. See [Credential / Egress Auth](/docs/credential/egress-auth) |

The same public `SandboxNetworkPolicy` shape is used in:

- template `spec.network`
- sandbox claim `config.network`
- runtime `GET` and `PUT` `/api/v1/sandboxes/{id}/network`

## Mode And Rule Evaluation

1. `trafficRules` are evaluated in order.
2. The first matching rule wins.
3. If no rule matches, traffic falls back to `mode`.

<Callout variant="info">
Use `trafficRules` for new policies. Legacy `allowed*` and `denied*` fields still work, but they are deprecated and should not be mixed with `trafficRules`.
</Callout>

<Callout variant="info">
If a credential rule uses `tlsMode: terminate-reoriginate`, Sandbox0 exposes the netd MITM CA as `SANDBOX0_NETD_MITM_CA_FILE` and configures procd-managed processes with a combined CA bundle through common TLS environment variables.
</Callout>

## Traffic Rule Fields

| Field | Required | Description |
|-------|----------|-------------|
| `action` | Yes | `allow` or `deny` |
| `name` | No | Stable identifier for replacement and merge |
| `domains` | No | Domain match list |
| `cidrs` | No | CIDR match list |
| `ports` | No | Port/protocol constraints |
| `appProtocols` | No | Classified application protocols such as `http`, `tls`, `ssh`, `dns`, `redis` |

## HTTP Request Matchers

`credentialRules[*].httpMatch` narrows credential injection for HTTP-family rules after the HTTP request is visible to netd. It can match methods, exact paths, path prefixes, query parameters, and headers.

For HTTPS and gRPC rules, request matching requires `tlsMode: terminate-reoriginate` so netd can read the request before injecting credentials.

## Protocol Rules

`protocolRules` run after traffic is allowed. The first supported protocol is MCP over HTTP/HTTPS. Use it to allow a sandbox to reach an MCP server while limiting tool calls by tool name.

For HTTPS MCP servers, set `tlsMode: terminate-reoriginate` on the protocol rule so netd can inspect JSON-RPC request bodies.

## Get Network Policy

<Endpoint method="GET">
/api/v1/sandboxes/{'{id}'}/network
</Endpoint>

<Tabs
  tabs={[
    {
      label: "Go",
      language: "go",
      code: `policy, err := sandbox.GetNetworkPolicy(ctx)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("mode=%s\\n", policy.Mode)`
    },
    {
      label: "Python",
      language: "python",
      code: `policy = sandbox.get_network_policy()
print(policy.mode)`
    },
    {
      label: "TypeScript",
      language: "typescript",
      code: `const policy = await sandbox.getNetworkPolicy();
console.log(policy.mode);`
    },
    {
      label: "CLI",
      language: "bash",
      code: `s0 sandbox network get -s sb_abc123`
    }
  ]}
/>

## Update Network Policy

<Endpoint method="PUT">
/api/v1/sandboxes/{'{id}'}/network
</Endpoint>

### Allow Only GitHub HTTPS

<Tabs
  tabs={[
    {
      label: "Go",
      language: "go",
      code: `_, err = sandbox.UpdateNetworkPolicy(ctx, apispec.SandboxNetworkPolicy{
    Mode: apispec.SandboxNetworkPolicyModeBlockAll,
    Egress: apispec.NewOptNetworkEgressPolicy(apispec.NetworkEgressPolicy{
        TrafficRules: []apispec.TrafficRule{
            {
                Name: apispec.NewOptString("allow-github"),
                Action: apispec.TrafficRuleActionAllow,
                Domains: []string{"github.com", "api.github.com"},
                Ports: []apispec.PortSpec{
                    {
                        Port: 443,
                        Protocol: apispec.NewOptString("tcp"),
                    },
                },
            },
        },
    }),
})
if err != nil {
    log.Fatal(err)
}`
    },
    {
      label: "Python",
      language: "python",
      code: `from sandbox0.apispec.models.sandbox_network_policy import SandboxNetworkPolicy

sandbox.update_network_policy(
    SandboxNetworkPolicy.from_dict({
        "mode": "block-all",
        "egress": {
            "trafficRules": [
                {
                    "name": "allow-github",
                    "action": "allow",
                    "domains": ["github.com", "api.github.com"],
                    "ports": [{"port": 443, "protocol": "tcp"}],
                },
            ],
        },
    })
)`
    },
    {
      label: "TypeScript",
      language: "typescript",
      code: `await sandbox.updateNetworkPolicy({
    mode: 'block-all',
    egress: {
        trafficRules: [
            {
                name: 'allow-github',
                action: 'allow',
                domains: ['github.com', 'api.github.com'],
                ports: [{ port: 443, protocol: 'tcp' }],
            },
        ],
    },
});`
    },
    {
      label: "CLI",
      language: "bash",
      code: `s0 sandbox network update --mode block-all \\
  --traffic-rule '{"name":"allow-github","action":"allow","domains":["github.com","api.github.com"],"ports":[{"port":443,"protocol":"tcp"}]}' \\
  -s sb_abc123`
    }
  ]}
/>

## Legacy Compatibility

`egress.allowedDomains`, `allowedCidrs`, `allowedPorts`, `deniedDomains`, `deniedCidrs`, and `deniedPorts` are still accepted for compatibility:

- In `block-all`, only `allowed*` fields are enforced.
- In `allow-all`, only `denied*` fields are enforced.

Prefer `trafficRules` for all new policies.

## Next Steps

<CardGroup>
  <Card title="Protocol Controls" href="/docs/sandbox/protocol-controls" cta="Continue">
    Restrict MCP tools and future protocol-level operations.
  </Card>

  <Card title="Egress Proxy" href="/docs/sandbox/proxy" cta="Continue">
    Route allowed TCP egress through a customer-managed SOCKS5 proxy.
  </Card>

  <Card title="Sandbox Services" href="/docs/sandbox/services" cta="Continue">
    Expose named sandbox ports through public HTTP service routes.
  </Card>
</CardGroup>
