Skip to main content

YOLO Jail

CI License

A secure, isolated container environment for AI coding agents (Claude Code, Copilot, opencode, pi, Codex, Antigravity) to safely modify codebases without compromising host security or identity. Agents are selected with the packs config key — see Agents. Runs on Linux and macOS (Apple Silicon and Intel) with Podman or Apple Container.

Why?

AI coding agents like Claude Code, GitHub Copilot, and OpenAI Codex have a --yolo mode that lets them run shell commands without confirmation. This is powerful but dangerous — agents can access your SSH keys, cloud credentials, git identity, and anything else on your machine.

YOLO Jail lets you run agents in YOLO mode safely by isolating them in a container with:

  • ❌ No access to ~/.ssh/, ~/.gitconfig, or cloud credentials
  • ✅ Separate auth (gh auth login, codex login, etc. inside the jail)
  • ✅ Your codebase mounted read-write at /workspace
  • ✅ Persistent tool state across restarts
  • ✅ Pre-configured MCP servers, LSP servers, and modern CLI tools

Features

  • Isolated: Runs in a podman or Apple Container container with no access to host credentials
  • Optimized: Pre-installed with modern, fast tools (rg, fd, bat, eza, jq, delta, fzf)
  • Restricted: Blocked tools return clear errors with suggestions (e.g., rg instead of grep)
  • Reproducible: Defined entirely via Nix Flakes
  • Agent-Ready: MCP presets (Chrome DevTools, Sequential Thinking) and LSP servers (Pyright, TypeScript) — enable by name
  • Configurable: Per-project config via yolo-jail.jsonc, user defaults via ~/.config/yolo-jail/config.jsonc
  • Container Reuse: Same workspace reuses the same container via exec
  • Runtime Flexible: Works with podman (Linux/macOS) and Apple Container (macOS native)
  • Cross-Platform: Full support for Linux and macOS (Apple Silicon and Intel)

Prerequisites

Core requirements (both platforms):

  • Nix (with flakes enabled)
  • A container runtime — one of:
    • Podman (preferred on Linux; Podman Machine on macOS)
    • Apple Container (native macOS, brew install container)

Additionally, to install from source:

Platform specifics (in priority order):

  • Linux / x86_64 — any modern distribution with Podman. No extra setup. The primary target.
  • macOS / Apple Silicon — via a native arm64 Linux container (Apple Container or Podman Machine); no emulation. See docs/guides/macos.md.
  • Linux / arm64 (aarch64-linux) — supported and CI-tested (image built + integration-tested natively on ubuntu-24.04-arm); same nix image as x86_64, no arch switch.
  • macOS / Intel — also supported (x86_64 Linux container).

No builder is needed on macOS — the standard image builds entirely from the NixOS binary cache. If you add a package that isn't cached, the from-source Linux build is offloaded automatically to a tiny throwaway container on whichever container runtime is already up (Podman or Apple Container); no VM, no sudo, no setup.

Install

Every channel below ships the same single yolo binary. Pick whichever fits — but read the note under each: a launch needs more than the binary.

Every launch also needs a flake bundle — the copy of yolo's build inputs (flake.nix, its lockfile, the prebuilt in-jail binaries) that yolo builds the jail from. Homebrew and the from-source install put one beside the binary for you; go install and pipx/uvx ship the binary alone, so they need a checkout named by YOLO_REPO_ROOT. yolo never consults your working directory to find it. Full table: docs/guides/USER_GUIDE.md.

Homebrew (easiest, macOS and Linux)

brew tap mschulkind-oss/tap
brew install mschulkind-oss/tap/yolo-jail

Works on macOS and Linuxbrew. Single command, auto-upgrades with brew upgrade. No source checkout, no just required.

Go

go install github.com/mschulkind-oss/yolo-jail/cmd/yolo@latest

Builds straight from the module. Needs Go on the host; puts yolo in $GOBIN (or $(go env GOPATH)/bin).

The module holds no flake bundle, so this channel gets the binary and nothing else: the first yolo refuses with "Cannot find yolo-jail repo root" until you clone the repo and export YOLO_REPO_ROOT=/path/to/checkout. If you are going to have a checkout anyway, from source is the channel that wants one.

pipx / uvx

pipx install yolo-jail
# or, to run without installing:
uvx yolo-jail

The PyPI distribution is per-platform wheels wrapping the same prebuilt Go binary — there is no Python code and no Python runtime dependency beyond the installer itself. It exists so the pre-Go audience keeps a working upgrade path.

A wheel carries the binary alone, so like go install this channel needs YOLO_REPO_ROOT pointed at a checkout before the first launch will do anything.

