How Microsandbox Handles Cross-Origin Isolation

Microsandbox does not implement browser-based cross-origin isolation headers (COOP/COEP); instead, it enforces isolation at the operating-system level through lightweight virtual machines, network namespaces, and explicit port-forwarding policies.

Microsandbox is an open-source sandboxing runtime that prioritizes OS-level isolation over HTTP-header-based security. Because each workload runs inside its own krun-based virtual machine, the traditional browser concepts of Cross-Origin-Opener-Policy (COOP) and Cross-Origin-Embedder-Policy (COEP) do not apply. This article examines how the project achieves equivalent—and often stronger—isolation guarantees through kernel-level mechanisms, with specific reference to the source code implementation.

Why COOP/COEP Headers Are Not Used

Cross-origin isolation in web browsers relies on HTTP headers to restrict how documents interact across origins. Microsandbox takes a fundamentally different approach: the guest code never runs in a browser context that would share an origin with other code. Instead, each sandbox executes in a separate VM process with its own kernel, memory space, and network stack.

As implemented in superradcompany/microsandbox, the runtime focuses on:

  • Process isolation via KVM-based virtualization (libkrun)
  • Network segmentation through explicit port-forwarding rules
  • System call filtering using seccomp-bpf
  • Filesystem jail via mount namespace restrictions

This means that even if a sandbox runs an HTTP server, that server is invisible to external clients unless explicitly exposed—and the "origin" concept becomes irrelevant because the sandbox operates below the browser abstraction layer.

Core Isolation Mechanisms

Separate VM Process Per Sandbox

The foundational isolation unit is the virtual machine itself. In crates/runtime/src/vm.rs, the runtime spawns each sandbox as an independent guest process with a dedicated kernel image.

// Conceptual usage from the Rust SDK
use microsandbox::sandbox::SandboxBuilder;

let sandbox = SandboxBuilder::new()
    .kernel_path("/usr/share/microsandbox/kernel")
    .memory_mb(512)
    .build()
    .await?;

Each VM receives its own:

  • Address space and CPU state
  • Virtualized hardware (block, network, serial devices)
  • Guest kernel booted from the bundled kernel image

This separation prevents memory corruption attacks from propagating between sandboxes—no shared heap, no shared JIT compiler, no browser event loop that could be poisoned.

Network Namespace and Port Forwarding

The network layer in crates/network/src/policy.rs implements deny-by-default connectivity. By default, a sandbox has no inbound network access. The user must explicitly declare which ports to forward from the host.

use microsandbox::network::NetworkPolicy;

// Whitelist only TCP port 8080 for inbound connections
let policy = NetworkPolicy::builder()
    .allow_tcp_port(8080)
    .build();

let sandbox = SandboxBuilder::new()
    .network_policy(policy)
    .await?;

Key implementation details:

  • The guest operates on a virtual NIC with private IP addressing
  • No NAT hairpinning or automatic service discovery between sandboxes
  • Outbound connections are permitted (subject to host firewall) but inbound requires explicit mapping

This design eliminates the attack surface that COOP/COEP headers attempt to mitigate. A malicious page inside one sandbox cannot even resolve the network address of another sandbox, let alone perform a cross-origin request.

Seccomp-Based Syscall Filtering

Even if network code were compromised, the crates/utils/src/seccomp.rs module restricts available system calls:

  • socket() — restricted to AF_INET/AF_INET6 with specific parameters
  • bind() — blocked for ports not in the NetworkPolicy whitelist
  • connect() — permitted for outbound but logged/audited

Unexpected syscalls trigger immediate termination via SIGSYS, containing lateral movement attempts.

Filesystem Sandboxing

The mount namespace implementation in crates/filesystem/src/mount.rs ensures each sandbox sees only explicitly shared directories:

SandboxBuilder::new()
    .mount("/host/data", "/data", MountOptions::read_only())
    .mount("/host/tmp", "/tmp", MountOptions::read_write())

