本文へスキップ
メニュー
自分に必要?エージェントが手元のマシンで触れられるもの仕組みエージェントとシステムの間にある層比較組み込みサンドボックス、Docker、VM設定タスクに必要なものだけを開けるセキュリティ脅威モデルとその限界ダウンロードバイナリ、チェックサム、リリースノートインストール
インストール

インストールして、中を見て、エージェントを動かす

ai-jailは1つのプログラムで、デーモンもrootも要りません。インストールして、いつも打っているコマンドの前にその名前を置けば、エージェントはサンドボックスの中で起動します。

キーボードの前にいる人へ。

インストール

コマンドラインツールを普段入れている方法を選んでください。どの方法でも、同じ単一のai-jailプログラムが入ります。

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

macOSとLinuxで使えます。

システムに必要なもの

Linux

bubblewrapをインストールしてください。ai-jailがサンドボックスの構築に使う小さなプログラムです。ほとんどのディストリビューションではbubblewrapという名前でパッケージになっています。

terminal
pacman -S bubblewrapapt install bubblewrapdnf install bubblewrap

macOS

インストールするものはありません。ai-jailはmacOSに付属のsandbox-execを使います。Appleはこのインターフェースを非推奨としています。macOSではパッケージレジストリにデフォルトでは届きません。--allow-hostで1つ足すか、--networkでネットワークを開けてください。

Windows

対応していません。WSL2を使い、その中でLinuxの手順に従ってください。

最初の実行

コマンドは3つ。計画、中の下見、動くエージェント。ログイン情報は最初から中にあり、エージェントのAPIホストへの経路はai-jailが開けてくれます。

↔ 横にスワイプすると図全体を見られます

あなたのホームディレクトリはどの段階でも外に残り、エージェントのログイン情報は最初から中にあります。最後にai-jailはエージェント自身のAPIホストを開きます。Linuxではツールチェーンからパッケージレジストリにも届きます。それ以外は閉じたままです。
  1. 何も実行せずに計画を見る

    プロジェクトに移動して、ドライランを実行します。ai-jailは、使うはずのサンドボックスコマンドを表示して終了します。ドライランがファイルを書き込むことはありません。

    ドライラン
    cd ~/Projects/my-appai-jail --dry-run claude
  2. 中を見て回る

    ジェイルの中で普通のシェルを起動します。プロジェクトは実際のパスにあり、編集もできます。ホームディレクトリは新しい空のもので、シェルのトークンは消えています。出るにはexitと打ちます。

    ジェイルの中のシェル
    ai-jail bash
  3. エージェントを実行する

    ai-jailはエージェント自身の状態フォルダをデフォルトでマウントするので、すでにサインイン済みです。エージェントを知っていれば、フィルタ付きプロキシでエージェント自身のAPIホストも通します。Claude Codeならapi.anthropic.com、Codexならapi.openai.comとchatgpt.com、Geminiならgenerativelanguage.googleapis.com、Grokならapi.x.ai、Devinならserver.codeium.comで、LinuxでもmacOSでも同じです。テレメトリのホストは閉じたままです。Linuxでは、ツールチェーンがcrates.io、npm、PyPIなどのパッケージレジストリにデフォルトで届くので、ビルドが動きます。代わりに--networkはネットワーク全体を開けます。

    本番の実行
    ai-jail claude# または、ネットワーク全体を開けるなら:ai-jail --network claude
  4. もっと必要なとき

    あなた自身の設定ファイル~/.ai-jailに、エージェント名の下にホストのリストを書きます。リストはエージェント自身のAPIホストに足され、APIホストは許可されたままです。Linuxではgithub.comとパッケージレジストリが最初から入っています。あるいは--networkでネットワーク全体を開けます。ログアウト状態で実行するなら--no-agent-stateを渡します。プロジェクト内の.ai-jailファイルはジェイルを厳しくすることしかできません。ホストのリストやforward_portsのリストを縮め、ログインを切ることはできても、その逆はできないので、cloneしたリポジトリが自分でジェイルを開けることはありません。

    ~/.ai-jail
    [commands.claude]allow_hosts = ["api.example.com"]# ai-jailがすでに許可しているAPIホストとレジストリに足される # または、一度だけなら:# ai-jail --network claude