From source

For hacking on yolo-jail itself, or running an unreleased working tree. Identical on Linux and macOS:

git clone https://github.com/mschulkind-oss/yolo-jail.git
cd yolo-jail
just setup             # pinned toolchain (mise) + Go module deps
just deploy            # builds + installs the yolo CLI

To upgrade later: cd yolo-jail && git pull && just deploy

Upgrading from the Python version

yolo-jail used to ship as a Python package installed with uv tool install. just deploy retires that install for you — it uninstalls the yolo-jail uv tool and clears the console scripts it left in $GOBIN (yolo, yolo-ps, yolo-host-processes, yolo-claude-oauth-broker-host), which otherwise make go install fail with build output "…/yolo" already exists and is not an object file.

Nothing is deleted that cannot be positively identified as part of that old install. If something unrecognized is sitting at $GOBIN/yolo, the migration stops and asks you to look at it rather than guessing. uv itself is no longer a prerequisite.

Optional — User-level defaults

yolo init-user-config
# Edit: ~/.config/yolo-jail/config.jsonc

Platform-specific runtime setup (one-time, needed whichever channel you installed from):

# Linux — Podman
sudo pacman -S podman                   # or apt/dnf/pacman for your distro

# macOS — Apple Container (native, recommended)
brew install container skopeo
container system start

# macOS — Podman Machine
brew install podman
podman machine init --cpus 4 --memory 8192 --disk-size 50
podman machine start

On macOS, image builds use the NixOS binary cache by default — no builder to set up. If you add packages that aren't in the cache (or build offline), the from-source Linux build is offloaded automatically to a throwaway container on the container runtime you already have running. See docs/guides/macos.md.

For development, see CONTRIBUTING.md.

Quick Start

Works identically on Linux and macOS:

# Navigate to any repository
cd ~/code/my-project

# Start an interactive shell in the jail
yolo

# Or run a command directly (agent installation is being reworked; see the Agents section)
yolo -- claude           # Claude Code in YOLO mode
yolo -- copilot          # Copilot with --yolo auto-injected
yolo -- opencode         # opencode.ai agent (auto-approve)
yolo -- pi               # pi.dev coding agent (auto-approve)
yolo -- codex            # OpenAI Codex CLI (auto-approve, sandbox off)

# Force a new container
yolo --new -- bash

# ALWAYS run this after every yolo-jail.jsonc edit, before restarting
yolo check

# Check your setup
yolo doctor

# List running jails
yolo ps

# Show full configuration reference
yolo config-ref

On macOS, yolo doctor additionally checks the VM backend (Podman Machine or Apple Container system status) — confirming the runtime is up, so that an uncached build can offload to a throwaway container on it.

First Run

On first run, YOLO Jail will:

  1. Build the Linux container image via nix build (takes a few minutes — both Linux and macOS download from the NixOS binary cache; on macOS, any non-cached package is built by offloading to an ephemeral container on the running runtime — no VM, no sudo, no first-boot)
  2. Load the image into your container runtime
  3. Install MCP servers, LSP servers, and utilities
  4. Start your command

Subsequent runs are fast — tools are cached in persistent storage on both platforms.

Auth Setup (One-Time)

Inside the jail, authenticate with your tools:

gh auth login          # GitHub CLI
# Claude Code authenticates via /login on first run
# codex login / opencode auth login / pi's /login work the same way

Each coding agent authenticates itself inside the jail — see the per-agent auth column in Agents. Agents that take a provider API key (opencode, pi, codex) can instead read it from env_sources.

These tokens are stored in ~/.local/share/yolo-jail/home/ (same path on Linux and macOS) and persist across jail restarts. On both platforms, a host-side systemd timer (installed by just deploy) periodically refreshes the shared Claude OAuth token so jails never race the refresh flow.

Configuration

Create a per-project config in yolo-jail.jsonc:

{
  "runtime": "podman",              // or "container" (Apple Container)
  "packages": ["strace", "htop"],   // extra nix packages
  "mounts": ["/path/to/ref-repo"],  // extra read-only mounts
  "network": {
    "mode": "bridge",               // or "host" for host networking
    "ports": ["8000:8000"]          // publish ports in bridge mode
  },
  "security": {
    "blocked_tools": ["curl", "wget"]
  }
  // "cache_relocations" exists too, but NOT here — user scope only, see below
}

Workspace config merges over user defaults (~/.config/yolo-jail/config.jsonc), and a sibling yolo-jail.local.jsonc — meant to be gitignored for per-machine overrides — auto-merges over the workspace config. Lists merge and dedupe, scalars override.

