docs/sdk/go/networking.mdx
See Networking for the conceptual overview and TLS Interception for TLS proxy details.
The Go SDK's network surface is a single NetworkConfig struct passed via WithNetwork. Common shapes come from NetworkPolicy; custom rule sets are built by populating NetworkConfig.Rules directly.
sb, err := m.CreateSandbox(ctx, "worker",
m.WithImage("alpine"),
m.WithNetwork(m.NetworkPolicy.PublicOnly()),
)
Helpers that return common preset *NetworkConfig values. Access via the package-level NetworkPolicy value.
func (networkPolicyFactory) PublicOnly() *NetworkConfig
Block private address ranges and cloud metadata endpoints. Allow everything else. This is the default when no network configuration is supplied.
func (networkPolicyFactory) None() *NetworkConfig
Deny all traffic. No network interface is created; the guest is fully offline. Exec and FS still work — they use the host-guest channel, not the network.
func (networkPolicyFactory) AllowAll() *NetworkConfig
Unrestricted network access, including private addresses and the host machine.
func (networkPolicyFactory) NonLocal() *NetworkConfig
Allow public + private (LAN) destinations; ingress allowed by default. Blocks loopback, link-local, and metadata.
Build a custom firewall by populating NetworkConfig.Rules. Rules are evaluated first-match-wins per direction. DefaultEgress and DefaultIngress set the fall-through action.
sb, err := m.CreateSandbox(ctx, "agent",
m.WithImage("python:3.12"),
m.WithNetwork(&m.NetworkConfig{
DefaultEgress: m.PolicyActionDeny,
DefaultIngress: m.PolicyActionAllow,
Rules: []m.PolicyRule{
{
Action: m.PolicyActionAllow,
Direction: m.PolicyDirectionEgress,
Destination: "api.openai.com",
Protocol: m.PolicyProtocolTCP,
Port: "443",
},
{
Action: m.PolicyActionAllow,
Direction: m.PolicyDirectionEgress,
Destination: ".internal",
Protocols: []m.PolicyProtocol{m.PolicyProtocolTCP},
Ports: []string{"8000-9000"},
},
},
}),
)
The first matching rule wins, so a broad rule placed before a narrow one swallows it:
Rules: []m.PolicyRule{
{Action: m.PolicyActionAllow, Destination: "10.0.0.0/8"}, // matches everything in 10.x
{Action: m.PolicyActionDeny, Destination: "10.0.0.5"}, // never reached
},
Put specific rules before general ones.
The configuration struct passed via WithNetwork.
| Field | Type | Description |
|---|---|---|
| Policy | NetworkPolicyPreset | Preset name. Mutually exclusive with Rules for canned configurations; set via NetworkPolicy |
| Rules | []PolicyRule | Ordered custom rules (first match wins) |
| DefaultEgress | PolicyAction | Fall-through action for outbound when no rule matches. Defaults to "deny" |
| DefaultIngress | PolicyAction | Fall-through action for inbound when no rule matches. Defaults to "allow" |
| DenyDomains | []string | Exact-match domains to refuse DNS resolution for. Adds high-priority deny Domain("...") policy rules that fire at DNS (REFUSED), TLS first-flight (SNI), and TCP egress (cache fallback) |
| DenyDomainSuffixes | []string | Domain suffixes (e.g. .ads) — denies the apex and any subdomain |
| DNS | *DNSConfig | DNS interception settings |
| DNSRebindProtection | *bool | Legacy convenience for DNS.RebindProtection. When DNS is also set, the nested value wins |
| TLS | *TLSConfig | TLS interception settings |
| Ports | map[uint16]uint16 | Host→guest TCP port mappings bound to 127.0.0.1 |
| PortBindings | []PortBinding | Host→guest port mappings with explicit bind addresses |
| IPv4Pool | string | IPv4 pool used for per-sandbox /30 guest subnets. Defaults to 172.16.0.0/12 |
| IPv6Pool | string | IPv6 pool used for per-sandbox /64 guest prefixes. Defaults to fd42:6d73:62::/48 |
| MaxConnections | *uint | Cap concurrent network connections from the sandbox |
| OnSecretViolation | ViolationAction | Sandbox-wide action when a secret is sent to a disallowed host |
| TrustHostCAs | *bool | Ship the host's trusted root CAs into the guest at boot. Opt-in for corporate MITM proxies (Cloudflare Warp Zero Trust, Zscaler, Netskope, ...) whose gateway CA is unknown to the guest's stock Mozilla bundle |
type PortBinding struct {
Bind string
HostPort uint16
GuestPort uint16
Protocol PortProtocol
}
A host-to-guest port mapping with an explicit host bind address. Use it with WithPortBindings or NetworkConfig.PortBindings when the default 127.0.0.1 bind is too restrictive.
sb, err := m.CreateSandbox(ctx, "api",
m.WithImage("python:3.12"),
m.WithPortBindings(
m.PortBinding{Bind: "0.0.0.0", HostPort: 8001, GuestPort: 8001},
m.PortBinding{Bind: "127.0.0.1", HostPort: 5353, GuestPort: 53, Protocol: m.PortProtocolUDP},
),
)
| Field | Type | Description |
|---|---|---|
| Bind | string | Host IP address to bind, such as 127.0.0.1, 0.0.0.0, or :: |
| HostPort | uint16 | Port on the host |
| GuestPort | uint16 | Port inside the sandbox |
| Protocol | PortProtocol | PortProtocolTCP or PortProtocolUDP. Empty defaults to TCP |
type PortProtocol string
| Constant | Value | Description |
|---|---|---|
PortProtocolTCP | "tcp" | TCP port mapping |
PortProtocolUDP | "udp" | UDP port mapping |
A single firewall rule.
| Field | Type | Description |
|---|---|---|
| Action | PolicyAction | allow or deny |
| Direction | PolicyDirection | Direction this rule considers. PolicyDirectionAny matches in either |
| Destination | string | Target filter: a destination group, domain, domain suffix (prefixed with .), CIDR (10.0.0.0/8), exact IP, or "*". Domain and suffix strings are validated at sandbox creation |
| Protocol | PolicyProtocol | Legacy single-protocol field. Prefer Protocols when matching multiple |
| Protocols | []PolicyProtocol | Protocol set. Empty means any |
| Port | string | Single port ("443") or range ("8000-9000") |
| Ports | []string | Multiple port values at once |
Ingress rules carrying ICMP protocols are rejected at sandbox creation — the host has no inbound ICMP path. Use PolicyDirectionEgress for ICMP allow/deny.
type DNSConfig struct {
RebindProtection *bool
Nameservers []string
QueryTimeoutMs *uint64
}
In-VM DNS proxy configuration.
| Field | Type | Description |
|---|---|---|
| RebindProtection | *bool | Block DNS responses resolving to private IPs. Default true when unset |
| Nameservers | []string | Upstream resolvers. Each entry is IP, IP:PORT, HOST, or HOST:PORT. Replaces /etc/resolv.conf when non-empty |
| QueryTimeoutMs | *uint64 | Per-DNS-query timeout in milliseconds |
type TLSConfig struct {
Bypass []string
VerifyUpstream *bool
InterceptedPorts []uint16
BlockQUIC *bool
CACert string
CAKey string
UpstreamCACerts []string
}
Transparent HTTPS inspection proxy configuration.
| Field | Type | Description |
|---|---|---|
| Bypass | []string | Domains to skip interception (supports *.suffix globs). Use for domains with certificate pinning |
| VerifyUpstream | *bool | Verify upstream server certificates. Default true. Set false only for self-signed servers |
| InterceptedPorts | []uint16 | TCP ports where TLS interception is active. Default [443] |
| BlockQUIC | *bool | Block QUIC/HTTP3 (UDP) on intercepted ports, forcing TCP/TLS fallback |
| CACert | string | Path to a custom interception CA certificate PEM file |
| CAKey | string | Path to a custom interception CA private key PEM file |
| UpstreamCACerts | []string | Paths to additional CA bundles trusted for upstream verification |
sb, err := m.CreateSandbox(ctx, "inspect",
m.WithImage("python:3.12"),
m.WithNetwork(&m.NetworkConfig{
TLS: &m.TLSConfig{
Bypass: []string{"*.googleapis.com"},
InterceptedPorts: []uint16{443},
},
}),
)
type PolicyAction string
| Constant | Value | Description |
|---|---|---|
PolicyActionAllow | "allow" | Permit the traffic |
PolicyActionDeny | "deny" | Drop the traffic silently |
type PolicyDirection string
| Constant | Value | Description |
|---|---|---|
PolicyDirectionEgress | "egress" | Traffic leaving the sandbox |
PolicyDirectionIngress | "ingress" | Traffic entering the sandbox |
PolicyDirectionAny | "any" | Rule applies in either direction |
type PolicyProtocol string
| Constant | Value | Description |
|---|---|---|
PolicyProtocolTCP | "tcp" | TCP traffic |
PolicyProtocolUDP | "udp" | UDP traffic |
PolicyProtocolICMPv4 | "icmpv4" | ICMPv4 traffic (egress only) |
PolicyProtocolICMPv6 | "icmpv6" | ICMPv6 traffic (egress only) |
type NetworkPolicyPreset string
Preset names accepted by NetworkConfig.Policy. Prefer NetworkPolicy, which returns a preconfigured *NetworkConfig.
| Constant | Value | Description |
|---|---|---|
NetworkPolicyPresetNone | "none" | Fully airgapped |
NetworkPolicyPresetPublicOnly | "public-only" | Block private + metadata; allow everything else |
NetworkPolicyPresetAllowAll | "allow-all" | Unrestricted |
NetworkPolicyPresetNonLocal | "non-local" | Public + private/LAN egress; block loopback / link-local / metadata |
The Destination field on PolicyRule accepts these well-known group names alongside literal CIDRs and domains:
| Value | Description |
|---|---|
"public" | Complement of the named categories: every address not in any other group |
"private" | Private/RFC 1918 addresses + ULA + CGN (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 100.64.0.0/10, fc00::/7) |
"loopback" | Loopback addresses (127.0.0.0/8, ::1); the guest's own loopback, not the host. See the loopback-vs-host watch-out |
"link-local" | Link-local addresses (169.254.0.0/16, fe80::/10) excluding metadata |
"metadata" | Cloud metadata endpoints (169.254.169.254) |
"multicast" | Multicast addresses (224.0.0.0/4, ff00::/8) |
"host" | The host machine, reached via host.microsandbox.internal. The right group for "let the sandbox reach my host's localhost", not "loopback" |
A domain prefixed with . becomes a suffix match: .example.com matches api.example.com but not example.com.