Skip to main content
Yanked

This release has been yanked by its maintainers, and will be ignored by installers, except when explicitly specified.
Consider using release 0.6.14 instead.
Reason given by maintainers: missing migrations for proper downgrade

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

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 "stdout":
            sys.stdout.buffer.write(event.data)
        case "stderr":
            sys.stderr.buffer.write(event.data)
        case "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, 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.public_only(),
    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.5-cp310-abi3-win_arm64.whl (34.1 MB view details)

Uploaded CPython 3.10+Windows ARM64

microsandbox-0.6.5-cp310-abi3-win_amd64.whl (30.5 MB view details)

Uploaded CPython 3.10+Windows x86-64

microsandbox-0.6.5-cp310-abi3-manylinux_2_28_x86_64.whl (32.9 MB view details)

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

microsandbox-0.6.5-cp310-abi3-manylinux_2_28_aarch64.whl (36.1 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.28+ ARM64

microsandbox-0.6.5-cp310-abi3-macosx_11_0_arm64.whl (34.3 MB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

File details

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

File metadata

  • Download URL: microsandbox-0.6.5-cp310-abi3-win_arm64.whl
  • Upload date:
  • Size: 34.1 MB
  • Tags: CPython 3.10+, Windows ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.27 {"installer":{"name":"uv","version":"0.11.27","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.5-cp310-abi3-win_arm64.whl
Algorithm Hash digest
SHA256 184cb0a9adc865b926ac6775388b6172c6b871983de91337bbb550e68493d5e8
MD5 6dba8f8bac4a38622180deccf2ce9603
BLAKE2b-256 910324f8e755ee835122b9697d1637df176a99ab46e9169d48a839cc3b7d6265

See more details on using hashes here.

File details

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

File metadata

  • Download URL: microsandbox-0.6.5-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 30.5 MB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.27 {"installer":{"name":"uv","version":"0.11.27","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.5-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 f9573a45a917d50e16dd7306342dd9fe6325ac0c9608578d8d2cf6bd79b7b45c
MD5 482cb6f3251c77cbd3b9ea3a7774ab6c
BLAKE2b-256 bd111e5407ddc287d67396d21b2c428f2de4a87ca24d5ecae6c0804d140f7550

See more details on using hashes here.

File details

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

File metadata

  • Download URL: microsandbox-0.6.5-cp310-abi3-manylinux_2_28_x86_64.whl
  • Upload date:
  • Size: 32.9 MB
  • Tags: CPython 3.10+, manylinux: glibc 2.28+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.27 {"installer":{"name":"uv","version":"0.11.27","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.5-cp310-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 b3f4d0bf403706b7b0a5f2cc27c44b26ddd2daf1427e4e449ba2e77f485b09ed
MD5 ad1e30a733b6954117508c8367d66694
BLAKE2b-256 e56b0fdde4ec30d38f2465e82493a7a30b9cd194e02ab82807fe111dbac32f33

See more details on using hashes here.

File details

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

File metadata

  • Download URL: microsandbox-0.6.5-cp310-abi3-manylinux_2_28_aarch64.whl
  • Upload date:
  • Size: 36.1 MB
  • Tags: CPython 3.10+, manylinux: glibc 2.28+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.27 {"installer":{"name":"uv","version":"0.11.27","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.5-cp310-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 7bebe7c2bc5b760f282fa1d5292d69e5304d8220a4691ece58b945c4f87da866
MD5 4ffd0beffad251f7527473ea480596fc
BLAKE2b-256 77bfd6e15ad0d5c2bcb07f2b4ff682d14957419d012c42fd7e92fcd8d39ed99a

See more details on using hashes here.

File details

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

File metadata

  • Download URL: microsandbox-0.6.5-cp310-abi3-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 34.3 MB
  • Tags: CPython 3.10+, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.27 {"installer":{"name":"uv","version":"0.11.27","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.5-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 cc894f8973cae4142f992aacbe6391eb58f70b26112faa5197e10e94f07be507
MD5 37f01d07b107be278ecfcbe67ad0a29c
BLAKE2b-256 46a5967e7c24b16521e5ad406ea426c6db9b1586d1dac531650a39212f6e91a8

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

0.6.9

5 files

0.6.8

5 files

0.6.7

5 files

0.6.6

5 files

This release

0.6.5 This release

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