Skip to content

Add exec-sandbox backend (self-hosted QEMU microVMs) #151

Description

@clemlesne

Add exec-sandbox backend (self-hosted QEMU microVMs)

Summary

Proposing exec-sandbox as a new SandboxBackend option. It runs code in ephemeral QEMU microVMs with hardware-level isolation (KVM on Linux, HVF on macOS) — no cloud account or Docker required.

Why

  • VM isolation — Current backends (Docker, Podman, Kubernetes) all use container-level isolation. exec-sandbox provides hardware-level VM boundaries — stronger security for untrusted code.
  • Self-hosted, no Docker — Runs on bare metal with just QEMU. No container runtime dependency. Useful on macOS dev machines without Docker Desktop.
  • macOS + Linux — HVF on macOS, KVM on Linux. Same codebase.
  • Fast — ~1-2ms from warm pool, ~200ms from memory snapshots.
  • Apache-2.0

How it maps

exec-sandbox is a Python library with an async API. Following the existing backend pattern:

1. Add enum value in const.py:

class SandboxBackend(StrEnum):
    EXEC_SANDBOX = "exec_sandbox"

2. Add match arm in session.py:

case SandboxBackend.EXEC_SANDBOX:
    from .exec_sandbox import SandboxExecSandboxSession
    return SandboxExecSandboxSession(*args, **kwargs)

3. Implement session extending BaseSession:

BaseSession method exec-sandbox mapping
open() Start Scheduler, create session
close() Close session and scheduler
run(code) session.exec(code)
execute_commands(commands) session.exec(command) per command
copy_to_runtime(src, dest) session.write_file(path, content)
copy_from_runtime(src, dest) session.read_file(path, destination)
_handle_timeout() Close session

The main difference from container backends (Docker, Podman, Kubernetes, Micromamba): exec-sandbox doesn't have a ContainerAPI that matches the create/start/stop/exec protocol. The session would need to either implement ContainerAPI by adapting the VM lifecycle, or override the mixin methods directly.

Open questions

  • ContainerAPI fit — The ContainerAPI Protocol is container-centric (create_container, start_container, etc.). exec-sandbox's VM lifecycle is different (scheduler → session). Should the adapter fake a ContainerAPI, or override the mixin methods?
  • Async/sync bridge — exec-sandbox is fully async. The session methods are sync. A dedicated event loop bridges the gap.

Links

Happy to submit a PR if there's interest.

Metadata

Metadata

Assignees

No one assigned

    Labels

    backendpythonPull requests that update python code

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions