Skip to content

Who JailBee is for

JailBee gives each git branch a long-lived system container: an unprivileged Incus container with its own init and IP, and — if the repo needs them — its own Docker daemon, browser and IDE on your desktop. Several branches can each boot the same stack, listen on localhost:3000 and run a browser against it, without sharing the host's Docker daemon or allocating host ports.

It is a container, not a VM. User namespaces, cgroups, AppArmor and seccomp provide a kernel-enforced boundary, but the host kernel is shared. Devices, mounts and host services you attach deliberately widen that boundary. If you need a hypervisor between the workload and your laptop, JailBee is not the answer; see Security and limitations.

You'll recognise yourself if…

  • You're on Linux and you control the host.
  • The runtime is the hard part. Your work boots services, runs a database, spawns an emulator, opens a browser or shells out to docker.
  • You want several of those running at once — a feature, a review, an agent experiment — without renaming Compose projects or hunting for ports.
  • You leave coding agents running unattended, but want their own checkout, bounded host access and a snapshot to restore when something goes wrong.

Choose by the problem you have

  • Dev Containers: a standard, portable toolchain the team can adopt with little ceremony. This is the first option most teams should try.
  • BranchBox: parallel worktrees and Compose stacks, with stack detection and editor integration doing much of the setup.
  • nono: fine-grained filesystem and network policy around an agent and its tools, without provisioning another machine.
  • Docker Sandboxes: a microVM boundary with a separate kernel and brokered API credentials around a supported agent.
  • JailBee: a persistent runtime per branch, with its own Docker, localhost, desktop apps and git transport back to the host. You accept Linux-only host setup and a shared kernel in return.

How this differs from the alternatives

The table compares built-in or documented support, not everything you could build on top of each tool. ✅ supported, 🟡 supported with the qualification in the cell, ❌ no built-in or documented support found, n/a outside that tool's role. Defaults and opt-in configurations are named explicitly. A ❌ is not a claim that a custom integration is impossible. The source note records the versions and scope checked.

Dev Containers BranchBox nono Docker Sandboxes JailBee
What it is a toolchain in a container a worktree + Compose per feature a fence around one process a microVM for an agent a Linux environment per branch
Boundary Docker container; host daemon by default Docker container by default; opt-in microVM runtimes Landlock + seccomp, Seatbelt hypervisor, own kernel Incus container, shared kernel
Run the repo's docker-compose.yml ✅ ✅ n/a — does not provision a runtime ✅ ✅
…without using the host's Docker daemon for the repo's stack 🟡 privileged docker-in-docker 🟡 generated template uses privileged Docker-in-Docker; opt-in VM runtimes also available n/a ✅ ✅ when the Docker stack is enabled
Separate runtimes both listening on :3000 ✅ container-local ports; distinct host ports if published 🟡 separate stacks; host port mappings must not collide n/a — no separate network stack ✅ VM-local ports; host forwarding still needs distinct ports ✅ no forwarding for an in-container browser
Run an emulator or a VM (/dev/kvm) 🟡 explicit device passthrough ❌ n/a — host device permissions still apply ❌ documented device support is an experimental NVIDIA GPU ✅ host_devices
Browser and IDE inside the boundary, as native desktop windows ❌ community noVNC desktop instead ❌ n/a — they run on the host ❌ ✅ Wayland passthrough
Built-in egress policy ❌ 🟡 local-vm blocks host and private networks ✅ per tool, including HTTP method and path ✅ hostname rules for TCP, HTTP method and path ✅ NIC ACL plus HTTP(S) hostname proxy; explicit host connections are exceptions
Stage agent's GitHub writes for human publication ❌ ❌ 🟡 token proxy can block writes; no outbox 🟡 method/path rules can block writes; no outbox 🟡 outbox; requires a correctly scoped read-only container token
Workspace separate from the host's main checkout 🟡 opt-in clone into a volume 🟡 separate worktree; shared git repository 🟡 path grants, not a separate checkout 🟡 opt-in --clone 🟡 clone by default; --mount shares the host checkout
Built-in host ↔ environment git bridge ❌ no bridge for a volume clone n/a — worktrees share the repository n/a ❌ no bridge for a --clone copy ✅ jailbee git push/pull/diff
Snapshot and restore the current environment ❌ rebuild instead ❌ 🟡 filesystem rollback in supervised mode on Linux and macOS 🟡 sbx template save creates a template, not in-place rollback 🟡 container snapshot; host mounts and shared state excluded
Separate guest kernel ❌ 🟡 opt-in VM runtimes ❌ ✅ ❌
macOS or Windows host support ✅ 🟡 macOS 🟡 Windows via WSL2 ✅ hardware virtualisation required ❌ Linux host required
Repo-carried environment specification ✅ devcontainer.json 🟡 generated from stack detection n/a — agent policy profiles 🟡 agent/team kits ✅ .jailbee/config.yaml
Licence / distribution open spec (MIT); VS Code's extension is Microsoft's MIT Apache-2.0 free CLI, Docker sign-in required, governance is paid GPL-3.0-or-later

