Documentation/docs/sandbox/protocol-controls

#Protocol Controls

egress.protocolRules adds protocol-aware controls after outbound traffic is allowed by trafficRules.

Use it when a sandbox must reach a broad protocol endpoint but only a subset of protocol operations should be allowed. The first supported protocol is remote MCP over HTTP or HTTPS.

How It Fits#

LayerPurpose
trafficRulesAllow or deny the destination by domain, CIDR, port, and classified app protocol
protocolRulesParse an allowed protocol request and allow, deny, or audit protocol operations
credentialRulesResolve and inject outbound credentials for matching traffic

Protocol controls are enforced in the data plane by netd. Regional control plane services store and distribute policy; they are not in the per-request data path.

MCP Tool Policy#

MCP protocol rules inspect HTTP-carried JSON-RPC requests. For tools/call, netd reads params.name and evaluates the configured tool policy.

yaml
mode: block-all egress: trafficRules: - name: allow-docs-mcp action: allow domains: - mcp.example.com ports: - port: 443 protocol: tcp protocolRules: - name: docs-mcp-tools protocol: mcp domains: - mcp.example.com ports: - port: 443 protocol: tcp tlsMode: terminate-reoriginate httpMatch: methods: - POST paths: - /mcp mcp: tools: allowed: - read_file denied: - write_file - run_command

denied is evaluated before allowed. If allowed is empty, tools are allowed unless they are listed in denied. If allowed is non-empty, only listed tools are allowed.

When a tool call is denied, netd does not forward the request upstream. It returns a JSON-RPC error response to the sandbox process and writes the protocol decision to the netd audit event.

MCP request bodies must be bounded and inspectable. If netd cannot safely read the JSON-RPC request body, the protocol rule fails closed and returns a JSON-RPC policy error.

Update Examples#

The SDK and CLI examples below update an existing sandbox. Set SANDBOX_ID to the sandbox you want to control.

PUT

/api/v1/sandboxes/{id}/network

go
package main import ( "context" "log" "os" sandbox0 "github.com/sandbox0-ai/sdk-go" "github.com/sandbox0-ai/sdk-go/pkg/apispec" ) func main() { ctx := context.Background() client, err := sandbox0.NewClient( sandbox0.WithToken(os.Getenv("SANDBOX0_TOKEN")), sandbox0.WithBaseURL(os.Getenv("SANDBOX0_BASE_URL")), ) if err != nil { log.Fatal(err) } _, err = client.Sandbox(os.Getenv("SANDBOX_ID")).UpdateNetworkPolicy(ctx, apispec.SandboxNetworkPolicy{ Mode: apispec.SandboxNetworkPolicyModeBlockAll, Egress: apispec.NewOptNetworkEgressPolicy(apispec.NetworkEgressPolicy{ TrafficRules: []apispec.TrafficRule{{ Name: apispec.NewOptString("allow-docs-mcp"), Action: apispec.TrafficRuleActionAllow, Domains: []string{"mcp.example.com"}, Ports: []apispec.PortSpec{{ Port: 443, Protocol: apispec.NewOptString("tcp"), }}, }}, ProtocolRules: []apispec.ProtocolRule{{ Name: apispec.NewOptString("docs-mcp-tools"), Protocol: apispec.ProtocolRuleProtocolMcp, Domains: []string{"mcp.example.com"}, Ports: []apispec.PortSpec{{ Port: 443, Protocol: apispec.NewOptString("tcp"), }}, TlsMode: apispec.NewOptEgressTLSMode(apispec.EgressTLSModeTerminateReoriginate), HttpMatch: apispec.NewOptHTTPMatch(apispec.HTTPMatch{ Methods: []string{"POST"}, Paths: []string{"/mcp"}, }), Mcp: apispec.NewOptMCPProtocolRule(apispec.MCPProtocolRule{ Tools: apispec.NewOptMCPToolPolicy(apispec.MCPToolPolicy{ Allowed: []string{"read_file"}, Denied: []string{"write_file", "run_command"}, }), }), }}, }), }) if err != nil { log.Fatal(err) } }

HTTPS Inspection#

For HTTPS MCP servers, set tlsMode: terminate-reoriginate on the protocol rule. Sandbox0 then uses the netd MITM CA already exposed to procd-managed processes.

Without TLS termination, netd can still apply destination-level trafficRules, but it cannot read MCP JSON-RPC bodies or enforce tool names.

Current Scope#

The first implementation targets remote MCP over HTTP/HTTPS Streamable HTTP style requests:

  • tools/call is enforced by tool name.
  • tools/list is audited but not filtered.
  • HTTP/1.1 and HTTP/2 HTTPS requests can be inspected when TLS termination is enabled.
  • Local stdio MCP does not traverse netd and must be controlled by a tool runner or procd-level policy.
  • Tool argument semantics are server-specific. Use tool-name allowlists as the strong boundary; treat argument-level checks as future protocol-adapter extensions.

Next Steps#

Network

Configure outbound destination policy and protocol-aware rules.

Egress Auth

Inject credentials for allowed outbound traffic.