Skip to content
Menu
Do I need it?What an agent can reach on your machineHow it worksThe layers between the agent and your systemCompareBuilt-in sandboxes, Docker and VMsConfigureOpen only what a task needsSecurityThe threat model and its limitsInstall
Security

A useful layer, with known edges

ai-jail keeps an AI coding agent away from your keys, your home directory and the rest of your machine. It is a process sandbox, so it shares your kernel. It does not replace a disposable virtual machine when the code is hostile.

What it is built to stop

An agent can be talked into bad behavior by a web page, a package or a file in the repository. These are the things it then reaches for, and does not find.

The agent and the project sit inside a wall of bars. Six arrows leave the agent and bounce off the wall. Outside, dim and barred, are your home and keys, your shell secrets, the network, your screen and clipboard, your terminal and the jail policy.
The defaults. Every item on the outside stays there until you open it yourself.

Out of reach

  • Your home directory and the credentials in it. The agent gets a fresh, empty home, so ~/.ssh and ~/.aws do not exist in there.
  • Secrets in your shell. Environment variables are cut down to a small allowlist, so exported tokens stay outside.
  • The network. It is off, so nothing the agent reads can be sent anywhere.
  • Host shared memory, your display server and your clipboard. Agent output passes through a filter that drops terminal clipboard and query sequences.
  • Typing into your terminal. Linux blocks the TIOCSTI call that fakes keystrokes, and macOS limits terminal control to the one terminal ai-jail created for the run.
  • Its own rules. A .ai-jail file inside a repository is untrusted: it can tighten the sandbox and never open it.
How each layer does this

Where the wall ends

The jail and your system stand on the same kernel. A bug in that kernel, in a driver or in the sandbox backend is a way around the wall, and ai-jail cannot do anything about it. A virtual machine brings its own kernel, which is why it is the stronger boundary.

On the left, your system and the ai-jail cage holding the agent stand on one shared slab, your kernel, and a dashed line runs from the agent through the slab to your system. On the right, a disposable VM encloses an agent standing on its own separate kernel.
A sandbox shares the ground with what it protects, and a VM brings its own.

What stays at risk

  • Kernel and driver vulnerabilities. Every sandboxed process talks to the same kernel as the rest of your machine.
  • Bugs in your terminal emulator, above all with --terminal-passthrough, which turns the output filter off.
  • Defects in the sandbox backend itself: bubblewrap, Landlock and seccomp on Linux, sandbox-exec on macOS.
  • Secrets inside the project. A .env file in the repository is readable unless you mask it. See how to mask files.
  • Masks cover only paths that exist when the sandbox starts. A secret file created later, during the session, is not hidden.
  • Side channels and some classes of inter-process communication.
  • On macOS, sandbox-exec is deprecated by Apple and is not equivalent to the Linux isolation. See the macOS differences.

Switches that open the wall

Everything below is off until you turn it on, and each one gives the agent real access. How to set them is on the Configure page.

SwitchWhat anything in the sandbox can then do
--networkSend anywhere everything it can read. Traffic is unrestricted and there is no per-domain filter.
--dockerAct as root on your machine through the Docker daemon.
--x11Log keystrokes and take screenshots of other X11 windows.
--systemd-userAsk your systemd user manager to run services on the host.
--inherit-envRead your whole shell environment, secrets included.
--agent-stateUse the agent's saved login, for example Claude's ~/.claude.
--audioRecord and play audio while it is on.
--no-private-homeSee your real home directory. This is a broad exception; prefer a map of the one path you need.

When in doubt, it refuses to start

A sandbox that silently starts weaker than you asked is worse than one that stops with an error. In these cases ai-jail stops.

  • A config file that exists and is invalid or unreadable.
  • A project .ai-jail that is a symlink. A symlinked global ~/.ai-jail is followed only to a regular file you own, that no one else can write, outside the project.
  • --lockdown when Landlock, the kernel's own filesystem rules, is missing, partial or fails to apply. --lockdown --no-landlock is rejected too.
  • --allow-tcp-port. That interface cannot constrain UDP, so the flag is accepted for compatibility and the launch fails.
  • A BWRAP_BIN that points at a bubblewrap binary someone other than root could have replaced. It is ignored with a warning, and with no trusted bubblewrap the launch fails.

How the project is checked

One maintainer runs the project in the open. Below is what gets checked and what does not.

19
sandbox-escape integration tests that try to write to /usr, read ~/.ssh, call ptrace and bpf, and expect to fail
720
unit tests in the source tree at version 1.22.0
0
network requests at launch. The update check is opt-in with --update-check

How a release is made

  • Release tags are signed, and CI verifies each one against a key fingerprint pinned in the repository.
  • Every GitHub Action is pinned to a commit SHA, and actions are restricted to an allowlist.
  • Builds use a pinned Rust toolchain and --locked dependencies.
  • macOS binaries are signed and notarized by Apple.
  • Each archive ships with a SHA-256 checksum, and the publish job checks them again.

What the release document says is still missing

  • Signing and publishing secrets are still stored at repository level and should move into the release environments.
  • No ruleset yet forces every v* tag to be signed.
  • Immutable releases are not enabled.
  • crates.io publishing still uses a token. Trusted publishing is planned.
  • With a single maintainer there is no second reviewer on changes or releases.

Read RELEASE_SECURITY.md

Report a vulnerability

Do not open a public issue. Use GitHub's private vulnerability reporting, include the steps to reproduce and the affected versions, and allow time to coordinate a fix.

Common questions

Can the agent break out?
The defaults are built and tested to block the ordinary routes: files, environment, network and host IPC. A kernel, driver, terminal or sandbox-backend bug could still let it out. Every process sandbox has that limit, which is why hostile code belongs in a disposable VM.
Is it safe to run with the network on?
It is safer than running the agent bare, because your keys and home directory are still not there to send. Anything the agent can read, it can send, and ai-jail has no per-domain filtering. Mask the secrets inside the project first. See how to mask them.
Has it been audited?
Internally, before 1.0, with the reports published in the repository. It has had no third-party audit. The code is open under GPL 3.0, and private vulnerability reports are welcome.

Put your agent behind bars

ai-jail is a single binary that needs no daemon and no root. You add one word in front of the command you already run.

terminal
brew tap akitaonrails/tap && brew install ai-jailai-jail claude