# How Microsandbox Handles Cross-Origin Isolation

> Discover how Microsandbox achieves cross-origin isolation using OS-level virtualization and network namespaces instead of browser COOP/COEP headers. Learn about its secure approach.

- Repository: [Super Rad Company/microsandbox](https://github.com/superradcompany/microsandbox)
- Tags: deep-dive
- Published: 2026-08-20

---

**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](https://github.com/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`](https://github.com/superradcompany/microsandbox/blob/main/crates/runtime/src/vm.rs), the runtime spawns each sandbox as an independent guest process with a dedicated kernel image.

```rust
// 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`](https://github.com/superradcompany/microsandbox/blob/main/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.

```rust
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`](https://github.com/superradcompany/microsandbox/blob/main/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`](https://github.com/superradcompany/microsandbox/blob/main/crates/filesystem/src/mount.rs) ensures each sandbox sees only explicitly shared directories:

```rust
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

```bash

# 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:

```rust
// 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:

```rust
// 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`](https://github.com/superradcompany/microsandbox/blob/main/crates/runtime/src/vm.rs) | VM lifecycle and guest process management |
| [`crates/network/src/policy.rs`](https://github.com/superradcompany/microsandbox/blob/main/crates/network/src/policy.rs) | `NetworkPolicy` struct and port-forwarding rules |
| [`crates/network/src/forwarder.rs`](https://github.com/superradcompany/microsandbox/blob/main/crates/network/src/forwarder.rs) | Host-side port forwarding implementation |
| [`crates/utils/src/seccomp.rs`](https://github.com/superradcompany/microsandbox/blob/main/crates/utils/src/seccomp.rs) | Seccomp-bpf syscall filter loader |
| [`crates/filesystem/src/mount.rs`](https://github.com/superradcompany/microsandbox/blob/main/crates/filesystem/src/mount.rs) | Mount namespace and bind mount handling |
| [`sdk/rust/src/sandbox.rs`](https://github.com/superradcompany/microsandbox/blob/main/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`](https://github.com/superradcompany/microsandbox/blob/main/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.