Libvirt

Libvirt uses KVM/QEMU hardware virtualization to run sandboxes as full virtual machines. It provides the strongest isolation of any backend and supports shell, Python, and Node.js sandbox types. It is best for running untrusted code, testing across different OS images, and scenarios that require complete kernel-level separation.

Requirements

  • Linux with KVM support (Intel VT-x or AMD-V)
  • libvirt, QEMU, and related tooling installed
  • User added to libvirt and kvm groups

Installation

Install via your package manager:

Debian / Ubuntu

sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients virtinst genisoimage qemu-utils

Fedora / RHEL

sudo dnf install qemu-kvm libvirt virt-install genisoimage qemu-img

Arch Linux

sudo pacman -S qemu-full libvirt virt-install cdrtools qemu-img

Setup

  1. Enable and start the libvirt daemon

    sudo systemctl enable --now libvirtd
  2. Add your user to the required groups

    sudo usermod -aG libvirt $(whoami)
    sudo usermod -aG kvm $(whoami)

    Log out and back in for the group changes to take effect.

  3. Verify KVM support

    egrep -c '(vmx|svm)' /proc/cpuinfo

    A non-zero result means KVM is supported.

  4. Verify libvirt is running

    systemctl status libvirtd
    virsh list --all

VM images

The libvirt backend uses cloud images as base disks. Supported images:

  • Ubuntu 24.04 (default)
  • Debian 12 (Bookworm)
  • Alpine 3.23

Images are automatically downloaded on first use. The driver searches these paths for existing images:

  1. /var/lib/libvirt/images/
  2. /var/lib/libvirt/boot/
  3. /home/libvirt/images/
  4. ~/.local/share/libvirt/images/ (user-specific fallback, auto-created)

Usage

Select the libvirt backend with the --backend-type flag:

heyvm --backend-type libvirt

Or set it as the default in ~/.heyo/settings.json:

{
  "backend_type": "libvirt"
}

Connection URIs

By default the driver connects to qemu:///session (unprivileged, user-level VMs). Other options:

  • qemu:///system — system-level VMs (requires libvirt group membership)
  • qemu+ssh://user@host/system — remote host over SSH
  • qemu+tcp://host/system — remote host over TCP

Resource configuration

Each VM defaults to 1 vCPU and 1 GB of memory. These can be customized per sandbox via the API:

{
  "cpus": 2,
  "memory": 2147483648
}

Host directory mounts

Host directories can be mounted into the VM using virtio-9p. Inside the guest, mount with:

sudo mount -t 9p -o trans=virtio mount0 /mnt/data

Trade-offs

Libvirt VMs provide the strongest isolation but have higher overhead than other backends:

  • Startup time: 5–10 seconds
  • Base memory: 200–300 MB per VM
  • Full kernel isolation: each VM runs its own kernel

For lighter-weight alternatives, see Bubblewrap or Microsandbox. For more detail, see the mvm-ctrl README.