Toolchain per branch: Dev Containers and BranchBox

Dev Containers wins on ecosystem and adoption: a committed .devcontainer/devcontainer.json, a Features marketplace, prebuilt images, three host OSes and implementations beyond VS Code (GitHub Codespaces, JetBrains, DevPod). If you need everyone to have the same Node and psql, start here.

Its usual local workflow is not designed to contain an unattended agent. The workspace is bind-mounted read-write and credentials are forwarded; "Clone Repository in Container Volume" is the separate-checkout alternative. Services are normally reached through host port forwarding. There is no built-in egress policy. The standard Docker Features offer either privileged Docker-in-Docker or the host Docker socket, which gives access to the host daemon. A community desktop-lite feature provides a desktop over noVNC, not native windows on your compositor.

You can extend this setup with networking, device mappings and custom security controls. JailBee's difference is that it integrates those concerns with a branch lifecycle, rather than asking the team to assemble them.

BranchBox (MIT, Rust) combines a git worktree, a Compose project and a generated devcontainer per feature. Stack detection, prebuilt images, macOS support, VS Code/Cursor integration and optional Cloudflare tunnels make it lighter to adopt. A worktree keeps feature files separate, but shares the underlying git repository rather than being an independent clone.

The current generated generic devcontainer uses privileged Docker-in-Docker and host IPC, with writable Claude, Codex and GitHub CLI configuration mounts; other credential files are read-only. This differs from directly mounting the host Docker socket, but is still not a separate-kernel boundary. Existing projects may use different Compose configurations.

Opt-in Docker Sandboxes and an experimental Firecracker local-vm runtime provide VM boundaries. The latter blocks guest-initiated host/private-network access and does not mount the host Docker socket or shared agent credential directories; credentials can still be explicitly injected. These VM boundaries are stronger than JailBee's; the default remains a Docker container workflow. JailBee adds a native in-container desktop, declared devices, a separate checkout with a git bridge, and in-place container snapshots.

Fenced agents: nono and Docker Sandboxes

nono (Apache-2.0, Rust) applies policy to an agent process and its tools, without a container or VM. A tool such as gh can receive its own filesystem grants and use a token proxy that filters API requests by method and path. Supervised mode offers filesystem rollback snapshots on Linux and macOS. These are finer-grained controls than JailBee provides; composable JSON profiles can be shared through a registry.

It does not provision a second runtime or network stack. nono's own security model calls itself "intentionally a different model from a guest/host isolation boundary" and recommends a container or microVM perimeter with nono inside it. nono inside JailBee is a sensible combination when you want both a separate runtime and tool-specific policy.

Docker Sandboxes (sbx) gives each local sandbox its own kernel and Docker daemon. Outbound TCP goes through a host-side proxy, with hostname rules for TCP ports, HTTP method/path rules and experimental UDP. Traffic needs an allow rule, but the supplied policy includes broad domain wildcards: inspect it rather than assuming an empty allowlist. Supported API credentials are injected into request headers instead of entering the VM. For those tokens, this is stronger than making a readable token file available inside an environment. If a hypervisor boundary is required, sbx meets that requirement and JailBee does not.

The distinction is the workflow around the boundary:

  • Branch lifecycle. JailBee starts configured services and keeps the environment for subsequent human or agent sessions. sbx is organised around supported agents (sbx run claude), but also persists across stops and restarts until removed. sbx template save creates reusable templates, not in-place rollback snapshots, and excludes mounted filesystems, including the workspace and Docker data.
  • Separate checkout and transport. sbx run mounts the host workspace read-write by default; --clone creates a private working copy while still exposing the source repository read-only. sbx create can also create a mountless sandbox. JailBee uses a shared Git clone by default: its working tree and refs are separate, but it borrows the host repository's object store. It tracks the base branch and provides a host/container git bridge, PR flow and a review outbox. Its opt-in --mount mode instead shares the host checkout read-write. Its ordinary destroy flow warns about detected work at risk; it is not a proof that every change is backed up.
  • Native desktop and host integration. JailBee can attach devices and host-agent sockets, and run Chrome or a JetBrains IDE on your Wayland session. These connections are also security trade-offs. VMs can broker host services too, but sbx documents no equivalent compositor, smartcard or adb integration; its documented device passthrough is an experimental NVIDIA GPU.
  • Configuration and distribution. JailBee carries the environment spec in the repo and runs locally without a JailBee account. sbx kits package workload/mixin configuration; Docker sign-in is mandatory and centrally managed policy is paid.
  • Storage model. JailBee creates containers from a reusable golden image; copy-on-write sharing depends on the Incus storage backend. Docker documents that sandboxes do not share images or layers. A suitable backend can favour JailBee for many similar environments, but this is not a measured disk or memory comparison.

Both can run a Docker stack. Choose sbx when the stronger kernel boundary is decisive; choose JailBee when branch lifecycle, native desktop apps and explicit host integration are the work you would otherwise build yourself.

Two more you may be thinking of

Neither has been checked in the same depth as the four above:

  • container-use (Dagger, Apache-2.0) gives each agent a container plus a git worktree over MCP, driven from the agent's side.
  • microsandbox (Apache-2.0) runs OCI images in local libkrun microVMs without a daemon or root, behind SDKs.

Two that are not alternatives at all, although they are often named in the same breath.

Microsoft MXC (MIT, Rust) is a library, not an environment: an agent host or tool embeds its Rust, .NET or Node SDK to run one command — model output, a plugin, a tool call — under a declared path and network policy, then usually discards the sandbox. It is closest to nono, using Bubblewrap on Linux, Seatbelt on macOS and native containment on Windows. Nothing provisions a repo's runtime, so it complements JailBee rather than replacing it: an agent that uses MXC could run inside a JailBee container, a combination not validated here.

herdr (Apache-2.0, Rust) is a terminal multiplexer for coding agents — a background server keeps each agent's terminal alive, a sidebar shows whether it is working, blocked or idle, and a socket API lets agents open panes and wait on each other. Its panes are plain host processes: it has no isolation of its own or built-in per-branch runtime. It overlaps the terminal-session layer of JailBee's dashboard and in-container tmux, rather than replacing Incus isolation. Running it inside JailBee is a possible integration, not one validated in this comparison.

Where that leaves JailBee

The argument for JailBee is the combination, not a claim to the strongest sandbox or the broadest ecosystem:

  1. A long-lived runtime per branch, declared by the repo, with its own Docker daemon when enabled and services started by configured autostart. Background stages can still be running when you attach.
  2. A desktop inside it, against its own localhost, without host port allocation for each branch's browser.
  3. A separate checkout and git bridge, with snapshots, PR workflows and dashboards across repos.
  4. Explicit host integration for devices, mounts and services, accepting the wider attack surface each connection brings.

The idea: isolation by boundary, not by allowlist

A process sandbox grants access to selected paths, hosts and tools. This is valuable when you need fine-grained policy, and per-tool grants can avoid widening permissions for everything else. But a changing development stack may require repeated policy work: a new service, browser or emulator can need a different set of filesystem, process and network permissions.

JailBee instead provides a separate Linux userland and network stack. Installing another ordinary tool inside it does not require a new host-filesystem grant. Egress destinations, host devices and mounts still need explicit configuration — the boundary does not make those free.

