何のためのものか
Bash コマンドとその子プロセスに対して、OS レベルでファイルシステムとネットワークの境界を強制する仕組み。コマンドごとの承認の代わりに、触れてよいファイルとドメインを定義する。
permission が「どのツールを使えるか」なら、sandbox は「そのコマンドがどこまで届くか」である。
触る
/sandboxを開く。Mode(承認方法)、Overrides(サンドボックス外での再実行を許すか)、Config(解決済み設定)が見える- macOS は組み込みの Seatbelt を使うためインストール不要。Linux / WSL2 は
bubblewrapとsocatが要る(sudo apt-get install bubblewrap socatなど)。不足は Dependencies タブに出る - 依存チェックは起動時に走る。パッケージ導入後は再起動する
パネルでモードを選ぶとプロジェクトの .claude/settings.local.json に保存される。全プロジェクトで有効にするなら ~/.claude/settings.json の sandbox.enabled を true にする。
入れる
2 つの層を、自分の作業に合わせて開ける。
filesystem
- 既定では作業ディレクトリとそのサブディレクトリ、セッション一時ディレクトリだけが書き込み可能。読み取りは一部を除きコンピュータ全体
- 外に書く必要があるなら
sandbox.filesystem.allowWriteにパスを足す。読ませたくないものはdenyRead、その中の例外はallowRead(より具体的なパスが勝つ) - パスの接頭辞は
/(絶対)、~/(ホーム)、接頭辞なし(settings の位置からの相対)。Read / Edit の permission ルールとは書式が違う
network
- 既定では事前許可されたドメインは無い。 新しいドメインが必要になると承認を求め、Yes を選ぶとそのセッションの残りで許可される
- 毎回聞かれたくないものは
allowedDomainsに事前登録する(WebFetchの allow ルールも効く)
守りたい認証情報があるなら sandbox.credentials に列挙する。組み込みの credential deny list は無い。
効かせる
- モードは 2 つ。 auto-allow はサンドボックス化できたコマンドを確認なしに実行し、できないものは通常の permission フローへ落ちる。regular permissions は常に通常フローを通る。どちらでもファイルシステムとネットワークの制限は同じ
- auto-allow でも通るとは限らない。 明示的な deny ルール、
/やホームを対象とするrm、Bash(git push *)のような content-scoped な ask ルールは効き続ける - 失敗したコマンドはサンドボックス外で再実行されることがある(
dangerouslyDisableSandbox)。毎回確認させたいならBash(dangerouslyDisableSandbox:true)の ask ルール、完全に塞ぐなら"allowUnsandboxedCommands": false - 非互換なコマンドは逃がす。
dockerはサンドボックスと非互換なのでexcludedCommandsに入れる。jestは--no-watchmanを使う。macOS の Go 製 CLI(gh/gcloud/terraform)は Seatbelt 下で TLS 検証に失敗しうる
落とし穴
- 組み込みファイルツールはサンドボックスを通らない。 Read / Edit / Write は permission system を直接使う。sandbox が効くのは Bash とその子プロセス
- 既定では TLS を終端・検査しない。 暗号化された接続の中身は見ていない。
github.comのような広いドメインの許可はデータ持ち出しの経路になりうる - サンドボックス化コマンドは親プロセスの環境を継承する。 そこに認証情報があれば見える。全サブプロセスから除去したいなら
CLAUDE_CODE_SUBPROCESS_ENV_SCRUB $TMPDIRの解決先がサンドボックス内外で違う。 両者間で一時ファイルを渡すなら作業ディレクトリ配下に書くallowUnixSocketsは権限昇格の経路になりうる(/var/run/docker.sockの許可は Docker socket 経由でホストへのアクセスを与える)- Windows ネイティブは非対応(WSL2 内で動かす)。WSL1 も非対応