github akitaonrails/ai-jail v2.13.0

3 hours ago

v2.13.0

Added

  • --publish-port PORT — the reverse of --forward-port, on Linux. A web
    UI or dev server started inside the jail listens on the sandbox's own
    loopback, which the host cannot reach, and --network would turn off the
    whole network fence just to open one port. --publish-port 4096
    (repeatable, or publish_ports = [...] in the global config) has the
    supervisor listen on the host's 127.0.0.1:4096 (never 0.0.0.0) and
    relay each connection, over a per-launch Unix socket and a non-dumpable
    in-sandbox bridge, to the sandbox's own 127.0.0.1:4096 (falling back to
    [::1]). The private network namespace stays in place: filtered egress,
    --allow-private-host and --audit-log keep applying to everything else.
    Under --lockdown the jailed service may bind the published port and no
    other. Trusted capability, exactly like forwards: CLI or global config
    only (project .ai-jail can only shrink the list), ports below 1024
    refused, cannot combine with --network or a forward of the same port,
    never written by auto-save or --init, refused on macOS. Thanks to
    @ohmer1 (#197, closes #195).

Fixed

  • A file map for a symlinked path no longer fails the launch (#196).
    Since v2.11.0's parent-first mount ordering, a map like
    ~/.local/bin/claude (a versioned-installer symlink) landed after the
    auto-mapped ~/.local/bin and bwrap refused to "mount on symlink
    destination", failing the whole launch — a regression from 2.10.x. A
    same-path map already covered by an ancestor's same-kind bind is now
    recognized as redundant and dropped, restoring the 2.10 behavior while
    keeping the nested-map fix from #183.

  • UTF-8-encoded C1 controls are dropped like their raw 8-bit forms
    (remaining hardening note from GHSA-v2fr-83mr-f9cg). The terminal output
    filter passed c2 80..=c2 9f (U+0080..=U+009F) through as multi-byte
    character data, which a terminal that honours UTF-8 C1 would act on. The
    lead byte is now held back until its continuation decides: C1 pairs are
    dropped, legitimate characters and the banner block glyphs forward
    intact, truncated sequences emit the held lead as lone data.

Security

  • An untrusted project .ai-jail that selects a known harness command now
    triggers a launch-time security warning
    (answer to GHSA-v2fr-83mr-f9cg,
    open question A). A repository-supplied command = ["claude"] still gets
    the harness defaults — state dir mounted read-write, API key forwarded,
    API host allowed — because saved-command resume relies on it, but the
    launch now says so explicitly and names both ways to take the choice back
    (remove command from the project config, or list the directory in the
    global trust_project_config). Documented in docs/SECURITY.md.

Backward compatible: every pre-2.13.0 .ai-jail keeps working. Security
advisories GHSA-v2fr-83mr-f9cg and GHSA-2gq6-9rhj-xrg4 are published with
this release.

Checksums (SHA256)

49f5b40c1ea8be8f31db251dbde94625ca6a8c74ebbe37f3a5895ea0491b0cf2  ai-jail-linux-x86_64.tar.gz
ea463f17c81caf530dcf780df833039c5914f33bf74b2abc6985cb2f8f6a3309  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

Don't miss a new ai-jail release

NewReleases is sending notifications on new releases.