Back to Microsandbox

Networking

docs/sdk/go/networking.mdx

0.5.111.7 KB
Original Source

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.

go
sb, err := m.CreateSandbox(ctx, "worker",
    m.WithImage("alpine"),
    m.WithNetwork(m.NetworkPolicy.PublicOnly()),
)

NetworkPolicy

Helpers that return common preset *NetworkConfig values. Access via the package-level NetworkPolicy value.


NetworkPolicy.PublicOnly()

go
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.


NetworkPolicy.None()

go
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.


NetworkPolicy.AllowAll()

go
func (networkPolicyFactory) AllowAll() *NetworkConfig

Unrestricted network access, including private addresses and the host machine.


NetworkPolicy.NonLocal()

go
func (networkPolicyFactory) NonLocal() *NetworkConfig

Allow public + private (LAN) destinations; ingress allowed by default. Blocks loopback, link-local, and metadata.


Custom rules

Build a custom firewall by populating NetworkConfig.Rules. Rules are evaluated first-match-wins per direction. DefaultEgress and DefaultIngress set the fall-through action.

go
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"},
            },
        },
    }),
)

Rule order matters

The first matching rule wins, so a broad rule placed before a narrow one swallows it:

go
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.


Types

NetworkConfig

The configuration struct passed via WithNetwork.

FieldTypeDescription
PolicyNetworkPolicyPresetPreset name. Mutually exclusive with Rules for canned configurations; set via NetworkPolicy
Rules[]PolicyRuleOrdered custom rules (first match wins)
DefaultEgressPolicyActionFall-through action for outbound when no rule matches. Defaults to "deny"
DefaultIngressPolicyActionFall-through action for inbound when no rule matches. Defaults to "allow"
DenyDomains[]stringExact-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[]stringDomain suffixes (e.g. .ads) — denies the apex and any subdomain
DNS*DNSConfigDNS interception settings
DNSRebindProtection*boolLegacy convenience for DNS.RebindProtection. When DNS is also set, the nested value wins
TLS*TLSConfigTLS interception settings
Portsmap[uint16]uint16Host→guest TCP port mappings bound to 127.0.0.1
PortBindings[]PortBindingHost→guest port mappings with explicit bind addresses
IPv4PoolstringIPv4 pool used for per-sandbox /30 guest subnets. Defaults to 172.16.0.0/12
IPv6PoolstringIPv6 pool used for per-sandbox /64 guest prefixes. Defaults to fd42:6d73:62::/48
MaxConnections*uintCap concurrent network connections from the sandbox
OnSecretViolationViolationActionSandbox-wide action when a secret is sent to a disallowed host
TrustHostCAs*boolShip 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

PortBinding

go
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.

go
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},
    ),
)
FieldTypeDescription
BindstringHost IP address to bind, such as 127.0.0.1, 0.0.0.0, or ::
HostPortuint16Port on the host
GuestPortuint16Port inside the sandbox
ProtocolPortProtocolPortProtocolTCP or PortProtocolUDP. Empty defaults to TCP

PortProtocol

go
type PortProtocol string
ConstantValueDescription
PortProtocolTCP"tcp"TCP port mapping
PortProtocolUDP"udp"UDP port mapping

PolicyRule

A single firewall rule.

FieldTypeDescription
ActionPolicyActionallow or deny
DirectionPolicyDirectionDirection this rule considers. PolicyDirectionAny matches in either
DestinationstringTarget 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
ProtocolPolicyProtocolLegacy single-protocol field. Prefer Protocols when matching multiple
Protocols[]PolicyProtocolProtocol set. Empty means any
PortstringSingle port ("443") or range ("8000-9000")
Ports[]stringMultiple 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.

DNSConfig

go
type DNSConfig struct {
    RebindProtection *bool
    Nameservers      []string
    QueryTimeoutMs   *uint64
}

In-VM DNS proxy configuration.

FieldTypeDescription
RebindProtection*boolBlock DNS responses resolving to private IPs. Default true when unset
Nameservers[]stringUpstream resolvers. Each entry is IP, IP:PORT, HOST, or HOST:PORT. Replaces /etc/resolv.conf when non-empty
QueryTimeoutMs*uint64Per-DNS-query timeout in milliseconds

TLSConfig

go
type TLSConfig struct {
    Bypass           []string
    VerifyUpstream   *bool
    InterceptedPorts []uint16
    BlockQUIC        *bool
    CACert           string
    CAKey            string
    UpstreamCACerts  []string
}

Transparent HTTPS inspection proxy configuration.

FieldTypeDescription
Bypass[]stringDomains to skip interception (supports *.suffix globs). Use for domains with certificate pinning
VerifyUpstream*boolVerify upstream server certificates. Default true. Set false only for self-signed servers
InterceptedPorts[]uint16TCP ports where TLS interception is active. Default [443]
BlockQUIC*boolBlock QUIC/HTTP3 (UDP) on intercepted ports, forcing TCP/TLS fallback
CACertstringPath to a custom interception CA certificate PEM file
CAKeystringPath to a custom interception CA private key PEM file
UpstreamCACerts[]stringPaths to additional CA bundles trusted for upstream verification
go
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},
        },
    }),
)

PolicyAction

go
type PolicyAction string
ConstantValueDescription
PolicyActionAllow"allow"Permit the traffic
PolicyActionDeny"deny"Drop the traffic silently

PolicyDirection

go
type PolicyDirection string
ConstantValueDescription
PolicyDirectionEgress"egress"Traffic leaving the sandbox
PolicyDirectionIngress"ingress"Traffic entering the sandbox
PolicyDirectionAny"any"Rule applies in either direction

PolicyProtocol

go
type PolicyProtocol string
ConstantValueDescription
PolicyProtocolTCP"tcp"TCP traffic
PolicyProtocolUDP"udp"UDP traffic
PolicyProtocolICMPv4"icmpv4"ICMPv4 traffic (egress only)
PolicyProtocolICMPv6"icmpv6"ICMPv6 traffic (egress only)

NetworkPolicyPreset

go
type NetworkPolicyPreset string

Preset names accepted by NetworkConfig.Policy. Prefer NetworkPolicy, which returns a preconfigured *NetworkConfig.

ConstantValueDescription
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

Destination groups

The Destination field on PolicyRule accepts these well-known group names alongside literal CIDRs and domains:

ValueDescription
"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.