You want to… Inside a JailBee container
Run the repo's Compose stack Its own Docker daemon runs the stack without changing Compose project names or remapping ports just to coexist with another branch.
Run an emulator or a KVM VM Declare host_devices: [{ path: /dev/kvm }]; install and configure the emulator inside.
Use a phone plugged into the host Declare host_ports: [{ name: adb, port: 5037 }] to reach the host adb server. Recipe.
Test in a real browser jailbee chrome <name> / jailbee firefox <name> runs a browser inside, rendered on your Wayland session, against the container's own localhost:3000.
Edit with a JetBrains IDE jailbee ide <name> uses the same display passthrough.
Run services or install tools Use systemd and the container's package manager.

And the agent is still fenced in

  • Egress policy. In strict mode, a kernel ACL filters traffic through the container's network interface, including SSH and database connections. JailBee resolves concrete allowlisted hostnames and writes their address pool to /etc/hosts; failed lookups can leave older addresses in use. Wildcards are proxy-only rules, not IP ACL or hosts entries. On the work network, a Squid proxy additionally checks HTTP(S) hostnames for tools that honour the proxy variables, including wildcard rules. TLS is not intercepted; direct traffic is checked by the IP ACL, which cannot distinguish hosts sharing an allowed IP. Declared port forwards and attached host sockets are deliberate exceptions, not traffic covered by this ACL. See Egress proxy and Port forwards for the limits.
  • GitHub review gate. With a correctly scoped read-only container token, agents stage GitHub changes in an outbox; you review and publish with the host's gh. JailBee cannot verify that token's effective permissions. A write-capable token bypasses the gate. Strict networking is not a GitHub write filter: the Claude preset's default plugin support adds github.com to the effective allowlist, and HTTPS access does not distinguish reads from writes.
  • Host access needs inspection. The default GnuPG integration mounts the host's entire .gnupg directory read-only, which can expose disk-stored private keys as well as sockets. A read-only agent socket can still sign and authenticate: read-only does not remove that authority. Hardware-key touch requirements depend on the key's configuration. Gitconfig is read-only by default, but shared SSH configuration is writable; its initial config.d copy is recursive and follows symlinks. Wayland attaches on demand; D-Bus and PulseAudio are opt-in. Shared caches and agent settings are writable shared state, so snapshots do not roll back everything reachable.
  • Own clone and snapshots. In the default clone mode, the agent edits the container's working tree, not your main checkout. Snapshot before a run and restore the container afterwards; host mounts and shared volumes remain outside that protection, including the borrowed Git object store. A container snapshot is not a self-contained repository backup. jailbee new --mount shares the host checkout read-write instead, so it does not provide this separation.

Running an agent without its in-process sandbox is a trade to make after reviewing the effective mounts, devices, credentials and network policy, not a guarantee supplied by strict mode alone. See Running an agent without prompts.

Whichever agent you run

Linux-compatible terminal agents can run inside, subject to their runtime, authentication and network requirements. agents: presets wire installation, mounts, egress and autostart for codex, gemini, aider, opencode and grok; the maintainers use Claude Code daily, while the others are starting points. Generic agent support covers custom setups.

Claude logins can be shared among containers in a credential group; jailbee account manages stored logins. For other providers' models, claude-jb routes Claude Code through JailBee's separate LiteLLM service. Provider credentials are not delivered to dev containers by that integration; host API-key source files remain on the host. Dev containers receive a shared account-level proxy master key, not a per-repo spending or authorization boundary. See Claude Code through LiteLLM.

The repo decides how its containers run

The committed .jailbee/config.yaml declares stacks and provisioning, autostart services, devices, egress, shared caches and GUI apps. Host-level global.yaml supplies personal defaults; host-local repos/<prefix>.yaml can override a repo's settings without committing tokens or machine-specific choices. The effective environment depends on all those layers.

host_mounts are read-write by default. Use readonly: true to prevent file modification, not to hide secrets or disable socket access; leave sensitive paths unmounted unless needed. optional_mounts remain detached until requested and record a TTL (jailbee mount --for 2h, 15 minutes by default). Automatic expiry needs the host refresh service and can be deferred while autostart holds the container. Detachment does not erase copied data. host_ports connects declared host services to container localhost.

jailbee config edit edits the layers and jailbee apply updates profiles, mounts and network settings. Changes to the golden image's installed stacks or provisioning require a rebuild. See Configuration reference.

Getting code in and out