Without access to host files, other sandbox directories, or sensitive paths like /proc/*/environ, the guest cannot extract cross-origin state from the filesystem.

CLI and SDK Usage Examples

Creating a Restricted Sandbox via CLI


# Create sandbox with only port 8080 exposed

msb create my-api \
  --network-policy "tcp:8080" \
  --memory 512 \
  --cpu 2

# Verify no other ports are accessible

msb inspect my-api --network

Attempting Unauthorized Network Access

From inside a sandbox with no exposed ports, outbound connection attempts fail at the host level:

// Guest code running inside sandbox
// Port 9000 was NOT in the NetworkPolicy

let client = reqwest::Client::new();
let result = client.get("http://127.0.0.1:9000").send().await;

// Returns: Connection refused
// Host-side: iptables DROP rule (no forwarding rule exists)

Enabling a Web Service with Explicit Headers

If you expose a sandboxed HTTP server and want browser-level cross-origin isolation, add headers at your reverse proxy or host-side server:

// Host-side Axum server forwarding to sandbox
use axum::{
    http::header::{
        CROSS_ORIGIN_EMBEDDER_POLICY, CROSS_ORIGIN_OPENER_POLICY, HeaderValue
    },
    response::Response,
    routing::get,
};

async fn with_coop_coep(mut response: Response) -> Response {
    response.headers_mut().insert(
        CROSS_ORIGIN_OPENER_POLICY,
        HeaderValue::from_static("same-origin"),
    );
    response.headers_mut().insert(
        CROSS_ORIGIN_EMBEDDER_POLICY,
        HeaderValue::from_static("require-corp"),
    );
    response
}

Microsandbox remains agnostic to these headers—they are the responsibility of whatever HTTP server faces the browser.

Key Source Files

Path Purpose
crates/runtime/src/vm.rs VM lifecycle and guest process management
crates/network/src/policy.rs NetworkPolicy struct and port-forwarding rules
crates/network/src/forwarder.rs Host-side port forwarding implementation
crates/utils/src/seccomp.rs Seccomp-bpf syscall filter loader
crates/filesystem/src/mount.rs Mount namespace and bind mount handling
sdk/rust/src/sandbox.rs Public SDK interface

Summary

  • Microsandbox implements cross-origin isolation through virtualization, not HTTP headers
  • Each sandbox runs in an isolated VM with separate kernel, memory, and network stack
  • NetworkPolicy enforces deny-by-default port access—no exposure without explicit configuration
  • Seccomp filters restrict system calls that could bypass network policies
  • Filesystem mounts limit data exfiltration to explicitly shared paths
  • COOP/COEP headers become unnecessary because sandboxes never share browser origins; any web-facing server must explicitly expose ports and may add headers at the host layer

Frequently Asked Questions

Does Microsandbox support COOP and COEP headers?

No. Microsandbox does not implement these headers because it does not operate within a browser context. Its isolation model uses OS-level virtualization rather than browser security policies. If you expose a sandboxed service to the web, add COOP/COEP headers in your host-side reverse proxy or load balancer.

Can sandboxes communicate with each other over the network?

Only if explicitly configured through host networking. By default, sandboxes receive private IP addresses in non-routed namespaces. They cannot discover or connect to each other without port-forwarding rules that bridge through the host. This is enforced by the virtual NIC implementation and iptables rules generated from NetworkPolicy.

What happens if sandbox code tries to open an unapproved port?

The system call is blocked by seccomp (crates/utils/src/seccomp.rs), and the guest process receives SIGSYS. The runtime logs this violation and terminates the sandbox. There is no silent failure or fallback—the security policy is strictly enforced at the kernel level.

Is Microsandbox suitable for running untrusted JavaScript/web apps?

Yes, provided you do not forward ports to the guest. For browser-based applications, consider running them in a sandbox without network exposure, using a host-side UI that communicates through controlled channels (stdin/stdout, shared memory, or explicitly approved APIs). This eliminates entire classes of cross-origin and XSS attacks.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →