Quicksand (GitHub Repo)
Quicksand is an asynchronous Python API that simplifies managing QEMU-based Linux virtual machine sandboxes for AI agents without requiring root or Docker.
Decoder
- QEMU: A generic, open-source machine emulator and virtualizer.
- SLIRP: A user-mode networking implementation for QEMU that allows guest OSs to access the internet via the host's network stack without root access.
Original article
Quicksand
Quicksand is an async Python API to launch, control, and snapshot QEMU virtual machines with a particular focus on sandboxing AI agents. Quicksand provides pre-built Linux VMs for Ubuntu and Alpine distros and supports x86_64 and ARM64 across macOS, Linux, and Windows. Running sandboxes needs no root privileges or Docker; install the QEMU and image extras for a bundled runtime on supported platforms.
Installation
pip install 'quick-sandbox[qemu,alpine]'
Or install the core package and add QEMU/images separately:
pip install quick-sandbox
quicksand install qemu alpine
Usage
Hello, World!
import asyncio
from quicksand import Sandbox
async def main():
async with Sandbox(image="ubuntu") as sb:
result = await sb.execute("echo 'Hello from the sandbox!'")
print(result.stdout)
asyncio.run(main())
Run commands
result = await sb.execute("apt update && apt install -y python3")
print(result.stdout, result.exit_code)
Mount host directories
Share host directories into the VM at boot or on the fly.
# At boot
async with Sandbox(
image="ubuntu",
mounts=[Mount("./workspace", "/mnt/workspace")],
) as sb:
...
# Or dynamically on a running sandbox
handle = await sb.mount("/tmp/data", "/mnt/data")
await sb.execute("ls /mnt/data")
await sb.unmount(handle)
Configure networking
Sandboxes are network-isolated by default. Opt in to internet access and port forwarding with NetworkMode.FULL.
async with Sandbox(
image="ubuntu",
network_mode=NetworkMode.FULL,
port_forwards=[PortForward(host=8080, guest=80)],
) as sb:
...
Multiple Linux users
Give multiple agents independent Linux user accounts in a single sandbox VM.
async with Sandbox(image="ubuntu") as sb:
alice = await sb.create_user("alice")
bob = await sb.create_user("bob")
await alice.execute("cat > hello.txt", stdin="Hello from Alice!\n")
await bob.execute("cat > hello.txt", stdin="Hello from Bob!\n")
for user in (alice, bob):
result = await user.execute("whoami && pwd && cat hello.txt")
print(result.stdout)
await sb.delete_user(user.name)
Save and load
Save the VM's disk state to a directory. Load it later, even on a different machine.
await sb.execute("pip install numpy pandas")
await sb.save("my-env") # VM keeps running
# Load later
async with Sandbox(image="my-env") as sb:
await sb.execute("python3 -c 'import numpy; print(numpy.__version__)'")
Checkpoint and revert
Capture the full VM state and roll back if something goes wrong.
await sb.checkpoint("before-experiment")
await sb.execute("apt install -y something-risky")
await sb.revert("before-experiment") # the VM snaps back to the checkpoint
Control a desktop
Desktop images provide a full Xfce4 graphical environment with a browser. Install one with quicksand install ubuntu-desktop or quicksand install alpine-desktop.
async with Sandbox(image="ubuntu-desktop", enable_display=True) as sb:
await sb.screenshot("screen.png")
await sb.type_text("hello world")
await sb.press_key(Key.RET)
await sb.mouse_move(500, 300)
await sb.mouse_click("left")
Configuration
Here are all of the Sandbox configuration options:
Sandbox(
# Image or save name to boot
image="ubuntu",
# Guest RAM (default: "512M")
memory="2G",
# Virtual CPU cores (default: 1)
cpus=4,
# Host directories shared into the VM at boot
mounts=[Mount("/host", "/guest")],
# NONE, MOUNTS_ONLY (default), or FULL internet access
network_mode=NetworkMode.FULL,
# Forward host TCP ports into the guest
port_forwards=[PortForward(host=8080, guest=80)],
# Expand the guest filesystem on boot
disk_size="10G",
# Attach virtual GPU, keyboard, and mouse for screenshot/type_text/mouse control
enable_display=True,
# Auto-save VM state on stop
save="my-save-name",
)
Available images
| Image | Type | Wheel size | Install command | What is it |
|---|---|---|---|---|
ubuntu |
Base | ~309-357 MB | quicksand install ubuntu |
Ubuntu 24.04 headless |
alpine |
Base | ~82-85 MB | quicksand install alpine |
Alpine 3.23 headless (faster boot) |
ubuntu-desktop |
Overlay (ubuntu) |
~273-281 MB | quicksand install ubuntu-desktop |
Ubuntu 24.04 + Xfce4 + Firefox |
alpine-desktop |
Overlay (alpine) |
~346-363 MB | quicksand install alpine-desktop |
Alpine 3.23 + Xfce4 + Chromium |
quicksand-agent |
Overlay (ubuntu) |
~306-335 MB | quicksand install quicksand-agent |
Ubuntu + Python 3.12, uv, build-essential, requests, pyyaml, ddgs, markitdown |
quicksand-cua |
Overlay (quicksand-agent) |
~489-500 MB | quicksand install quicksand-cua |
Agent Sandbox + Xvfb, x11vnc, noVNC, Playwright, Chromium |
Sizes are approximate full image-wheel downloads for the September 14, 2026 releases and vary by architecture. Overlay sizes exclude their base images.
Building from source
git clone https://github.com/microsoft/quicksand.git
cd quicksand
uv sync
uv run uvr build --all-packages
Documentation
| Topic | Guide | Under the Hood |
|---|---|---|
| Installation | Installing packages | QEMU binaries, kernels, qcow2 disks |
| Sandbox Lifecycle | Creating and configuring sandboxes | -m, -smp, -accel, machine types |
| Running Commands | execute(), streaming, exit codes |
Kernel boot, agent tokens, hostfwd |
| File Exchange | Mounts, hot-mounts, getting data in/out | CIFS via guestfwd, 9p via -fsdev |
| Save and Rollback | Checkpoints, reverts, persistent saves | qcow2 overlays, savevm, blockdev-snapshot-sync |
| Desktop Control | Screenshots, keyboard, mouse | VNC, GPU, USB tablet, QMP input injection |
| Network and Isolation | Network modes, port forwarding | SLIRP NAT, restrict=on, guestfwd |
| Performance | What makes it fast | io_uring, IOThreads, TCG vs KVM |
Contributing
| Guide | When to use |
|---|---|
| Creating Images | Build a new base or overlay image package |
| Extending the Sandbox | Add a method, OS, architecture, or QEMU flag |
| Testing | Run or write tests |
| Releasing | Cut a release |
Fresh dev news, AI-digested daily. Never miss a trend at devoured.fyi