Download ai-jail 2.9.0
Released October 14, 2026. One archive for Linux and one for macOS, each with a SHA-256 checksum next to it. Free software under GPL-3.0-only.
For the person at the keyboard.
Binaries
The install is one step: unpack the archive and put ai-jail somewhere on your PATH.
Linux x86_64
Needs bubblewrap, the small program ai-jail uses to build the sandbox. Most distributions package it as bubblewrap.
ai-jail-linux-x86_64.tar.gz · 1.6 MB
Check the checksum
Put the archive and its .sha256 file in the same folder and run the line for your system. It prints OK when the archive matches.
# Linuxsha256sum -c ai-jail-linux-x86_64.tar.gz.sha256# macOSshasum -a 256 -c ai-jail-macos-aarch64.tar.gz.sha256Release tags are signed as well. Security lists how a release is made and what is still missing.
Package managers
Each of these installs the same program through a tool you already use, and updates come from it.
Homebrew
macOS and Linux.
brew tap akitaonrails/tap && brew install ai-jailArch Linux
ai-jail-bin is the prebuilt binary. ai-jail builds from source.
yay -S ai-jail-bincrates.io
Builds with Rust 1.97.1 and the dependency versions the release was tested with.
cargo install --locked ai-jailNix
The flake points ai-jail at its own copy of bubblewrap.
nix profile install github:akitaonrails/ai-jailRelease notes
The last 6 releases, as the project publishes them.
Release notes are the project's own text and stay in English.
v2.9.0October 14, 2026
A feature release: one narrow way to reach a host loopback service without
--network, Devin launching pre-authenticated with its installation
protected, Codex starting under macOS Seatbelt again, and two correctness
fixes.
Backward compatible: every pre-2.9.0 .ai-jail keeps working.
Added
--forward-port PORTrelays one host loopback port into the sandbox (#164, closes #158). Without--networkthe sandbox has its own loopback, so a local MCP server, an editor's IDE socket, or a dev database on the host's127.0.0.1was unreachable, and--network— the whole host network back on — was the only way out.--forward-port(repeatable;forward_portsin the global config) relays exactly that port through a per-launch Unix socket onto the sandbox's own loopback: the private network namespace stays up and every other host port stays unreachable. It composes with filtered egress and--lockdown, is refused with--network, for ports below 1024, and outside Linux; the agent starts only once every forward bridge is listening, and a bridge that cannot bind fails the launch. At most 256 relays run per forward. A forwarded port is trusted in full — no allowlist, inspection, or audit record — and only the CLI and global config can open one: a project.ai-jailcannot, and auto-save and--initnever write one. The host side dials127.0.0.1first and falls back to[::1]for IPv6-only services. Thanks @lucascouts.Devin launches pre-authenticated with its managed installation protected (#163).
ai-jail devinnow shares the existingdevinstate roots under$XDG_DATA_HOMEand$XDG_CONFIG_HOME(defaults~/.local/shareand~/.config) read-write — login, settings, and session history — while the self-managed CLI installation underdevin/clistays pinned:cliis a mountpoint so it cannot be renamed, andcli/_versionsis read-only on both backends, with the mutablecurrentselector write-denied by node on macOS. A present-but-invalid installation falls back conservatively (read-only data); an absentcli(an external install) shares state without installation rules. XDG overrides are resolved physically — symlinked bases and..never collapse lexically — and Devin's API hostserver.codeium.comjoins the default filtered-egress table, unioned with explicit--allow-hostas for the other agents. Thanks @lhzapata.chatgpt.comjoins Codex's default filtered egress (#168). Workspace- backed Codex needs it alongsideapi.openai.comfor ChatGPT OAuth routing; API-key traffic alone needed only the API host.
Fixed
Codex starts again under macOS Seatbelt (#168). Codex 0.162.1 calls the setuid
/bin/psto validate its managed app-server, which Seatbelt refuses to exec. Non-lockdown Codex launches now get a private, unprivilegedpsshim (this binary, symlinked into the session temp dir) that answers only that one PID/start-time query, reading no command lines or other host process data. The shim also reaches the canonical executable through symlinked launch paths, and Codex's app-server gets the macOS services it needs (CFPreferences shared memory, cfprefsd/trustd lookups) scoped to Codex with--no-agent-stateopting out. Thanks @andrelramos.--x11alone passes X11 through, as documented (#167). All X11 handling lived behind--display, so--x11without it gave the sandbox noDISPLAYand no/tmp/.X11-unix— silently, not even under--verbose— although every doc describes X11 as its own opt-in. Each flag now gates its own protocol;--lockdownstill turns both off. Thanks @diogochaves.Auto-save no longer writes opt-ins an untrusted project file would refuse (#166). One
ai-jail --pictures --no-network truewas enough to getproject .ai-jail pictures ignored because it weakens the baseline sandboxon every later run: auto-save wrote CLI capability opt-ins into the project file that the untrusted merge then rejects. Auto-save now writes exactly what the project layer's own load accepts (tightening values kept; trusted projects unchanged), so a saved file never warns on reload, and files polluted by earlier versions clean themselves up. Thanks @diogochaves.
Documentation
- Host-side git and masks noted as residual risks (#165). The writable
project includes
.git/, which host-side git trusts: a program named in.git/config(for examplecore.fsmonitor) or dropped into.git/hooks/runs outside the sandbox on the next matching host git operation. The note says what closes it today (--lockdown,--map .git) and that--mask/--deny-pathchange only what the sandbox sees — host-side helpers acting for the agent still read the real files.
Checksums (SHA256)
9a6120a67c0e8d14dd57b06c4b003c28b0e565dd1c8632bf998b3c7f878872a9 ai-jail-linux-x86_64.tar.gz
62b3ece819a899760ef41fa04ab026729703cc388fde486e54b177a7eb253f37 ai-jail-macos-aarch64.tar.gz
Install
brew tap akitaonrails/tap && brew install ai-jail
yay -S ai-jail-bin
cargo install --locked ai-jail
v2.8.1October 9, 2026
A follow-up to the v2.8.0 agent-API-egress default: an explicit --allow-host
list no longer cuts off the agent's own API.
Backward compatible: every pre-2.8.1 .ai-jail keeps working.
Fixed
The default agent API host is unioned with
--allow-host, not suppressed by it (#156). In v2.8.0 the automatic API-host default only applied when--allow-hostwas empty, soai-jail --allow-host github.com claudereachedgithub.combut silently droppedapi.anthropic.comand left Claude unable to talk to its API — surprising, and inconsistent with the toolchain-registry default, which already unions onto an explicit--allow-hostlist. The agent default now behaves the same: adding a host extends what the agent can reach instead of cutting off its own API, soai-jail --allow-host github.com claudereachesgithub.comandapi.anthropic.com. Neither automatic default (agent API host or registry hosts) is gated on--allow-hostbeing empty any more — only on the asserted network posture.The verbatim "only this list, nothing automatic" mode is unchanged and explicit:
ai-jail --no-network --allow-host github.com claudecomposes to filtered egress withgithub.comonly.--no-networksets the posture, which disables both automatic defaults, while a non-empty allow-list keeps egress filtered rather than fully offline.--networkand--lockdownkeep their existing behavior; the sandbox stays deny-by-default throughout.
Checksums (SHA256)
9c5e41b59be8fd65f239252f8d2e03f16a806d76c090bd256948b452b350710b ai-jail-linux-x86_64.tar.gz
ff1f076b2ed8cedffaa78d02c3c5014ed9e3424f70a5f06145475424ce79cedb ai-jail-macos-aarch64.tar.gz
Install
brew tap akitaonrails/tap && brew install ai-jail
yay -S ai-jail-bin
cargo install --locked ai-jail
v2.8.0October 9, 2026
A bare ai-jail claude (or codex/gemini/grok) now reaches its model API
out of the box, and Kiro CLI joins the recognized agents. macOS Codex and
Claude logins are fixed, and the PTY no longer stalls launchers that probe the
cursor position.
Backward compatible: every pre-2.8.0 .ai-jail keeps working.
Added
- Each known agent's own API host is default-allowed (#156). With no
network posture and no explicit
--allow-hostlist, a bare launch of a known API agent now receives filtered egress to that agent's own documented API host —claude→api.anthropic.com,codex→api.openai.com,gemini→generativelanguage.googleapis.com,grok→api.x.ai— so it reaches its model API without opening the whole network. Deny-by-default still holds: only the agent's single functional API host is added (never a telemetry host), and an explicit--allow-hostset is used verbatim instead. Not Linux-only — macOS filtered egress is a seatbelt loopback rule, so it applies there too — and gated on the same unprivileged-netns probe as registry egress, staying fully offline when that is unavailable.--no-network,--network, a browser launch, and--lockdownall keep their existing semantics. Reshaped from a Claude-only proposal; thanks @andrelramos. - Kiro CLI is recognized for agent-state (#155). Its login/session state
(
~/.kiroplus~/.local/share/kiro-clion Linux,~/Library/Application Support/kiro-clion macOS) is mounted under private home on both backends, andkiro-cliis listed among the positional presets. Thanks @JuanMCanchala.
Fixed
- macOS: Claude Code Keychain login and the Codex control socket (#154). The seatbelt profile now preserves Claude Code's Keychain-stored auth and allows the Codex app-server control socket, so both launch logged-in on macOS. Thanks @andrelramos.
- Cursor-position requests are answered from the vt100 screen (#159). A launcher that emits a Device Status Report (cursor-position query) no longer stalls waiting for a reply: ai-jail answers it from the virtual terminal's own cursor when the child is on the primary screen. Thanks @enosteteo.
Internal
- Hardened the filtered-egress proxy against descriptor exhaustion and fixed a lock race in its tests (#157, thanks @lucascouts). Widened a flaky gh-token-lookup test timeout.
- Assessed Microsoft LiteBox for a future Windows port (not a fit; a Windows backend would use WSL2 or a native AppContainer/Job Objects sandbox).
Checksums (SHA256)
4965827929a1366f75747e87116cee6a5eb3fc13d310d180f3c923dca7df6a6c ai-jail-linux-x86_64.tar.gz
52fd5f693b049c1b1956a2030c4768d9ca6bcbe12df6547434df941c7ab9090b ai-jail-macos-aarch64.tar.gz
Install
brew tap akitaonrails/tap && brew install ai-jail
yay -S ai-jail-bin
cargo install --locked ai-jail
v2.7.0October 7, 2026
Two contributed fixes land this release: --github now works when your gh
token lives in the system keyring, and the private-home command exemption no
longer breaks symlink-following launchers.
Backward compatible: every pre-2.7.0 .ai-jail keeps working.
Added
--githubforwards a keyring-stored gh token (#153).--githubalready mounts~/.config/ghread-only, butgh auth loginstores the token in the system keyring by default, so a jailedghfound the account but no credential. With--github, ai-jail now runsgh auth token --hostname github.comon the host (no shell, 5s timeout, validated output) and forwards the result asGH_TOKENfor that launch only. The value rides the #147--argsmemfd, so it never touches argv, disk, or a saved.ai-jail;--dry-runnever fetches it; an explicit/hostGH_TOKEN/GITHUB_TOKENshort-circuits the lookup; and the capability stays opt-in, monotonic (a project.ai-jailcannot enable or steer it), and disabled under--lockdown. No keyring or D-Bus access from inside the jail. Thanks @miguins.prime-agentis recognized for agent-state (#152). Its auth/session state under~/.prime/agentis mounted (bwrap + seatbelt), never the whole~/.prime— the siblingconfig.jsonholding the prime CLI's API key stays hidden.
Fixed
- Private-home command exemption preserves symlink chains (#152). The
exemption bound the launcher's path with
--ro-bind, which flattened symlink hops, so a symlink-following launcher (e.g. bun's app-root heuristic, which looks forpackage.jsonin the dirname of the resolved executable) crashed with ENOENT. Each symlink hop is now recreated inside the sandbox with--symlinkusing the verbatim host target text; only the terminal real path is bind-mounted read-only. Relative hops are lexically normalized so no collected mount path carries... The #138 dedup (skip paths under an already-bound dir) is preserved. Thanks @jadsongmatos.
Checksums (SHA256)
b8b5ef75027d0d6bd9d2d2f2cfc20e83a4f0916e7237604fea3b81f85eaee067 ai-jail-linux-x86_64.tar.gz
3c6a4cc41212f337ba72e1895b11dd10ae620b5bb86d384919a7e29aeb8ff0ba ai-jail-macos-aarch64.tar.gz
Install
brew tap akitaonrails/tap && brew install ai-jail
yay -S ai-jail-bin
cargo install --locked ai-jail
v2.6.4October 4, 2026
A reliability fix for filtered egress. Transient listener failures no longer disable proxy access for the remainder of a sandbox session.
Backward compatible: every pre-2.6.4 .ai-jail keeps working.
Fixed
- Filtered egress recovers after a transient
accept()failure (#151). The supervisor's TCP and Unix proxy listeners and the in-sandbox bridge used iterator loops that ended permanently on the first failed accept. Descriptor exhaustion or an aborted client could therefore leave every later connection refused until the sandbox exited. All three listeners now retry after a bounded delay, avoiding a busy loop while preserving the session. Internal bridge retries also inherit--execquiet mode.
Documentation
- Corrected two references in the v2.6.1 notes that were internal ai-memory inbox identifiers rather than GitHub issue numbers.
Checksums (SHA256)
7749b73435686b783567bf0427f7cdf4faf7783ac31b1d590d0454048b243d4b ai-jail-linux-x86_64.tar.gz
2563884af5c29e761612e38f50c970e51d0a94e64ed59c167a327b886bffc169 ai-jail-macos-aarch64.tar.gz
Install
brew tap akitaonrails/tap && brew install ai-jail
yay -S ai-jail-bin
cargo install --locked ai-jail
v2.6.3October 3, 2026
A maintenance release. The sandbox binary is unchanged from v2.6.2; this release only fixes building ai-jail from source under Nix on recent kernels.
Backward compatible: every pre-2.6.3 .ai-jail keeps working.
Fixed
nix buildno longer fails itscheckPhaseon kernels with Landlock ABI ≥ 6 (Linux ≥ 6.12). Nix's builder hardening wraps Linux builds in an outer, scope-only Landlock layer; under stacked-layer semantics, as soon as ai-jail's own filesystem ruleset makes the domain filesystem-applicable, the outer layer (which grants noREFER) denies every cross-directory rename withEXDEV, so thelandlock_allows_cross_dir_rename_*integration tests failed andlandlock_denies_rename_out_of_readonly_mappassed vacuously. The REFER tests now run a probe outside the jail and skip themselves when an outer Landlock domain denies reparenting to a nested ruleset, since ai-jail's innerREFERgrants are unmeasurable there. On an ordinary host (no outer Landlock) the tests still run and pass as before. Thanks to @pqitr (#150).
Checksums (SHA256)
31c44e8f4da78bc4bad7b4d0ba4e0c2578eec8035594e13744764c6b108eef95 ai-jail-linux-x86_64.tar.gz
dc466ba94f99ab179f525e0d5749dbed7d81c7832c677d090fb5745a78365848 ai-jail-macos-aarch64.tar.gz
Install
brew tap akitaonrails/tap && brew install ai-jail
yay -S ai-jail-bin
cargo install --locked ai-jail
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.
brew tap akitaonrails/tap && brew install ai-jailai-jail claude