Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.microsandbox.dev/llms.txt

Use this file to discover all available pages before exploring further.

All network traffic from a sandbox flows through a host-controlled networking stack. From inside, the sandbox sees a normal network interface, but on the host side every packet is subject to policy before it goes anywhere. The sandbox’s only path to the outside world is through this stack, so blocked traffic never leaves the VM.

Defaults

Without any policy flags, sandboxes get public-internet egress only: routable destinations work, but private (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 100.64.0.0/10), loopback (127.0.0.0/8), link-local (169.254.0.0/16), and the cloud metadata endpoint (169.254.169.254) are denied. Inbound traffic on published ports is unfiltered until you add an explicit ingress rule. To turn off networking entirely:
let sb = Sandbox::builder("isolated")
    .image("python")
    .network(|n| n.enabled(false))
    .create()
    .await?;

Custom policies

A policy is a list of rules plus two direction-specific defaults:
default_egress  : Allow | Deny     (action when no egress rule matches)
default_ingress : Allow | Deny     (action when no ingress rule matches)
rules           : [Rule, ...]      (first match wins)
Each rule carries its own direction (Egress, Ingress, or Any), a destination, an optional protocol set, an optional port set, and an action. --net-rule takes a comma-separated list of tokens shaped as <action>[:<direction>]@<target>[:<proto>[:<ports>]]. Direction defaults to egress when omitted. Repeating the flag concatenates tokens in argv order; first match wins.
use microsandbox::{NetworkPolicy, Sandbox};

let policy = NetworkPolicy::builder()
    .default_deny()
    .egress(|e| e.tcp().port(443).allow_public())
    .egress(|e| e.udp().tcp().port(53).allow_host())
    .build()?;

let sb = Sandbox::builder("secure-agent")
    .image("alpine")
    .network(|n| n.policy(policy))
    .create()
    .await?;
Rules can target groups like public, private, and host, or specific IPs, CIDRs, domains, and port ranges. The full grammar lives in the CLI reference, and SDK-specific shapes live in each networking reference. For deny-by-default policies, remember that DNS is delivered through the sandbox gateway. The host group is usually the right target for DNS egress; see DNS-as-egress for the full breakdown.

Port mapping

Expose ports from the sandbox to the host so services running inside the VM are reachable from your machine.
let sb = Sandbox::builder("api")
    .image("python")
    .port(8080, 80)
    .port_udp(5353, 5353)
    .create()
    .await?;

Reaching the host

From inside the sandbox, host.microsandbox.internal resolves to the host machine, same idea as Docker’s host.docker.internal. Use it to call a dev server, database, or other process running on your machine without hard-coding an IP.
# Inside the sandbox:
curl http://host.microsandbox.internal:8080
The name is wired through /etc/hosts and the DNS interceptor, so both standard resolvers and tools that bypass /etc/hosts (like dig) find it. The default policy denies host access — the sandbox gateway sits in a private range, same as any other local destination. Add the host group to open it:
NetworkPolicy::builder()
    .default_deny()
    .egress(|e| e.allow_public().allow_host())
    .build()?

Loopback vs host: a common trap

loopback means the sandbox’s own 127.0.0.1. It does not mean your laptop’s localhost. Use host when the sandbox needs to reach a service running on your machine via host.microsandbox.internal. This is the Docker-style “talk to the host” path. Use local when you intentionally want to allow guest loopback, link-local addresses, and the host together. Cloud metadata stays separate; allow meta explicitly only if you need it.

Protocol support

For most sandboxed workloads, networking behaves the way you’d expect:
  • Normal egress TCP and UDP traffic works, including common tools and libraries like curl, wget, package managers, HTTP clients, database drivers, and DNS lookups.
  • DNS queries are intercepted on the host side. See DNS for blocking, pinned resolvers, and query timeouts.
  • ICMP echo is supported: pinging external hosts works on systems that support unprivileged ICMP echo sockets.
  • Ingress on published ports is gated by the same policy. Denied connections drop with TCP RST so the peer sees ECONNRESET.
Raw sockets and full ICMP forwarding are not supported because they require elevated privileges on the host. Tools that depend on richer ICMP behavior, such as traceroute, are outside the current scope.

Next

  • DNS: domain blocking, pinned nameservers, query timeouts
  • TLS interception: HTTPS inspection with an auto-generated CA
  • Security model: how the stack defends against SSRF, rebinding, and metadata exfiltration