Skip to main content

microsandbox

Lightweight VM sandboxes for Python applications that need hardware-level isolation for AI agents, tools, tests, and untrusted code.

The microsandbox Python package provides async Python bindings to the microsandbox runtime. It creates microVM-backed sandboxes from OCI images or other rootfs sources, then exposes command execution, guest filesystem access, networking, secrets, volumes, metrics, logs, snapshots, and SSH/SFTP through Python-friendly classes and dataclasses.

For the full API reference and longer guides, use the docs site:

Features

  • Hardware VM isolation with a guest Linux kernel
  • Async sandbox lifecycle, execution, filesystem, metrics, and logs APIs
  • OCI image, bind-rootfs, disk-image, and snapshot-based sandboxes
  • Named volumes, bind mounts, tmpfs mounts, and disk-image mounts
  • Network policies, DNS filtering, TLS interception, secrets, and port publishing
  • Rootfs patches before boot
  • Detached sandboxes that can outlive the Python process
  • Typed Python surface with StrEnums, frozen dataclasses, event objects, .pyi stubs, and py.typed

Requirements

  • Python 3.10+
  • Linux with KVM, macOS with Apple Silicon, or Windows with Windows Hypervisor Platform
  • Windows support is currently preview; see the Windows troubleshooting guide for WHP and runtime setup notes.

Supported Platforms

Platform Architecture Notes
macOS ARM64 / Apple Silicon Wheel bundles msb and libkrunfw
Linux x86_64 Wheel bundles msb and libkrunfw
Linux ARM64 Wheel bundles msb and libkrunfw
Windows x86_64, ARM64 Preview; requires WHP

Python wheels bundle the matching msb runtime and libkrunfw library. Source checkouts and unreleased local builds can override runtime paths with MSB_PATH, MSB_LIBKRUNFW_PATH, or microsandbox.set_libkrunfw_path(...).

Installation

pip install microsandbox

Quick Start

import asyncio

from microsandbox import Sandbox


async def main() -> None:
    async with await Sandbox.create("python-readme", image="alpine", replace=True) as sandbox:
        output = await sandbox.shell("echo 'Hello from microsandbox!'")
        print(output.stdout_text.strip())


asyncio.run(main())

async with stops and removes the sandbox when the block exits. Use Sandbox.create(...) without a context manager when you want to control stop(), kill(), or remove() yourself.

Common Examples

These snippets assume you already have a live sandbox: Sandbox.

Command Execution

import sys

from microsandbox import ExecEventType

output = await sandbox.exec("python3", ["-c", "print(1 + 1)"])
print(output.stdout_text)
print(output.exit_code)

output = await sandbox.shell("echo hello && pwd")
print(output.stdout_text)

output = await sandbox.exec(
    "python3",
    ["script.py"],
    cwd="/app",
    env={"PYTHONPATH": "/app/lib"},
    timeout=30.0,
)

handle = await sandbox.exec_stream("tail", ["-f", "/var/log/app.log"])
async for event in handle:
    match event.event_type:
        case ExecEventType.STDOUT:
            sys.stdout.buffer.write(event.data)
        case ExecEventType.STDERR:
            sys.stderr.buffer.write(event.data)
        case ExecEventType.EXITED:
            break

Filesystem Operations

fs = sandbox.fs

await fs.write("/tmp/config.json", b'{"debug": true}')
print(await fs.read_text("/tmp/config.json"))

for entry in await fs.list("/etc"):
    print(f"{entry.path} ({entry.kind})")

await fs.copy_from_host("./local-file.txt", "/tmp/file.txt")
await fs.copy_to_host("/tmp/output.txt", "./output.txt")

if await fs.exists("/tmp/config.json"):
    meta = await fs.stat("/tmp/config.json")
    print(f"size: {meta.size}, kind: {meta.kind}")

Named Volumes

from microsandbox import Sandbox, Volume

data = await Volume.create("python-readme-data", quota_mib=100)

writer = await Sandbox.create(
    "python-readme-writer",
    image="alpine",
    volumes={"/data": Volume.named(data.name)},
    replace=True,
)
await writer.shell("echo 'hello' > /data/message.txt")
await writer.stop()

reader = await Sandbox.create(
    "python-readme-reader",
    image="alpine",
    volumes={"/data": Volume.named(data.name, readonly=True)},
    replace=True,
)
output = await reader.shell("cat /data/message.txt")
print(output.stdout_text.strip())
await reader.stop()

Network, DNS, and Ports

from microsandbox import Network, NetworkProfile, Sandbox
from microsandbox.types import DnsConfig

isolated = await Sandbox.create(
    "python-readme-isolated",
    image="alpine",
    network=Network.none(),
    replace=True,
)