Two keys opt out of that merge, and both for the same reason: a workspace config lives inside the jail's writable mount, so an agent could otherwise grant itself something. packs and cache_relocations are read straight from ~/.config/yolo-jail/config.jsonc and nowhere else; yolo check errors if either appears in yolo-jail.jsonc.

// ~/.config/yolo-jail/config.jsonc — never yolo-jail.jsonc
{
  // Everything a jail has beyond a bare shell. A bare NAME selects a pack that
  // ships with yolo; an address brings one from elsewhere. Nothing is on by
  // default, so with no entries here a jail has no coding agent.
  "packs": [
    "claude",                                    // a shipped agent pack
    "file:///home/me/code/my-skills-pack",       // a local pack of your own
    "git+ssh://git@github.com/org/repo//packs/team?ref=main"
  ]
}

A pack delivers a coding agent (its CLI, config files, skills and briefing), or your own shared skills and house rules, or both. An EMBEDDED pack — one shipped with yolo — may read a host file, which is how claude and pi compose your own settings.json into the jail. A FETCHED pack never can: installing a third-party pack approves distributing content, not handing that repository your host config. Run yolo pack --help for authoring and yolo pack install to fetch.

On cache_relocations specifically: it moves a subdir of the jail cache onto other storage, bind-mounted read-write — which is the read-write host mount an agent must not be able to grant itself. Podman only.

// ~/.config/yolo-jail/config.jsonc — never yolo-jail.jsonc
{
  "cache_relocations": {
    // cache subdir name → absolute host path (the parent must already exist)
    "huggingface": "/data/relocated/yolo-jail/cache/huggingface"
  }
}

Moving an existing cache needs a stop-copy-configure-restart dance — see Storage & Persistence in the user guide.

Run yolo check after every edit to yolo-jail.jsonc to validate the merged config, dry-run the generated jail agent configs, and preflight the image build before restarting into the jail. Inside a running jail, yolo check --no-build is the fast way to validate config changes mid-session before asking for a restart.

Run yolo config-ref for the full configuration reference.

Agents

