bVisor is an SDK and runtime for securely running Linux sandboxes, locally.
Inspired by gVisor, bVisor runs workloads directly on the host machine, providing isolation by intercepting and virtualizing linux syscalls from userspace, allowing for secure and isolated I/O without the overhead of a virtual machine or remote infra.
Unlike gVisor, bVisor is built to run directly in your application, spinning up and tearing down sandboxes in milliseconds. This makes it ideal for ephemeral tasks commonly performed by LLM agents, such as code execution or filesystem operations.
It is currently a proof-of-concept, and not something you'd be able to easily use yet. But soon!
bVisor is built on Seccomp user notifier, a Linux kernel feature that allows userspace processes to intercept and optionally handle syscalls from a child process. This allows bVisor to block or mock the kernel API (such as filesystem read/write, network access, etc.) to ensure the child process remains sandboxed.
Other than the overhead of syscall emulation, child processes run natively.
bVisor will be ~complete once it can embed into higher-level languages, such as into Python or TypeScript, as an alternative "bash" subprocess runner.
For example, embedded into a Python SDK:
from bvisor import Sandbox
with Sandbox() as sb:
sb.bash("echo 'Hello, world!'")
sb.bash("ls /") # serves virtual "/"
sb.bash("touch /tmp/test.txt")
sb.bash("curl https://www.google.com")
sb.bash("npm install")
sb.bash("sleep 5")
try:
sb.bash("chroot /tmp") # blocked
except Exception as e:
pass # as expectedOr similarly in TypeScript:
import { Sandbox } from "bvisor";
using sb = await Sandbox.create();
await sb.bash("echo 'Hello, world!'");
// etc ...bVisor is an early proof-of-concept. Core syscall interception works via seccomp. Process isolation works via virtual namespaces. Now just working through the laundry list of misc syscalls.
Sandboxed processes can only see and signal other processes within the same namespace. Processes use real kernel PIDs, but namespace boundaries control visibility.
- Virtual namespaces with parent/child relationships.
-
killrestricted to processes within namespace -
/procreads filtered to visible processes only -
clone/forkinherit namespaces, mimicking real kernel behavior - Per-process virtual FD tables
-
wait4/waitidfor process reaping -
execvefor program execution
bVisor is imageless, meaning it does not require a base image to run. It runs with direct visibility to the host filesystem. This allows system dependencies such as npm to work out of the box.
Isolation is achieved via a copy-on-write overlay on top of the host filesystem. Files opened with write flags are copied to a sandbox-local directory. Read-only files are passed through to the real filesystem.
- Path normalization (blocks
..traversal attacks) -
openatwith path-based allow/block rules - COW (copy-on-write) layer for write operations
- Storage backend for COW (plans for /tmp, local, s3)
- FD operations (
read,write,close,dup,lseek,fstat,fcntl) - Directory operations (
getcwd,chdir,mkdirat,unlinkat,getdents64)
- Block or virtualize network syscalls
- Optional allowlist for specific hosts/ports
- CPU/memory limits
- I/O throttling
Prevent leaking host system details in multi-tenant environments.
-
uname- kernel version, hostname -
sysinfo- total RAM, uptime, load -
getrlimit- resource configuration -
getrusage- resource usage stats
Core
- Seccomp user notifier interception
- Supervisor/child process model
- BPF filter installation
- Cross-process memory access (
process_vm_readv/writev) -
writevemulation (stdout/stderr capture)
Blocked Dangerous Syscalls
-
ptrace,mount,umount2,chroot,pivot_root,setns,unshare,seccomp,reboot,prlimit64
Passthrough (kernel handles directly)
- Memory:
brk,mmap,mprotect,munmap - Time:
clock_gettime,gettimeofday,nanosleep - Identity:
getuid,geteuid,getgid,getegid - Runtime:
getrandom,futex
- Linux (aarch64, x86_64)
- macOS - requires alternative to seccomp (no equivalent exists)
- Compile runtime for distribution
- Python bindings
- TypeScript bindings
bVisor is written in Zig. Zig is pre-1.0, so compilation is only guaranteed with the exact zig build. We're using a tagged commit on 0.16 dev, which includes major breaking changes (Io) compared to previous versions, so please use the exact version specified in the build.zig.zon file. It's also recommended to compile ZLS from source using a tagged commit compatible with Zig. You'll be flying blind otherwise.
bVisor depends on Linux kernel features, although it's developed primarily on ARM Macs and tested via Docker. The build.zig is currently configured to cross-compile aarch64-linux-musl, so running zig build will produce a binary in zig-out/bin/bVisor which will only run in a Linux container. Use zig build run to execute the binary in a container.
There are three ways to test:
Native unit tests
zig build testruns unit tests on your Mac. It's intended for quick correctness checks for anything behind the seccomp notification layer (syscall handlers, namespace isolation, virtual filesystem, etc). Prefer to use POSIX APIs over Linux where possible, to allow more tests to natively run on Mac. If POSIX APIs are not available, we can do comptime dependency injection (seesrc/deps) to use Mac-compatible mocks when running on Mac.
Containerized unit tests
zig build test -Duse-dockerruns the same tests aszig build testbut in a Linux container. This exercises the Linux deps insrc/deps.
E2E test in linux container
zig build runruns the full executable in a Linux container, executingsmoke_test.zigas a sandboxed guest process. It will print out a scorecard detailing which features are supported so far. The goal is to get it to 100%, and then to add more tests!