filtered = await Sandbox.create(
    "python-readme-filtered",
    image="alpine",
    network=Network(
        deny_domains=("blocked.example.com",),
        deny_domain_suffixes=(".evil.com",),
        dns=DnsConfig(nameservers=("1.1.1.1:53",)),
    ),
    replace=True,
)

web = await Sandbox.create(
    "python-readme-web",
    image="python",
    ports={8080: 80},
    network=Network.from_profiles(NetworkProfile.PUBLIC),
    replace=True,
)

Secrets

Secrets use placeholder substitution. The real value stays on the host and is substituted only for allowed network destinations.

import os

from microsandbox import Sandbox, Secret

sandbox = await Sandbox.create(
    "python-readme-agent",
    image="python",
    secrets=[
        Secret.env(
            "OPENAI_API_KEY",
            value=os.environ["OPENAI_API_KEY"],
            allow_hosts=["api.openai.com"],
        ),
    ],
    replace=True,
)

Rootfs Patches

from microsandbox import Patch, Sandbox

sandbox = await Sandbox.create(
    "python-readme-patched",
    image="alpine",
    patches=[
        Patch.text("/etc/greeting.txt", "Hello!\n"),
        Patch.mkdir("/app", mode=0o755),
        Patch.text("/app/config.json", '{"debug": true}', mode=0o644),
        Patch.append("/etc/hosts", "127.0.0.1 myapp.local\n"),
    ],
    replace=True,
)

Detached Mode

sandbox = await Sandbox.create(
    "python-readme-background",
    image="python",
    detached=True,
    replace=True,
)

handle = await Sandbox.get("python-readme-background")
reconnected = await handle.connect()
output = await reconnected.shell("echo reconnected")
print(output.stdout_text.strip())

TLS Interception

from microsandbox import (
    Network,
    Sandbox,
    ScopedUpstreamCACert,
    ScopedVerifyUpstream,
    TlsConfig,
)

sandbox = await Sandbox.create(
    "tls-inspect",
    image="python",
    network=Network(
        tls=TlsConfig(
            bypass=("*.googleapis.com",),
            verify_upstream=True,
            intercepted_ports=(443,),
            upstream_ca_certs=("/etc/ssl/corp-root.pem",),
            scoped_upstream_ca_certs=(
                ScopedUpstreamCACert("api.internal", "./certs/api-ca.pem"),
            ),
            scoped_verify_upstream=(
                ScopedVerifyUpstream("*.preview.internal", False),
            ),
        ),
    ),
)

Metrics

from microsandbox import MiB, all_sandbox_metrics

metrics = await sandbox.metrics()
print(f"CPU: {metrics.cpu_percent:.1f}%")
print(f"Memory: {metrics.memory_bytes // MiB} MiB")

async for sample in sandbox.metrics_stream(interval=1.0):
    print(f"CPU: {sample.cpu_percent:.1f}%")
    break

for name, sample in (await all_sandbox_metrics()).items():
    print(f"{name}: {sample.cpu_percent:.1f}%")

Typed Errors

Python exports typed errors for the common SDK categories and falls back to MicrosandboxError for unmapped runtime variants. Catch specific errors when you need category-specific handling, and catch MicrosandboxError as the broad SDK base class.

from microsandbox import MicrosandboxError, Sandbox, SandboxAlreadyExistsError

try:
    await Sandbox.create("worker", image="alpine")
except SandboxAlreadyExistsError:
    print("already exists; resume it or pass replace=True")
except MicrosandboxError as exc:
    print(f"microsandbox error: {exc}")

Runtime Setup

Installed wheels bundle the runtime files. The setup helpers are useful for source checkouts, shared runtime installs, and surfacing setup failures at process startup.

from microsandbox import install, is_installed

if not is_installed():
    await install()

More Documentation

Development

From sdk/python:

uv sync --group dev
uv run maturin develop --release
uv run pytest tests
uv run ruff check .

From the repository root, run an example against the SDK project:

uv run --project sdk/python python examples/python/root-oci/main.py

Runtime integration tests require local virtualization support and runtime artifacts:

cd sdk/python
uv run pytest integration/test_create_kwargs.py integration/test_exec.py

License

Apache-2.0

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

microsandbox-0.6.9-cp310-abi3-win_arm64.whl (36.8 MB view details)

Uploaded CPython 3.10+Windows ARM64

microsandbox-0.6.9-cp310-abi3-win_amd64.whl (33.4 MB view details)

Uploaded CPython 3.10+Windows x86-64