YOLO Jail is a library of coding agents. Which ones a jail gets follows from the packs you configure, and nothing in the core knows what an agent is — the six below are pack files (packs/*/pack.json), not Go code.

  • No rebuild: agents install lazily on first use, so changing packs never rebuilds the image — just restart the jail.

Each agent is launched with its autonomous/YOLO mode auto-enabled (the jail container is the security boundary), and authenticates itself inside the jail — host credentials never cross the boundary.

Agent pack name Run Install Auth (inside the jail)
Claude Code claude yolo -- claude native installer /login on first run
GitHub Copilot copilot yolo -- copilot npm @github/copilot /login (GitHub OAuth)
opencode opencode yolo -- opencode npm opencode-ai opencode auth login, or a provider key (e.g. ANTHROPIC_API_KEY/OPENAI_API_KEY)
pi (pi.dev) pi yolo -- pi npm @earendil-works/pi-coding-agent pi /login, or a provider key
OpenAI Codex codex yolo -- codex native installer codex login (ChatGPT), or OPENAI_API_KEY
Antigravity agy yolo -- agy native installer Google sign-in on first run

Provider API keys are easiest to supply via env_sources (a gitignored dotenv file) so they reach the agent inside the jail without living in your committed config. MCP servers you configure (mcp_presets / mcp_servers) are wired into every selected agent that supports MCP — claude, copilot, opencode, codex, and agy (pi has no native MCP).

Isolation backends

The runtime config picks how the agent is isolated:

  • podman (Linux, default) / container (macOS, Apple Container) — the agent runs in a Linux container. Strongest boundary (kernel/VM isolation, resource caps). On macOS this means a lightweight Linux VM — native arm64 on Apple Silicon (no emulation); see docs/guides/macos.md.

Security

  • Strict Isolation: No access to host ~/.ssh/, ~/.gitconfig, or cloud credentials
  • Separate Auth: Run gh auth login, codex login, etc. inside the jail once
  • User Mapping: Files created in the jail are owned by your host user (matching UID/GID)
  • Blocked Tools: Configurable list of tools that return clear error messages
  • Config Safety: Changes to yolo-jail.jsonc require human confirmation at next startup — agents cannot silently modify the jail environment. See docs/reference/config-safety.md.
  • Read-Only Mounts: Extra mounts are read-only by default

Troubleshooting

Run yolo doctor to diagnose common setup issues:

yolo doctor

This checks your container runtime, Nix installation, configuration files, image status, and running containers.

Run yolo check after every config edit, especially when handing work from an outside agent into the jail or when an in-jail agent edits yolo-jail.jsonc mid-session and needs to verify the restart will succeed.

Contributing

See CONTRIBUTING.md for development setup and guidelines.

Documentation

License

Apache License 2.0

Metadata

Release files for yolo-jail 0.10.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for yolo-jail 0.10.0
File
yolo_jail-0.10.0-py3-none-musllinux_1_2_x86_64.whl Python 3 none Linux musl 1.2+ x86-64 Details
yolo_jail-0.10.0-py3-none-musllinux_1_2_aarch64.whl Python 3 none Linux musl 1.2+ ARM64 Details
yolo_jail-0.10.0-py3-none-manylinux_2_17_x86_64.whl Python 3 none Linux glibc 2.17+ x86-64 Details
yolo_jail-0.10.0-py3-none-manylinux_2_17_aarch64.whl Python 3 none Linux glibc 2.17+ ARM64 Details
yolo_jail-0.10.0-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details
yolo_jail-0.10.0-py3-none-macosx_10_9_x86_64.whl Python 3 none macOS 10.9+ x86-64 Details

Total release size: 83.7 MB

Release files / yolo_jail-0.10.0-py3-none-musllinux_1_2_x86_64.whl

Download URL yolo_jail-0.10.0-py3-none-musllinux_1_2_x86_64.whl
Size 14.5 MB
Tags Linux musl 1.2+ x86-64 Python 3
SHA-256 checksum
How to use checksums
c2a455cb352bd214de317445b90be270f2e6a8a57db4001c29f503b7947ad006
BLAKE2b-256 checksum
How to use checksums
b15e412d6c603fec9cfbb1f29df884c07dd0beeace1c0df8b0e9d5ab31dee9a6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / yolo_jail-0.10.0-py3-none-musllinux_1_2_aarch64.whl

Download URL yolo_jail-0.10.0-py3-none-musllinux_1_2_aarch64.whl
Size 13.3 MB
Tags Linux musl 1.2+ ARM64 Python 3
SHA-256 checksum
How to use checksums
20eb267dfce391742a310969c249fb6f500db82ecf930d4f82de82d4435d818b
BLAKE2b-256 checksum
How to use checksums
b1fa6fe9930cde0a0cf7ec4e53d2611e7fe36472e02ed4214c83815c890fd39a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / yolo_jail-0.10.0-py3-none-manylinux_2_17_x86_64.whl

Download URL yolo_jail-0.10.0-py3-none-manylinux_2_17_x86_64.whl
Size 14.5 MB
Tags Linux glibc 2.17+ x86-64 Python 3
SHA-256 checksum
How to use checksums
d35e42b7c974976b8b5f7e832da5f98b8e9996b5a2bf7d8720bed85998e8275d
BLAKE2b-256 checksum
How to use checksums
55618a06c346e193a7138a3b2d418f377d8f996007ebc845759eff9a6fe3689c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / yolo_jail-0.10.0-py3-none-manylinux_2_17_aarch64.whl

Download URL yolo_jail-0.10.0-py3-none-manylinux_2_17_aarch64.whl
Size 13.3 MB
Tags Linux glibc 2.17+ ARM64 Python 3
SHA-256 checksum
How to use checksums
a8e59cce9826b0e4d37dcccc2dd4661638daf7f9b31f74647646fcf2d079262e
BLAKE2b-256 checksum
How to use checksums
741c9c69337d879eda958b13ed9f7a54fd3d1bcb130a3219e8ea5d3dbdb190bd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / yolo_jail-0.10.0-py3-none-macosx_11_0_arm64.whl

Download URL yolo_jail-0.10.0-py3-none-macosx_11_0_arm64.whl
Size 13.4 MB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
a20de9956426e71f5aca775abde4c7774950cfe037d22285c9edfbb67ec0e325
BLAKE2b-256 checksum
How to use checksums
b90e75136db477ace0b8d65f6a2112d1bc836e6c0549ebe62647609acc11f3bf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / yolo_jail-0.10.0-py3-none-macosx_10_9_x86_64.whl

Download URL yolo_jail-0.10.0-py3-none-macosx_10_9_x86_64.whl
Size 14.7 MB
Tags Python 3 macOS 10.9+ x86-64
SHA-256 checksum
How to use checksums
1924297872a261c361a581deabd1f2d3d78bec1b1d4f18902c9c315426612944
BLAKE2b-256 checksum
How to use checksums
7bf8fa9fde3c6fe4612547ae6f454c156196e4adbeba8aab6b2c3481fab7a2b1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

0.11.0

6 release files

This release

0.10.0 This release

6 release files

0.9.0

6 release files

0.8.0

6 release files

0.7.1

6 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.3

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page