In clone mode, each container is a git remote. The jailbee git push/pull/fetch transport is local, including submodule objects; diff compares state rather than transferring commits. The default push first attempts to refresh the host's upstream ref, so local transport does not mean the command is offline. Base-branch tracking supports review and stacked work; jailbee git merge and jailbee fork let containers exchange or branch from committed work.

jailbee new --pr <N> creates a review environment, and host-side jailbee pr push opens or updates a PR (new PRs are drafts by default). Ordinary destruction checks dirty files, submodule changes and whether commits appear preserved on the host or in container remote-tracking refs. Those refs may be stale, and stopped-container state may be unknown. Risk or uncertainty prompts for extra confirmation; force and unconditional cleanup policies bypass the guard. See Git bridge.

Driving it

By default, bare jailbee opens the terminal dashboard (the default command is configurable); jailbee gui opens the optional Qt version. Both span repos and show git status, CPU use and Claude Code's busy/waiting/idle state, with actions on selected containers. CLI commands prompt for omitted required values on an interactive terminal, and jailbee console provides completion and history.

Optional SSH access offers a restricted dashboard, console, commands and SFTP. Remote GUI uses waypipe ssh with a compatible Wayland client (including experimental macOS support), or RDP clients connecting to a shared display. See Remote GUI over SSH.

What JailBee costs you

  • Linux host required. macOS and Windows can be remote clients; running JailBee in a Linux VM on a Mac is experimental. See Using JailBee from a Mac.
  • Host setup and image builds. Incus, UID delegation, firewall and kernel limits take real setup work. Budget an afternoon for Installation, then roughly 10–15 minutes for an initial golden image per stack. Some upgrades require a rebuild and apply.
  • Disk and shared state. Copy-on-write-capable storage can reduce the cost of similar containers, but does not make them free. Shared caches, agent settings and credential groups also mean not all damage is contained to one branch or reversed by its snapshot.
  • GUI integration has limits. JetBrains, Chrome and Firefox have built-in launchers; other apps need an apps: entry and an installed binary. There is no devcontainer editor integration. Only one IDEA-family IDE can run at a time across containers with the shared profile; browsers have per-container profiles.
  • A shared kernel. A kernel vulnerability is an escape path. This is not a hostile multi-tenant boundary. Incus supports VMs, but JailBee does not use them; Docker Sandboxes and BranchBox's opt-in VM runtimes provide a separate guest kernel.
  • Readable tokens and usable sockets. Mounted API tokens can be read by code inside. Agent sockets permit signing/authentication requests, and the GnuPG directory mount can also expose private-key files. A credential proxy avoids disclosing supported API tokens to the guest; it does not by itself prevent account usage. LiteLLM likewise keeps provider credentials outside the dev container, but its shared proxy master key still grants account access.
  • Host integration widens the boundary. /dev/kvm, other devices, writable mounts, display sockets and forwarded host services each expose something outside the private runtime. Attach only what the repo needs.
  • Agent compatibility needs validation. The maintainers use Claude Code daily; other agent presets may need correction. Previous LiteLLM integration checks covered particular models and versions, not every current provider or agent release. Mocked tests do not replace a live compatibility check.
  • A young project and a small team. JailBee is developed at GISGRO for its own use, released publicly at 1.0.0 in August 2026 and available on PyPI. There is no established community yet. Price that in.

If a worktree plus docker compose -p is enough, use it. JailBee earns its cost when the runtime is the hard part and you want the whole runtime fenced, with the host connections chosen deliberately.

Sources and scope

Written by the JailBee maintainers, so read the comparison with that in mind. This is a source/documentation comparison, not a runtime test or performance benchmark. The original external review on 2026-10-02 covered BranchBox 0.13.4, nono 0.79.0, Docker Sandboxes sbx 0.46.0, and the Dev Containers specification and VS Code documentation.

On 2026-10-14, JailBee claims were checked against the current code and tests, and the following external sources were re-read for the corrections here:

On 2026-10-26, the MXC note was written from its documentation at commit 05a430b (after the v1.0.1 release): the README, containment policy 1.0.0, container lifecycle, and the Bubblewrap, LXC and Nanvix backend guides. No MXC build was run.

The smaller projects above were not re-audited in the same depth. All these tools move quickly; absence of documented support is not proof that a feature cannot be built. Corrections are welcome — please open an issue.