microsandbox-0.6.9-cp310-abi3-manylinux_2_28_x86_64.whl (35.9 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.28+ x86-64

microsandbox-0.6.9-cp310-abi3-manylinux_2_28_aarch64.whl (39.0 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.28+ ARM64

microsandbox-0.6.9-cp310-abi3-macosx_11_0_arm64.whl (36.9 MB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

File details

Details for the file microsandbox-0.6.9-cp310-abi3-win_arm64.whl.

File metadata

  • Download URL: microsandbox-0.6.9-cp310-abi3-win_arm64.whl
  • Upload date:
  • Size: 36.8 MB
  • Tags: CPython 3.10+, Windows ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for microsandbox-0.6.9-cp310-abi3-win_arm64.whl
Algorithm Hash digest
SHA256 d9edc1bea7e185013be37ff97d3ff9f1ef7cdb64e87357591cd25b9337fc6b3e
MD5 3d3cb92fd5c797325c32d2ffd0ffb89b
BLAKE2b-256 568efc4252ee4ac6e0cc21884e4016c171050572763d2d629e39cd9d8022d446

See more details on using hashes here.

File details

Details for the file microsandbox-0.6.9-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: microsandbox-0.6.9-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 33.4 MB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for microsandbox-0.6.9-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 90839de0f2e0a5962ad7e49c41a225579d3c99ec24e33ba72717c23e4d2e5089
MD5 aaca00335119e656cca3b92f2ff95131
BLAKE2b-256 66cdc762be576fa7ee2821494e9e7cbcec6cbc830f4f65523b60c21c141224c3

See more details on using hashes here.

File details

Details for the file microsandbox-0.6.9-cp310-abi3-manylinux_2_28_x86_64.whl.

File metadata

  • Download URL: microsandbox-0.6.9-cp310-abi3-manylinux_2_28_x86_64.whl
  • Upload date:
  • Size: 35.9 MB
  • Tags: CPython 3.10+, manylinux: glibc 2.28+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for microsandbox-0.6.9-cp310-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 b5193071cc8c79655459e0be79408b1287f3b3dc6e9a9207b352f28b23e56329
MD5 39e95da6286d783e5a6ac5e11589ea07
BLAKE2b-256 7fa929b81847140a7b195473511a1b0785dd6d775a8d56afd6bccb96fa43373a

See more details on using hashes here.

File details

Details for the file microsandbox-0.6.9-cp310-abi3-manylinux_2_28_aarch64.whl.

File metadata

  • Download URL: microsandbox-0.6.9-cp310-abi3-manylinux_2_28_aarch64.whl
  • Upload date:
  • Size: 39.0 MB
  • Tags: CPython 3.10+, manylinux: glibc 2.28+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for microsandbox-0.6.9-cp310-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 dc61c7496753a2e3b0a4722d0cffbbac1ff754de1b0fd963a2321aca4fcd3c31
MD5 dab40ba465c5f353f05d75386f9c9b1e
BLAKE2b-256 73042699ac852424cb4b6c672a6fe0592debe79320722b0887508fc05da8dd67

See more details on using hashes here.

File details

Details for the file microsandbox-0.6.9-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

  • Download URL: microsandbox-0.6.9-cp310-abi3-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 36.9 MB
  • Tags: CPython 3.10+, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for microsandbox-0.6.9-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 618d9cd3f309f59db5afe7b4301d708f5b8ecfd90abcf2e2f53ae47b56cf126c
MD5 f15de06b26c0b6eadd4b99bd608b0ddd
BLAKE2b-256 83f4a21b50ff460f387e37a544506b879f4a800d0edfc806d238a26d78f6e754

See more details on using hashes here.

Release history Release notifications | RSS feed

0.6.14

5 files

0.6.13

5 files

0.6.12

5 files

0.6.11

5 files

0.6.10

5 files

This release

0.6.9 This release

5 files

0.6.8

5 files

0.6.7

5 files

0.6.6

5 files

0.6.5

5 files

0.6.4

5 files

0.6.3

5 files

0.6.2

5 files

0.6.1

5 files

0.6.0

5 files

0.5.10

3 files

0.5.8

3 files

0.5.7

3 files

0.5.6

3 files

0.5.5

3 files

0.5.4

3 files

0.5.3

3 files

0.5.2

3 files

0.5.1

3 files

0.5.0

3 files

0.4.6

3 files

0.4.5

3 files

0.4.4

3 files

0.4.3

3 files

0.4.2

3 files

0.4.1

3 files

0.4.0

3 files

0.3.14

3 files

0.3.13

3 files

0.1.8

2 files

0.1.7

2 files

0.1.6

2 files

0.1.5

2 files

0.1.4

2 files

0.1.3

2 files

0.1.2

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page