/dev/kvm on Linux). Granting it is a privileged operation with a real security cost, and every decision below is about paying that cost deliberately.
Prerequisites
- A working BoxLite install (Python
boxliteor Node@boxlite-ai/boxlite) and a machine with hardware virtualization — see Installation.
BoxLite needs hardware virtualization to start each sandbox microVM. A container has no access to/dev/kvmby default, so a box created inside an unprivileged container fails to start and raises a standardRuntimeError(Python) /Error(Node). The configuration below is what grants that access.
Why privileged access is required
Each BoxLite sandbox is a microVM, not a shared-kernel container. Starting a microVM requires the kernel virtualization interface, which on Linux is the character device/dev/kvm. Two conditions must hold inside the container:
- The
/dev/kvmdevice node must be present in the container. - The process must have permission to open it.
--privileged in Docker, securityContext.privileged: true in Kubernetes)
and passing the device through from the host. This is the same trust boundary
you accept whenever you run nested virtualization in a container.
Security consequence: a privileged container can largely bypass container
isolation from the host. The isolation BoxLite gives you is inside the
boxes (each box is a microVM that untrusted agent code cannot escape), not
between the agent service container and its host. Treat the host that runs the
agent service as part of your trusted compute base, and do not co-tenant it
with workloads you do not trust.
Quick Example: minimal agent service
A minimal agent service is your code plus the SDK. The example below is a small handler that runs untrusted code in aCodeBox and returns the result;
it is what you would containerize.
app.py access to
/dev/kvm.
Docker deployment
Run the agent service inside a Docker container. The container must run with--privileged and have /dev/kvm passed through.
Dockerfile
Run with KVM access
Multi-tenancy warning
Running BoxLite inside a privileged Docker container is appropriate for single-tenant deployments where you control everything on the host. It is not recommended for multi-tenant environments: a privileged container weakens the boundary between the container and its host, so a compromise of the agent service container can affect the host and any neighbors on it. For multi-tenant isolation, run each tenant’s agent service on its own dedicated VM rather than relying on the container boundary.Kubernetes deployment
On Kubernetes, the same two requirements apply: the pod must be privileged, and/dev/kvm must be mounted from the host. Because only nodes that actually
expose /dev/kvm can start boxes, schedule the pod onto KVM-enabled nodes with
a node selector.
Pod manifest
Notes
- Privileged pods are a cluster-wide security consideration. If your cluster
enforces Pod Security admission, a
privilegedpod requires theprivilegedpolicy level for its namespace. - Only nodes with KVM available can run these pods. Label and select those nodes explicitly; do not rely on default scheduling.
- The container’s
resources.limitsbound the agent service process, not the individual boxes. Set per-box limits withcpus/memory_mibonBoxOptions(see Compute Resources), and ensure the pod limit is large enough for the sum of concurrent boxes plus overhead.
Pre-deployment checklist
Before shipping a BoxLite-backed agent service:- Per-box resource limits set. Configure
cpus/memory_mib(anddisk_size_gbif you need persistence) on every box so a runaway agent cannot exhaust the host. See Running sandboxes at scale. - Error handling covers low-level failures. Catch standard
RuntimeError(Python) / bareError(Node) in addition toBoxliteError; image pull failures and missing virtualization do not subclassBoxliteError. See Error Handling. - Cleanup is guaranteed. Use
async withfor one-shot boxes, orruntime.remove(id, force=True)for runtime-managed boxes, so sessions are reclaimed. - Concurrency is sized to the host. Estimate total resource use as per-box limits times expected concurrency, and keep it under the pod/host limits.
- Host trust is appropriate. The privileged container does not isolate the agent service from its host; keep untrusted neighbors off the host.
Troubleshooting
Box fails to start inside the container with RuntimeError
The most common cause is that /dev/kvm is not accessible inside the container.
Verify:
--privileged and --device /dev/kvm:/dev/kvm are
set. For Kubernetes, confirm securityContext.privileged: true, the hostPath
mount with type: CharDevice, and that the pod landed on a KVM-enabled node.
Pod is rejected by Pod Security admission
Aprivileged pod requires the privileged Pod Security level for its
namespace. Either run it in a namespace labeled for the privileged policy, or
move the agent service to a dedicated cluster/node pool that permits privileged
pods.
Boxes start but the pod is OOM-killed under load
The pod’sresources.limits.memory bounds the whole pod, including every box’s
microVM memory. Either lower per-box memory_mib and concurrency, or raise the
pod memory limit to cover the sum of concurrent boxes plus overhead. See
Compute Resources.
Node has no /dev/kvm
Not every node supports nested virtualization (this is common on cloud
instance types without nested-virt enabled). Label only the nodes that expose
/dev/kvm and use a nodeSelector so the pod is never scheduled onto a node
that cannot start boxes.
See Also
- Running sandboxes at scale — concurrency, resource limits, isolation, cleanup
- Error Handling — distinguishing command failures from low-level runtime errors
- Building from source — when you need a custom or locally built runtime
- Compute Resources —
cpus/memory_mib/disk_size_gb - Secrets and Security — locking down the blast radius

