Skip to main content

BandSox

BandSox logo

Python library and CLI for managing Firecracker microVMs. Create, snapshot, and restore sandboxes from Docker images. Runs untrusted code or isolates workloads.

Features

  • Millisecond boot times via Firecracker
  • Create VMs from Docker images
  • Pause, resume, and snapshot VMs for instant restore
  • Web dashboard with login, API key management, and terminal sessions
  • CLI for all operations, including auth management
  • Python API for scripting and integration
  • TypeScript SDK for Node.js
  • Optional authentication: API keys for programmatic access, session cookies for the dashboard. Off by default.

Usage

Quick start

Create a VM and run Python code:

from bandsox.core import BandSox

bs = BandSox()
vm = bs.create_vm("python:3-alpine", enable_networking=False)

result = vm.exec_python_capture("print('Hello from VM!')")
print(result['stdout'])  # Hello from VM!

vm.stop()

Python API

from bandsox.core import BandSox

bs = BandSox()

# Create a VM from a Docker image (needs python preinstalled)
vm = bs.create_vm("python:3-alpine", name="test-vm")
print(f"VM started: {vm.vm_id}")

# Run a command
exit_code = vm.exec_command("echo Hello World > /root/hello.txt")

# Run Python code directly inside the VM
result = vm.exec_python_capture("print('Hello World')")
print(result['stdout'])  # Hello World

# Read a file
content = vm.get_file_contents("/root/hello.txt")
print(content)  # Hello World

vm.stop()

Run Claude Code

import os
from bandsox.core import BandSox

bs = BandSox()
vm = bs.create_vm(
    "ghcr.io/bandsox/claude-code:latest",
    env_vars={"ANTHROPIC_API_KEY": os.environ["ANTHROPIC_API_KEY"]},
    # Optional: wire MCP servers (resolved from built-in registry)
    mcp={"github": {"token": os.environ.get("GITHUB_TOKEN", "")}},
)

vm.exec_command(
    "claude --dangerously-skip-permissions -p 'Add a README section about performance'",
    timeout=300,
)
vm.stop()

docs/CLAUDE_CODE.md covers headless prompts, working with a cloned repo inside the VM, and the pause/snapshot/resume pattern for long-running Claude Code sessions. docs/MCP_REGISTRY.md lists the built-in MCP servers and how to add new ones.

Remote server usage

If the BandSox server is already running somewhere, point the Python client at it:

from bandsox.core import BandSox

# With authentication
bs = BandSox("http://localhost:8000", headers={"Authorization": "Bearer bsx_your_key_here"})
vm = bs.create_vm("python:3-alpine", enable_networking=False)

result = vm.exec_python_capture("print('Hello from the server')")
print(result["stdout"])

vm.stop()

Web dashboard

Start the server:

bandsox serve --host 0.0.0.0 --port 8000

Visit http://localhost:8000 to access the dashboard. Authentication is off by default -- see docs/AUTHENTICATION.md to enable it.

Authentication

Auth is off by default. Turn it on with bandsox auth init --storage /var/lib/sandbox. See docs/AUTHENTICATION.md for the full setup, CLI commands, SDK examples, and endpoint reference.

CLI

BandSox includes a CLI tool bandsox (or python -m bandsox.cli).

# Create a VM
bandsox create ubuntu:latest --name my-vm

# Open a terminal
bandsox terminal <vm_id>

# Start the server
bandsox serve --host 0.0.0.0 --port 8000

Prerequisites

  • Linux with KVM support (bare metal or nested virtualization)
  • Firecracker installed at /usr/bin/firecracker
  • Python 3.8+
  • sudo for TAP/NAT setup when networking is enabled (BandSox prompts as needed)
  • Vsock kernel module (virtio-vsock) in the guest kernel for fast file transfers (optional, falls back to serial)

Installation

From PyPI

# Using pip
pip install bandsox

# Using uv
uv pip install bandsox

Then initialize the required artifacts:

bandsox init --rootfs-url ./bandsox-base.ext4

From source

  1. Clone the repo:

    git clone https://github.com/HACKE-RC/Bandsox.git
    cd bandsox
    
  2. Install:

    pip install -e .
    
  3. Initialize artifacts (kernel, CNI plugins, optional base rootfs):

    bandsox init --rootfs-url ./bandsox-base.ext4
    

    This downloads:

    • vmlinux (Firecracker kernel)
    • CNI plugins into cni/bin/
    • (Optional) a base rootfs .ext4 into storage/images/ when --rootfs-url is provided

    Default URLs are provided for kernel and CNI. For the rootfs, build one locally (instructions below) and point --rootfs-url to a local path or file:// URL. Use --skip-* flags to omit specific downloads or --force to re-download.