中で見えるもの

プロンプトは(jail)に変わり、プロジェクトはいつもの場所にあります。ツールチェーンも読み取り専用でそこにあります。盗む価値のあるものは見当たりません。例外はエージェント自身のログイン情報で、これは意図してそこにあります。

ai-jail bash、Linuxの場合
$ ai-jail bash# プロジェクトは実際のパスにある(jail) ~/Projects/my-app $ pwd/home/you/Projects/my-app# シェルでexportしたトークンは付いてこない(jail) ~/Projects/my-app $ echo $GITHUB_TOKEN # このホームにあなたの鍵はない(jail) ~/Projects/my-app $ cat ~/.ssh/id_ed25519cat: /home/you/.ssh/id_ed25519: No such file or directory# ジェイルには専用のホスト名がある(jail) ~/Projects/my-app $ hostnameai-sandbox

これはLinuxでのセッションです。macOSには別のファイルツリーを組み立てる手段がないので、同じパスは存在しますが、読み取りが拒否されます。

↔ 横にスワイプすると図全体を見られます

中から見ると、あなたのもので変更できるのはプロジェクトだけです。ツールチェーン(mise、cargo、npmなど)は読み取り専用でそこにあり、依存キャッシュはジェイル専用です。ネットワークは外に残ります。例外は既知のエージェント自身のAPIホストと、Linuxではそのツールチェーンが取得先にするパッケージレジストリだけで、--allow-hostでホストを開けるか、--forward-portでローカルのポート1つを開けるか、--networkで全部開けるまで変わりません。ツールチェーンのマップ方法。

ジェイルが何かを止めたとき

エージェントが起動するものはすべて一緒に中で動くので、止められたものは失敗し、あなたに尋ねるものはありません。それがどう見えるか、どう確かめるかをまとめます。

  • プロジェクト外のファイルは存在しません。Linuxではパスそのものがなく、macOSではパスはあっても読み取りが拒否されます。
  • リスト外のホストには届きません。接続が失敗します。--allow-host HOSTを付けると次の実行から届きます。
  • シェルの変数は、--env NAMEか--env-from-fileで渡さない限り、中では空です。
  • 何が拒否されたかを見るには--audit-logを足します。起動のたびに記録し、プロキシが許可または拒否した接続をすべて残します。ai-jail --audit-showで表示できます。
  • 自分で中を見て回るには、ai-jail bashで同じジェイルの中にシェルを開けます。

初日に開けることになるもの

インストール

Linuxではそのまま動きます。レジストリとgithub.comはデフォルトのリストに入っています。macOSでは--allow-host registry.npmjs.orgのように1つ足すか、--networkですべて開けます。

ローカルのサービス

自分のマシンのループバックにあるデータベース、ローカルのMCPサーバー、エディタのソケット。Linuxでは--forward-port 5432でそのポート1つを中継します。macOSでは--networkです。

Git push

GitHubからのcloneとpullはLinuxでそのまま動きます。pushには認証情報が要ります。HTTPS経由でghのトークンを使うなら--github(macOSでは--allow-host github.comも足します)、SSH鍵なら--network --sshです。

MCPサーバー

エージェントと一緒にジェイルの中で起動します。シェルのトークンを読むものは、--env GITHUB_TOKENか--env-from-fileで渡すまで何も受け取れません。HTTP経由のリモートのものは、そのホストを--allow-hostに入れる必要があります。

起動しないとき

READMEのトラブルシューティングにあるケースと、つまずく人の多いセットアップ上のルール2つを取り上げます。

bwrap: setting up uid map: Permission denied

Ubuntu 24.04以降とDebian 13以降には、プログラムがrootなしでユーザー名前空間を作ることを禁じるAppArmorポリシーが入っています。bubblewrapはまさにその方法でジェイルを隔離しています。この種のrootなしのツールはどれも影響を受けます。システム全体で緩めるには次のようにします。

terminal
echo 'kernel.apparmor_restrict_unprivileged_userns=0' \  | sudo tee /etc/sysctl.d/60-userns.confsudo sysctl --system

ポリシーは残して、bwrapだけを対象外にすることもできます。次の内容を/etc/apparmor.d/bwrapとして保存し、sudo apparmor_parser -r /etc/apparmor.d/bwrapを実行してください。

