Skip to main content
All sandbox network traffic passes through a host-controlled networking stack where policies are enforced at the packet level. There’s no underlying host network to bypass. See Networking concepts for more on how this works.

Preset policies

public_only is the default. It blocks private address ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.0/8, 169.254.0.0/16) while allowing public internet access.
use microsandbox::{Sandbox, NetworkPolicy};

// No network access
let sb1 = Sandbox::builder("isolated")
    .image("python:3.12")
    .disable_network()
    .create()
    .await?;

// Public internet only (default)
let sb2 = Sandbox::builder("web-agent")
    .image("python:3.12")
    .network(|n| n.policy(NetworkPolicy::public_only()))
    .create()
    .await?;

// Unrestricted access
let sb3 = Sandbox::builder("dev")
    .image("python:3.12")
    .network(|n| n.policy(NetworkPolicy::allow_all()))
    .create()
    .await?;

// Allow only specific hosts
let sb4 = Sandbox::builder("scoped-agent")
    .image("python:3.12")
    .network(|n| n.policy(NetworkPolicy::allowlist(["api.openai.com", "pypi.org"])))
    .create()
    .await?;

// Block specific destinations
let sb5 = Sandbox::builder("safe-agent")
    .image("python:3.12")
    .network(|n| n.policy(NetworkPolicy::denylist([
        DestinationGroup::CloudMetadata,
        DestinationGroup::PrivateNetworks,
    ])))
    .create()
    .await?;

Custom policies

Build a policy with explicit egress and ingress rules. Rules are evaluated first-match-wins.
use microsandbox::network::*;

let policy = NetworkPolicy::builder()
    .default_egress(Action::Deny)
    .default_ingress(Action::Deny)
    .egress(Rule::builder()
        .name("allow-https")
        .protocol(Protocol::Tcp)
        .ports(443)
        .action(Action::Allow)
        .build())
    .egress(Rule::builder()
        .name("allow-dns")
        .protocol(Protocol::Udp)
        .ports(53)
        .action(Action::Allow)
        .build())
    .deny_egress_to(Destination::Group(DestinationGroup::CloudMetadata))
    .deny_egress_to(Destination::Group(DestinationGroup::PrivateNetworks))
    .build();

let sb = Sandbox::builder("secure-agent")
    .image("alpine:latest")
    .network(|n| n.policy(policy))
    .create()
    .await?;

Port mapping

Expose ports from the sandbox to the host so services running inside the VM are accessible from your machine. For Rust, SandboxBuilder::port() and port_udp() are top-level shorthands that compose with .network(...) when you also need policy, DNS, or TLS settings.
use microsandbox::{Sandbox, NetworkPolicy};

let sb = Sandbox::builder("api")
    .image("python:3.12")
    .port(8080, 80)
    .port_udp(5353, 5353)
    .network(|n| n.policy(NetworkPolicy::public_only()))
    .create()
    .await?;

DNS interception

All DNS queries are intercepted and resolved on the host side. This enables domain blocking, suffix blocking, and rebinding protection.
use microsandbox::{Sandbox, NetworkPolicy, DnsMode};

let sb = Sandbox::builder("safe-agent")
    .image("python:3.12")
    .network(|n| n
        .policy(NetworkPolicy::public_only())
        .dns(DnsMode::Intercepted)
        .block_domain("malware.example.com")
        .block_domain("*.tracking.com")
    )
    .create()
    .await?;

Secrets

Secrets use a placeholder substitution model. The guest VM never sees the real credential. When you bind a secret to an environment variable and one or more allowed hosts, microsandbox generates a random placeholder (e.g., OPENAI_API_KEY=msb_ph_a8f3c2...) and injects that into the guest instead. The real value never enters the VM. The only way it reaches the outside world is when a request goes to an allowed host, at which point microsandbox swaps the placeholder for the real value. Everywhere else, the placeholder is just a meaningless string. So even with full code execution inside the sandbox, there’s nothing to steal. The credential was never there.
use microsandbox::{Sandbox, SecretViolationAction};

let sb = Sandbox::builder("agent")
    .image("python:3.12")
    .secret(|s| s
        .env("GITHUB_TOKEN")
        .value(std::env::var("GITHUB_TOKEN")?)
        .allow_host("api.github.com")
        .allow_host_pattern("*.githubusercontent.com")
    )
    .secret_env("OPENAI_API_KEY", api_key, "api.openai.com")
    .on_secret_violation(SecretViolationAction::BlockAndLog)
    .create()
    .await?;

TLS interception

Enable HTTPS traffic inspection with an auto-generated CA certificate. microsandbox generates a per-sandbox CA during creation, installs it in the guest’s trust store, and generates per-domain certificates on first connection. Domains that use certificate pinning (or that you don’t want to intercept) can be bypassed.
use microsandbox::tls::*;

let sb = Sandbox::builder("agent")
    .image("python:3.12")
    .network(|n| n
        .tls(|t| t
            .ca_storage("/var/lib/microsandbox/ca")
            .ca_cn("My Agent Sandbox CA")
            .bypass("pinned-api.example.com")
        )
    )
    .create()
    .await?;