Architecture

BandSox has four main modules:

  • bandsox.core -- manages VMs, snapshots, and CID/port allocation.
  • bandsox.vm -- wraps the Firecracker process; handles config, networking, vsock bridge, and guest interaction.
  • bandsox/agent -- Go guest agent (bandsox-agent) baked into VM images; runs commands and file I/O over serial and vsock.
  • bandsox.server -- FastAPI backend for the web dashboard and REST API, with built-in authentication.
  • bandsox.auth -- optional authentication. When auth.json exists, enforces API key and session auth. Stores hashed keys and a signing secret. Sessions are HMAC-signed tokens (no server-side state). Rate-limits login attempts.

Storage layout

Default: /var/lib/bandsox (override with BANDSOX_STORAGE env var)

├── images/               # Rootfs ext4 images
├── snapshots/            # VM snapshots
├── sockets/              # Firecracker API sockets
├── metadata/             # VM metadata (including vsock_config)
├── auth.json             # API key hashes, admin password hash, session signing secret
├── cid_allocator.json    # CID allocation state
└── port_allocator.json   # Port allocation state

Docs and API reference

Building a local base rootfs

Build a minimal ext4 from a Docker image:

IMG=alpine:latest          # pick a base image with python if needed
OUT=bandsox-base.ext4
SIZE_MB=512                # increase for more disk
TMP=$(mktemp -d)

docker pull "$IMG"
CID=$(docker create "$IMG")
docker export "$CID" -o "$TMP/rootfs.tar"
docker rm "$CID"

dd if=/dev/zero of="$OUT" bs=1M count=$SIZE_MB
mkfs.ext4 -F "$OUT"
mkdir -p "$TMP/mnt"
sudo mount -o loop "$OUT" "$TMP/mnt"
sudo tar -xf "$TMP/rootfs.tar" -C "$TMP/mnt"

cat <<'EOF' | sudo tee "$TMP/mnt/init" >/dev/null
#!/bin/sh
export PATH=/usr/local/bin:/usr/bin:/bin:/sbin
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts
exec /usr/local/bin/bandsox-agent 2>&1
EOF
sudo chmod +x "$TMP/mnt/init"

# Build the Go agent if needed (requires Go toolchain)
(cd bandsox/agent && go build -ldflags='-s -w' -o agent .)
sudo mkdir -p "$TMP/mnt/usr/local/bin"
sudo cp bandsox/agent/agent "$TMP/mnt/usr/local/bin/bandsox-agent"
sudo chmod 755 "$TMP/mnt/usr/local/bin/bandsox-agent"

sudo umount "$TMP/mnt"
sudo e2fsck -fy "$OUT"
sudo resize2fs -M "$OUT"   # optional: shrink to minimum
rm -rf "$TMP"

Use it with bandsox init --rootfs-url ./bandsox-base.ext4.

You can also skip the base rootfs entirely -- BandSox builds per-image rootfs on demand from Docker images when you call bandsox create <image>.

License

Apache License 2.0

Note: This project wasn't supposed to be made public so it may have artifacts which make no sense. Please open issues so I can remove them.

Metadata

Release files for bandsox 3.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bandsox 3.5
File Size Uploaded Provenance
bandsox-3.5.tar.gz 147.4 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for bandsox 3.5
File Interpreter ABI Platform
bandsox-3.5-py3-none-any.whl Python 3 none any Details

Total release size: 314.0 kB

Release files / bandsox-3.5.tar.gz

Download URL bandsox-3.5.tar.gz
Size 147.4 kB
Tags Source
SHA-256 checksum
How to use checksums
1577a2f486835f2ace932dcdf34d4657ef3f0c5ce940e7a2790bf5c9b4a4021c
BLAKE2b-256 checksum
How to use checksums
770b276a8baf4bb285d6a876ff0663a8c4d4d62338dcb1d91f8c30ae6f4de6c4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.8.14

Release files / bandsox-3.5-py3-none-any.whl

Download URL bandsox-3.5-py3-none-any.whl
Size 166.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
68caedc708970e5f6855d044b712b9b9ce7ca4518cef7c0f10f00a9de5309d72
BLAKE2b-256 checksum
How to use checksums
4fb1d14b2ea088573e74179b80422346802c04dcc3ace02c3c7a5e937d1060b6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.8.14

Security for bandsox 3.5

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page