/etc/apparmor.d/bwrap
abi <abi/4.0>,include <tunables/global>profile bwrap /usr/bin/bwrap flags=(unconfined) {  userns,}

BWRAP_BINが拒否される

BWRAP_BINを使うと、特定のbubblewrapをai-jailに指定できます。ai-jailが受け入れるのは、解決先が、rootが所有しほかのユーザーが書き込めないプログラムである場合か、標準的なマルチユーザーの/nix/store内にある場合だけです。自分のホームに置いたコピーは拒否されます。そのファイルを差し替えられる人なら誰でも、ジェイルを支配できてしまうからです。

opencodeがStarting background serverで止まる

opencode 2.xは共有のバックグラウンドサーバーと通信します。ジェイルは起動のたびに作り直すラッパーで、ホームも新しくなるので、そのサーバーは実行をまたいで残りません。--standaloneを付けてopencodeを単体で起動し、毎回打たずに済むよう設定ファイルに固定してください。これなしでopencodeを起動すると、ai-jailは起動時に警告します。

~/.ai-jail
[commands.opencode]command = ["opencode", "--standalone"]

起動時にFailed to create stream fdと出る

miseのセットアップ中に、Ubuntuデスクトップのログインスクリプトが出すメッセージです。害はなく、miseは問題なく動きます。--no-miseを渡せば、miseのセットアップごとこのメッセージも出なくなります。

terminal
ai-jail --no-mise claude

エージェント別

ai-jailは、各エージェントがログイン情報をどこに保存するかを知っていて、デフォルトでマウントします。対象は起動するエージェントのフォルダだけで、存在する場合に限ります。--no-agent-stateで無効になります。シェルに設定されていれば、そのエージェントのAPIキーの変数も一緒に渡ります:ANTHROPIC_API_KEY、OPENAI_API_KEY、GEMINI_API_KEYまたはGOOGLE_API_KEY、XAI_API_KEY、MOONSHOT_API_KEY。

エージェント別の表を表示
実行するコマンドデフォルトでマウントされるもの知っておくとよいこと
ai-jail claude~/.claude
~/.claude.json
2つ目のClaudeプロファイルを使うには、--claude-dirでそのディレクトリを指定します。
ai-jail codex~/.codexウィンドウをリサイズすると、ai-jailがCodexに再描画キーを送ります。macOSではlockdown外のCodexに専用psシムを渡し、agent stateが有効ならapp serverに必要な限定システムサービスも渡します。--no-agent-stateで外れるのはサービス権限で、シムではありません。
ai-jail gemini~/.gemini
ai-jail opencode~/.config/opencode
~/.local/share/opencode
--standaloneが必要です。上のトラブルシューティングの項目を見てください。
ai-jail antigravity~/.geminiGoogleのログインをGeminiと共有するので、一度のサインインで両方に使えます。
ai-jail kimi~/.kimi以前の場所である~/.kimi-codeも、存在すればマウントされます。
ai-jail kiro-cli~/.kiro
~/.local/share/kiro-cli
macOSでは2つ目のフォルダは代わりに~/Library/Application Support/kiro-cliです。
ai-jail prime-agent~/.prime/agentエージェント自身のフォルダだけで、~/.prime全体は決してマウントしません。
ai-jail devin~/.local/share/devin
~/.config/devin
devin/cli/_versionsにあるCLI自身のインストールは読み取り専用のままです。Devinの更新はホストで行い、そのあと新しいセッションを始めてください。
ai-jail ai-memory run claude起動されるエージェントのフォルダai-jailは、ai-memoryが起動するエージェントを認識して、そのエージェントの設定を適用します。2つのプログラムは同じジェイルに入ります。

crush、grok、jcode、pi、aider、soulforge、ompでも同じです。それ以外のコマンドも、同じジェイルで、ログインフォルダなしで動きます。ai-jailがAPIホストをデフォルトで開けるのはステップ03の5つのエージェントで、ほかのエージェントには--allow-hostか--networkが必要です。

エージェントを檻の中に

ai-jailは単一のバイナリで、デーモンもroot権限も要りません。いつものコマンドの前に1語足すだけです。

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