サンドボックス
Bash コマンドのファイルシステム・ネットワーク隔離(サンドボックス)の使い方と仕組み、認証情報の保護、組織での強制、サンドボックス環境(コンテナ・VM など)の選び方をまとめています。
サンドボックスは、Claude が自分のマシン上で実行するシェルコマンドの周りに、OS が強制する境界を作る機能です。そのコマンドが触れてよいファイルとネットワークのドメインを決めておくと、Bash・PowerShell・Monitor のコマンドとその子プロセスに、OS が実行中にその制限を適用します。OS が制限を課すので、Claude Code はコマンドごとの承認を求めずにサンドボックス内のコマンドを実行できます。設定キーは 設定キー一覧 の「サンドボックス」、権限ルールとの関係は 権限ルール にあります。
サンドボックスの対象はシェルコマンドだけです。Claude のファイルツール・MCP サーバー・フックはサンドボックスの外で動きます(下の「サンドボックスの外で動くもの」)。
- macOS・Linux・WSL2 で動く。ネイティブ Windows では、Claude Code はコマンドをサンドボックスなしで実行する(Windows のマシンでは、WSL2 のディストリビューションの中で Claude Code を動かす)。WSL1 は非対応
- 隔離は 2 層:ファイルシステム(読み書きできるパス)とネットワーク(届くドメイン)
- 2 つのモード:自動許可(サンドボックス内のコマンドを確認なしで実行)と通常の権限(サンドボックス内でも通常の確認を出す)
- サンドボックスの対象は Bash・PowerShell・Monitor のコマンドだけ。組み込みのファイルツール・MCP サーバー・フックは対象外
- サンドボックスは完全な隔離境界ではない。ネットワークの絞り込みはホスト名ベースで、TLS の中身は検査しない
補足
このページは、自分のマシン上のシェルコマンドを囲むサンドボックスを扱います。クラウドセッションの隔離は クラウド(Web)で使う、コンテナ・仮想マシンなどほかの隔離方法の比較は下の「サンドボックス環境の選び方」、Bash 以外のツールの確認を減らすには 権限モード を見てください。
サンドボックスが制限するもの#
サンドボックスがオンのあいだ、Claude が実行するシェルコマンドは境界の内側で始まり、そこから起動するプロセスも同じです。サンドボックスは既定でオフです。オンにするには、セッションで /sandbox を実行する(下の「使い始める」)か、~/.claude/settings.json などの設定ファイルで sandbox.enabled を true にします。
サンドボックス内のコマンドが既定で届くものと、それぞれの既定を変える設定は次のとおりです。
| アクセス | 既定 | 変える設定 |
|---|---|---|
| 書き込み | 作業ディレクトリ・ユーザーごとの一時ディレクトリ・追加したディレクトリ。保護されたパスは書き込み拒否のまま | filesystem.allowWrite・filesystem.denyWrite |
| 読み取り | ~/.ssh や ~/.aws/credentials などの認証情報ファイルを含む、マシンのほぼ全体 |
filesystem.denyRead・credentials |
| ネットワーク | 直接の経路は無い。接続は自分のマシン上のプロキシを通り、プロキシが各ホストを許可ドメイン(最初は空)と照合する。許可外のホストの扱いは権限モードで決まる | network.allowedDomains・network.deniedDomains |
| 環境変数 | Claude Code から引き継ぐ(その環境にある秘密も含む) | credentials・CLAUDE_CODE_SUBPROCESS_ENV_SCRUB |
Claude Code は、オープンソースの @anthropic-ai/sandbox-runtime パッケージの上にサンドボックスを作っています。
サンドボックスの外で動くもの#
サンドボックスが包むのはシェルコマンドです。次のツールとプロセスは、その外で動きます。
- 組み込みのファイルツールと Web ツール:Read・Edit・Write・WebFetch・WebSearch などは、代わりに権限ルールに従う。
denyReadの項目は Read ツールを止めず、allowedDomainsは WebFetch を制限しない - Claude Code が起動するほかのプロセス:コマンドフック・ローカルの MCP サーバー・プラグインのモニター・LSP サーバー・ステータスラインのコマンドや
apiKeyHelperなどの補助コマンドは、自分の全アクセスで動く
設定によっては、次のシェルコマンドもサンドボックスの外で動きます。
- 自分で打ったコマンド:
!のシェルモードのプロンプトに打ったコマンドは、ほとんどのセッションでサンドボックスの外で動く。打ったコマンドがサンドボックス内で動くセッションは、下の「厳格なサンドボックスモードで再試行を止める」に挙がっている - 除外されたコマンド:
excludedCommandsに一致するコマンドは、サンドボックスの外で動く - サンドボックス外での再試行:Claude は、たいていサンドボックス内で失敗したあとに、サンドボックスなしでのコマンド実行を求められる
ここに挙げたツール・プロセス・コマンドをまとめて 1 つの境界の内側に置くには、Claude Code のプロセス自体を、コンテナ・仮想マシン・サンドボックスランタイム(後半の「サンドボックス環境の選び方」)の中で動かします。
使い始める#
サンドボックスは Claude Code に組み込まれています。入れるものはプラットフォームで違います。
- macOS:組み込みの Seatbelt を使うので、そのまま手順に進める
- Linux と WSL2:
bubblewrapとsocatが要る(次の節)。まだ入れていなくても/sandboxは開け、パネルが足りないものを示す
- セッションで
/sandboxを実行する。パネルのタブは「Mode」(コマンドの承認方法)・「Overrides」(サンドボックスで失敗したコマンドを、サンドボックス外で実行する逃げ道を許すか。allowUnsandboxedCommandsの設定)・「Config」(解決済みのサンドボックス設定)で、Linux でオプションの seccomp フィルターが無いときは「Dependencies」タブも出る。必須パッケージが足りないときは「Dependencies」タブだけが出るので、インストールして Claude Code を再起動し、もう一度/sandboxを実行する - 「Mode」タブで、自動許可(auto-allow)か通常の権限(regular permissions)を選ぶ
- Claude にビルドやテストなどのコマンドを頼む。既定では、サンドボックス内のコマンドは、作業ディレクトリ・ユーザーごとの一時ディレクトリ・
--add-dir、/add-dir、permissions.additionalDirectoriesで足したディレクトリに書ける
- コマンドが新しいネットワークドメインを初めて必要としたとき、確認が出る。auto mode では確認の代わりに、Claude がコマンドに必要なホストを名指しし、分類器が審査する
- コンテナの中でサンドボックス内のコマンドが
Operation not permittedで失敗するなら、トラブルシューティングの「コンテナの中で bubblewrap が起動しない」を見る - モードを選ぶと、そのプロジェクトの
.claude/settings.local.jsonに保存される(保存時にそのファイルがグローバルの gitignore に足される)。全プロジェクトで有効にするには、~/.claude/settings.jsonでsandbox.enabledをtrueにする。組織全員に強制するなら管理設定を使う - 設定ファイルに書かずに 1 セッションだけ変えるには
--settingsで起動する
claude --settings '{"sandbox": {"enabled": true, "allowUnsandboxedCommands": false}}'
注意
既定では、依存パッケージの欠落や非対応のプラットフォームでサンドボックスが起動できないと、Claude Code はサンドボックスなしでコマンドを実行します。これを、起動時に Claude Code を終了させる動作にするには sandbox.failIfUnavailable を true にします(サンドボックスを必須のセキュリティゲートにする管理配布向け)。
サンドボックス内で動いているか確かめる#
サンドボックスが動いているかは、Claude に次の表の各行を実行させて確かめます。! のプロンプトに打ったものは、たいていサンドボックスの外で動くので、自分で打っても確認になりません。
| コマンド | サンドボックス内での結果 |
|---|---|
touch ~/sandbox-probe |
macOS では Operation not permitted、Linux・WSL2 では Read-only file system で失敗する |
curl --noproxy '*' https://example.com |
サンドボックスのプロキシを迂回する経路が無いので、Could not resolve host で失敗する |
失敗したコマンドをサンドボックスの外で再試行するかと Claude に聞かれたら、断ります。touch が成功し、ホームディレクトリがサンドボックスの書き込める先に入っていないなら、~/sandbox-probe を削除します。そのうえで /sandbox を実行し、サンドボックスがオンで依存が入っているかを確かめます。
Linux と WSL2 の準備#
サンドボックスは次のパッケージに依存します。
bubblewrap:ファイルシステムの隔離を強制する、特権不要のサンドボックスツールsocat:ネットワークトラフィックをサンドボックスのプロキシへ中継する
# Ubuntu / Debian
sudo apt-get install bubblewrap socat
# Fedora
sudo dnf install bubblewrap socat
- パッケージが足りないとき、
/sandboxの「Dependencies」タブがripgrep・bubblewrap・socat・seccomp フィルターのどれが無いかを示す。インストールして再起動してもタブが出なければ、依存はすべて揃っている。依存の検査は起動時に走るので、インストール後は Claude Code を再起動する - ripgrep はネイティブ版の Claude Code に同梱される。seccomp フィルターはオプションで、Unix ドメインソケットのブロックを加える。無ければ
npm install -g @anthropic-ai/sandbox-runtimeで入れる
Ubuntu 24.04 以降では、既定の AppArmor ポリシーが bubblewrap の必要とするユーザー名前空間の作成を妨げます。sysctl kernel.apparmor_restrict_unprivileged_userns を実行して(WSL2 の中でも)、0 を返すかキーが無い(No such file or directory)なら対応は不要です。1 を返すなら、bwrap にこの権限を与える AppArmor プロファイルを足します。
sudo tee /etc/apparmor.d/bwrap > /dev/null <<'EOF'
abi <abi/4.0>,
include <tunables/global>
profile bwrap /usr/bin/bwrap flags=(unconfined) {
userns,
include if exists <local/bwrap>
}
EOF
sudo systemctl reload apparmor
プロファイルが適用されるのは bwrap 自身だけで、サンドボックスの中で動かすコマンドには適用されません。
WSL2 の注意:
- PowerShell で
wsl -l -vを実行してバージョンを確かめる。Sandboxing requires WSL2と出たらディストリビューションは WSL1 なので、WSL2 にアップグレードするか、サンドボックスなしで動かす - WSL2 は、
cmd.exe・powershell.exe・/mnt/c/以下など Windows のバイナリの起動を、Unix ソケット経由で Windows ホストに渡す。サンドボックス内のコマンドがそれを起動できるかは、サンドボックスの Unix ソケット設定に従う(ソケットを最初にブロックするにはオプションの seccomp フィルターが要る)。起動を許すにはallowAllUnixSocketsを設定する(すべての Unix ソケットをサンドボックス内のコマンドに開く)
サンドボックスのモード#
2 つのモードで、サンドボックスの強制するファイルシステムとネットワークの制限は同じです。違いは、サンドボックス内のコマンドを自動で承認するか、明示の許可を求めるかだけです。
自動許可モード(auto-allow)#
サンドボックス内で実行されるコマンドは、確認なしで自動承認されます。通常の権限の流れを通るのは、excludedCommands に一致するか、Claude がサンドボックス外で再試行したために、サンドボックスの外で動くコマンドです。
許可していないホストに接続するサンドボックス内のコマンドは、サンドボックス内にとどまります。接続の可否を誰が決めるかは、下の「許可ドメイン外のホスト」を参照してください。
自動許可モードでも、次は引き続き適用されます。
- 明示的な deny ルールは常に守られる
- 重要なパスを対象にする
rmやrmdirは、通常の権限の流れに従う Bash(git push *)のような内容を絞った ask ルールは、サンドボックス内のコマンドでも確認を強制するBashだけの ask ルール(同等のBash(*))は、サンドボックス内で動くコマンドでは省かれ、通常の権限の流れに回ったコマンドには適用される。plan mode では省かれず、サンドボックス内の読み取り専用のコマンドを含めて確認が出る
自動許可モードは権限モードの設定とは独立に動きます。例外は 3 つ:plan mode、コマンドごとの許可ドメインを持つ auto mode のコマンド、auto mode でのサーバー側の分類器によるサンドボックス内コマンドの審査です。「accept edits」モードでなくても、自動許可がオンなら、サンドボックス内の Bash コマンドは自動で動きます。つまり、サンドボックスの境界内でファイルを変更する Bash コマンドは、ファイル編集ツールが確認を出す Manual モードでも確認なしで実行されます。plan mode では自動許可は承認を広げません。
通常の権限モード(regular permissions)#
すべての Bash コマンドが、サンドボックス内でも通常の権限の流れを通ります。制御は増えますが、承認も増えます。
サンドボックス外での再試行(逃げ道)#
サンドボックス外での再試行は、サンドボックスの中で失敗するコマンド(互換性のないツールなど)のための逃げ道です。サンドボックスがネットワーク接続をブロックすると、Claude Code は拒否したホストの名前をコマンドの結果に書くので、Claude は何がブロックされたかを見られます。Claude は失敗を分析して、dangerouslyDisableSandbox パラメーターでコマンドを再試行することがあります。
再試行したコマンドはサンドボックスの外で動きます。対話のターミナルセッションでは、誰が承認するかは権限モードで決まります。
bypassPermissionsモード:確認なしで再試行が動く- Manual モードと
acceptEditsモード:「Bash command (unsandboxed)」という見出しの確認が出る - auto mode:別の分類器モデルが元のコマンドを評価する
dontAskモード:Claude Code が再試行を拒否する- plan mode:計画中のコマンドの扱いは、権限モード を参照
次のルールと設定は、再試行を誰が承認するかを変えます。
- 一致する allow ルール:
Bash(curl *)のような allow ルールがコマンドに一致すると、再試行も承認されるので、確認なしでサンドボックスの外で動く - パラメーターの ask ルール:
Bash(dangerouslyDisableSandbox:true)の ask ルールを足すと、Bash の再試行で確認が出る。auto mode とbypassPermissionsモードでも確認が出て、このルールは一致する allow ルールより優先される permissions.blockReadsOutsideWorkingDirectories:オンのあいだ確認が出る再試行は、権限モード の「どのモードも自動承認しないアクション」にある
厳格なサンドボックスモードで再試行を止める#
サンドボックス設定で "allowUnsandboxedCommands": false にすると、サンドボックス外での再試行を止められます。止めると、dangerouslyDisableSandbox パラメーターは無視され、サンドボックスの動作中は、excludedCommands の項目に一致しないかぎり、Claude が実行するコマンドはサンドボックス内で動きます。サンドボックスが起動できないときに Claude Code がコマンドをサンドボックスなしで動かさないようにするには、failIfUnavailable も設定します。/sandbox の「Overrides」タブでは、この設定が「Strict sandbox mode」と表示されます。
ユーザー設定・--settings・管理設定の false は、プロジェクト設定が true でも保たれます。ユーザー設定の false ではサンドボックスは admin-required(管理者が必須にした状態)にならず、プロジェクトのほかのサンドボックス設定は引き続き適用されます。v2.1.285 より前は、プロジェクトの true がユーザー設定の false を上書きしました。
管理設定か --settings フラグで再試行を止めると、サンドボックスは admin-required になります。このとき Claude Code は、リポジトリのファイルにある、サンドボックスを緩める設定(excludedCommands の項目を含む)を無視します。無視される設定は、下の「admin-required のサンドボックスでのリポジトリ設定」に挙げています。
厳格なサンドボックスモードが適用されるのは、Claude が実行するコマンドです。! のシェルモードのプロンプトに自分で打ったコマンドは、次のどちらかのセッションでないかぎり、サンドボックスの外で動きます。
- バックグラウンドセッション:厳格なサンドボックスモードがシェルモードのコマンドにも及ぶ
CLAUDE_CODE_SUBPROCESS_ENV_SCRUBを設定した Linux のセッション:シェルモードを含むすべてのコマンドがサンドボックス内で動く
v2.1.260 より前は、すべてのセッションで、厳格なサンドボックスモードがシェルモードのコマンドもサンドボックス内で動かしました。
一時ディレクトリ#
ユーザーごとの一時ディレクトリは、作業ディレクトリと並んで、サンドボックスの中で既定で書き込めます。ファイルシステムの隔離を無効にしていないかぎり、Claude Code はサンドボックス内のコマンドの $TMPDIR をこのディレクトリにするので、一時ファイルを書くツールは追加の設定なしで動きます。
- サンドボックス外のコマンドは、シェルに
$TMPDIRがあればそれを引き継ぐので、隔離がオンのあいだ、サンドボックス内外では$TMPDIRが別のディレクトリに解決される - シェルで
$TMPDIRが未設定か空なら、サンドボックス外のコマンドで$TMPDIRを参照すると、CLAUDE_CODE_TMPDIRの上書き(未設定か長いパスなら OS の一時ディレクトリ)が渡り、空文字に展開されない - 両者のあいだで一時ファイルを渡すには、作業ディレクトリの下に書く
サンドボックスの設定#
settings.json で挙動を変えます。全キーは 設定キー一覧 にあります。
サブプロセスのコマンド(kubectl・terraform・npm など)が、既定の書き込み先の外へ書く必要があるときは、sandbox.filesystem.allowWrite で特定のパスに許可を与えます。
{
"sandbox": {
"enabled": true,
"filesystem": {
"allowWrite": ["~/.kube", "/tmp/build"]
}
}
}
- これらのパスは OS レベルで強制され、子プロセスを含むサンドボックス内のすべてのコマンドが従う。ツールが特定の場所への書き込みを必要とするときは、
excludedCommandsでツールをサンドボックスから外すよりこちらを勧める - 同じファイルシステムの配列を複数のスコープで定義すると、置き換えずにパスが結合される。下の「開発者がポリシーを広げるのを防ぐ」のロックが覆う項目は、結合から外れる
- CLI の
--setting-sourcesや Agent SDK のsettingSourcesで設定元を除くと、サンドボックス設定を作るとき、その設定元のsandbox.filesystemの項目・Editの権限ルール・Readの deny ルールが無視される(v2.1.246 以降) - セッション中にこれらのファイルシステムのリストを編集すると、実行中のセッションに反映され、次のサンドボックス内のコマンドから新しいパスで動く
- サンドボックスのファイルシステムのパスは標準の慣習で、
/tmp/buildは絶対パス、~/.kubeはホームディレクトリからの相対。Read・Edit の権限ルール(//pathが絶対、/pathがプロジェクト相対)とは書き方が違う。相対パス・末尾のスラッシュ・ワイルドカードの扱いは、設定キー一覧 の「Sandbox path prefixes」にある
sandbox.filesystem.denyWrite・denyRead で書き込み・読み取りを拒否し、allowRead で拒否した領域の中の特定のパスを開き直せます。読み取りのルールが重なるときは、より狭いパスのルールが適用されます。
| ルールの例 | 結果 |
|---|---|
"denyRead": ["~/"] と "allowRead": ["~/projects"] |
~/projects は読め、ホームディレクトリの残りはブロックされたまま(狭い allow が拒否領域の一部を開き直す) |
"allowRead": ["~/"] と "denyRead": ["~/.env"] |
~/.env はブロックされたままで、ホームディレクトリの残りは読める(広い allow の中でも deny が保たれ、秘密が黙って再び見えることはない) |
"allowRead": ["~/"] と "denyRead": ["~/**/.env"] |
ホームディレクトリ以下のすべての .env がブロックされたままで、残りは読める(ワイルドカードの deny も、完全なパスと同じく広い allow の中で保たれる) |
次の例は、ホームディレクトリ全体の読み取りをブロックしつつ、現在のプロジェクトの読み取りを許します。相対パス . は、設定がプロジェクト設定にあるときにプロジェクトルートに解決されるので、プロジェクトの .claude/settings.json に置きます。
{
"sandbox": {
"enabled": true,
"filesystem": {
"denyRead": ["~/"],
"allowRead": ["."]
}
}
}
同じ設定を ~/.claude/settings.json に置くと、. は ~/.claude に解決され、プロジェクトのファイルは denyRead のルールでブロックされたままになります。
ホームディレクトリとマウントされたボリュームの読み取りを、作業ディレクトリは読めるままサンドボックス内のコマンドから拒否するには、パスのルールを書く代わりに permissions.blockReadsOutsideWorkingDirectories を設定します。
excludedCommands でコマンドをサンドボックスの外で動かす#
sandbox.excludedCommands にコマンドのパターンを挙げると、一致するコマンドがサンドボックスの外で動きます。つまり、ファイルシステムの制限もネットワークプロキシもありません。サンドボックスの中では動かず、自分の全アクセスを預けてよいツールに使います。もう 1 つのディレクトリやホストが要るだけのツールは、コマンドをサンドボックス内に保つ allowWrite や allowedDomains で動くことがあります。
次の例は、docker compose のコマンドをサンドボックスから出します。全プロジェクトに適用するには ~/.claude/settings.json に保存します。
{
"sandbox": {
"enabled": true,
"excludedCommands": ["docker compose *"]
}
}
Claude Code は、Bash と Monitor の呼び出しごとに項目を照合します。呼び出しとは、Claude が送るコマンドライン全体で、複数のコマンドをつないでいることもあります。呼び出しがサンドボックスを出るかは、次のルールで決まります。
- パターンは
*で終える:項目はBash(...)の権限ルールと同じ構文で、ワイルドカードの無いパターンは完全一致。dockerは引数なしのdockerだけに一致し、docker *は引数ありでもなしでも一致する - 呼び出しの中のすべてのコマンドが一致する必要がある:
npm ci && docker compose buildは、別の項目がnpm ciを覆わないかぎりサンドボックス内にとどまる - Claude Code は呼び出しの文字列に一致させる:内部で
dockerを呼ぶスクリプトやmakeのターゲットは一致せず、/usr/local/bin/dockerも一致しない - サンドボックス内にとどまる呼び出しがある:ファイルへのリダイレクト・
cd・$(...)のようなコマンド置換があると、呼び出し全体がサンドボックス内にとどまる。ほかにとどまる呼び出しは、設定キー一覧のsandbox.excludedCommandsに挙がっている - 項目を保存する場所が影響することがある:サンドボックスが admin-required のあいだ、Claude Code は
.claude/settings.jsonと.claude/settings.local.jsonの項目を無視する
除外されたコマンドは、通常の権限の流れを通ります。
- 読み取り専用のコマンドと、allow ルールが覆うコマンドは、確認なしで動く
- auto mode では、分類器がそのほかの除外されたコマンドを審査する
bypassPermissionsモードでは、ask ルールが一致しないかぎり、除外されたコマンドは確認なしで動く
項目が一致するかを確かめるには、Manual モードに切り替え、一致するコマンドで何かを変えるもの(docker compose up -d など)を Claude に実行させます。権限の確認の見出しが「Bash command (unsandboxed)」になります。
注意
除外されたコマンドは、自分の全アクセスで動きます。docker * のような広い項目は、そのツールにできることすべてを覆います。インタープリターや、作業ディレクトリ内のスクリプト、docker compose が compose ファイルを扱うようにそこにあるファイルに作用するツールを覆うパターンを書くと、Claude がそのファイルを書き、そのあとサンドボックスの外で実行できてしまいます。パターンが狭いほど、Claude がサンドボックスの外で実行できるものは減ります。
ファイルシステムの隔離を無効にする#
sandbox.filesystem.disabled を true にすると、ネットワークの隔離は保ったまま、ファイルシステムの隔離を省きます。次の例は、ファイルシステムの隔離をオフにして、ネットワークのドメインの許可リストを保ちます。
{
"sandbox": {
"enabled": true,
"filesystem": { "disabled": true },
"network": { "allowedDomains": ["github.com", "*.npmjs.org"] }
}
}
サンドボックスには独立した 2 つの層があります。ファイルシステムの隔離は、サンドボックス内のコマンドが読み書きできるパスを、ネットワークの隔離は届くドメインを制御します。ファイルシステム層をオフにすると、サンドボックス内のコマンドはホストのファイルシステムを自由に読み書きでき、ネットワークの出口だけが許可ドメインに限られます。コマンドが何を書くかでなく、どこへ接続するかを制御したいときに使います。
sandbox.filesystem.disabled の既定は false です。v2.1.216 以降が必要です。
注意
ファイルシステムの隔離をオフにして、コマンドを自動許可していると、サンドボックス内のコマンドが、後のコマンドが実行・読み取りするファイル(シェルの起動ファイル・$PATH の実行ファイル・~/.claude/settings.json)を書き、次の実行で自分のアクセスを広げられます。自分でアクセスを昇格させないと信頼できる作業にだけ使います。allowManagedDomainsOnly でネットワークのドメインを固定してもリスクは狭まるだけです(このロックはサンドボックス内のコマンドにだけ適用されるため)。
どの設定元がオフにできるかは次のとおりです。
- ユーザー設定・管理設定・
--settingsフラグが設定できる。.claude/settings.jsonと.claude/settings.local.jsonのプロジェクト設定は設定できない(チェックアウトしたプロジェクトが隔離を外せないように) - 管理設定が
sandbox.filesystemを何か設定している、または"mode": "deny"のsandbox.credentials.filesの項目があると、管理設定だけがこのキーを設定できる(管理者が配ったファイルシステムの制限を保つため。緩めるには管理設定で"disabled": true) CLAUDE_CODE_SUBPROCESS_ENV_SCRUBを設定していると、管理設定を含むすべての設定元のfilesystem.disabledが無視され、ファイルシステムの隔離はオンのまま
有効な mask の項目は、起動時に deny にフォールバックしても、このキーを固定しません。マスクできないパス(認証情報のディレクトリなど)は、管理設定で明示的な deny の項目として書くと、キーが固定されます。
隔離がオフのときに何が変わるかは次のとおりです。ファイルシステム層自身が強制する保護は外れ、ほかの層が強制する保護は残ります。
| 保護 | 隔離がオフのとき |
|---|---|
filesystem.denyRead と credentials.files の deny の読み取りブロック |
強制されない(どちらもファイルシステム層が適用する) |
credentials.envVars の deny と mask の項目 |
強制される(環境変数の除去はファイルシステム層と独立) |
マスクとして適用された credentials.files の mask の項目 |
強制される(deny にフォールバックした項目は、どの deny とも同じく強制されない) |
- サンドボックス内のコマンドが、ユーザーごとの一時ディレクトリでなくシェルの
$TMPDIRを引き継ぐ(どの一時ディレクトリも書き込めるので Claude Code が誘導しなくなる)。Linux では親のシェルで未設定のことが多く、Bash ツールの指針は、$TMPDIRに頼らずmktemp -dで作業用ディレクトリを作るよう Claude に伝える autoAllowBashIfSandboxedは引き続き既定でtrueなので、サンドボックス内のコマンドは確認なしで動く。サンドボックス内のコマンドにも確認を出すならfalseにする
認証情報を守る#
sandbox.credentials は、サンドボックス内のコマンドから守る認証情報のファイルと環境変数を宣言します。各項目はファイルパスか環境変数名と mode を持ちます。
"mode": "deny":ファイルはサンドボックス内で読み取りが拒否され(filesystem.denyReadと同じ制限)、環境変数は各サンドボックス内のコマンドの実行前に unset される。ファイルの保護はファイルシステム層の一部なので、隔離を無効にすると適用されない(環境変数の保護は続く)- ファイルパスは
sandbox.filesystem.*と同じ接頭辞の規則に従う denyの項目は、セッションが読み込む全設定スコープから結合される。denyは狭めるだけなので、どのスコープも足せるが、ほかのスコープが足したものは消せない- 設定元を除くと、プロジェクト/ローカル設定の
credentialsの項目はどれも適用されない(v2.1.246 以降)。ユーザー設定の場合は、~/.claude/settings.jsonのdenyの項目は適用され、ファイルのmaskの項目は、プロキシが本物の値に置換する権限を失った制限として残るが、環境変数のmaskの項目は捨てられる - 組み込みの認証情報の deny リストは無く、挙げたファイルと変数だけが制限される。
sandbox.credentialsはサンドボックス内の Bash コマンドにだけ効く。サンドボックスに関係なくすべてのサブプロセスから認証情報を取り除くにはCLAUDE_CODE_SUBPROCESS_ENV_SCRUBを設定する
{
"sandbox": {
"enabled": true,
"credentials": {
"files": [
{ "path": "~/.aws/credentials", "mode": "deny" },
{ "path": "~/.ssh", "mode": "deny" }
],
"envVars": [
{ "name": "GITHUB_TOKEN", "mode": "deny" },
{ "name": "NPM_TOKEN", "mode": "deny" }
]
}
}
}
認証情報をマスクする#
認証情報をマスクすると、Claude Code はサンドボックス内のコマンドに、セッションごとの身代わりの値(sentinel)を見せ、サンドボックスのプロキシが、許可したホストへの外向きのリクエストで本物の値に置き換えます。「認証情報を守る」の deny の項目は、代わりに認証情報をブロックします。macOS のファイルでは、マスクの代わりにファイルをブロックします。全フィールドは 設定キー一覧 の「sandbox.credentials」にあります。
マスクには次が必要です。
- TLS の終端:プロキシはリクエストの内容の中で本物の値に置換するので、内容を見られなければならない。
network.tlsTerminateを設定して、プロキシ自身に TLS を終端させる。設定しないとマスクは何も露出せずに失敗する(コマンドは身代わりの値だけを見るが、身代わりがそのままサーバーに届き、認証が失敗する)。この設定ミスは、ターミナルでclaude doctorを実行し、TLS termination is unavailableの警告を探して確かめる - 許可された宛先:各
maskの項目は、本物の値が届いてよいホストをinjectHostsに挙げられる。プロキシはドメイン許可リストが通す接続にだけ注入するので、injectHostsのホストはnetwork.allowedDomainsでも届く必要がある。injectHostsが無いmaskの項目では、プロキシはnetwork.allowedDomainsのすべてのホストへのリクエストで本物の値に置換する - 信頼できる設定スコープ:マスクは、プロキシが本物の認証情報をどこかへ送る権限を与えるので、Claude Code は
maskの項目・network.tlsTerminate・credentials.allowPlaintextInject・awsPairs・sigv4を、ユーザー設定・管理設定・--settingsフラグからだけ有効にする。リポジトリの.claude/settings.jsonと.claude/settings.local.jsonでは無視する。管理者がサーバー管理設定でmaskの項目・network.tlsTerminate・credentials.allowPlaintextInjectを配ると、承認が要る設定として扱われる
環境変数のマスク#
環境変数をマスクするには、その credentials.envVars の項目に "mode": "mask" を付けます。コマンドとそのログは本物の認証情報を持ちませんが、リクエストは認証できます。同じ変数がどのスコープでも deny に挙がっていれば、deny が優先されます。
次の例は 2 つのトークンをマスクします。GH_TOKEN は api.github.com へのリクエストだけで置換され、NPM_TOKEN は injectHosts が無いので network.allowedDomains のすべてのホストへのリクエストで置換されます。
{
"sandbox": {
"enabled": true,
"network": {
"tlsTerminate": {},
"allowedDomains": ["*.github.com", "registry.npmjs.org"]
},
"credentials": {
"envVars": [
{ "name": "GH_TOKEN", "mode": "mask", "injectHosts": ["api.github.com"] },
{ "name": "NPM_TOKEN", "mode": "mask" }
]
}
}
}
マスクは既定で値全体を置き換えます。DATABASE_URL の接続文字列や JWT のように構造を持つ値には、extract・decode・maskClaims・onExtractNoMatch のフィールドを使うと、値を解析するツールが動き続けます(設定キー一覧 の「sandbox.credentials」)。
IPv6 の宛先は、2 つのリストで書き方が違います。
network.allowedDomains:角括弧付きの形("[::1]"など)injectHosts:正規の圧縮形の素のアドレス("::1"など)
プロキシは injectHosts の各項目を、接続の素の宛先アドレスと(ポートを無視して)照合するので、角括弧・ゾーン ID・別の圧縮の書き方は一致しません。claude doctor は一致しえない項目を Sandbox credential injectHosts entries can never match their destination の警告で挙げます。この検査は v2.1.229 以降が必要です。
AWS リクエストの再署名#
AWS のリクエストはリクエスト内容への SigV4 署名を持つので、AWS_ACCESS_KEY_ID と AWS_SECRET_ACCESS_KEY を一緒にマスクします。プロキシは、アクセスキーの身代わりの値で SigV4 のリクエストを検出し、本物の値でリクエストを再署名します(v2.1.221 以降が必要)。シークレットだけをマスクすると、リクエストはプロキシが検出できない身代わりの値で署名されるので、AWS で失敗します。
標準の AWS_ACCESS_KEY_ID・AWS_SECRET_ACCESS_KEY・AWS_SESSION_TOKEN は、値全体をマスクすれば自動で 1 つの認証情報にまとめられます。AWS の認証情報がほかの名前の変数にあるなら、credentials.awsPairs でまとめます(v2.1.224 以降が必要)。
ストリーミングアップロード・事前署名 URL・SigV4A のリクエストは、プロキシが再計算できない署名を持ちます。マスクしたペアの身代わりの値でそのようなリクエストが署名されると、プロキシは壊れた署名を転送せずに失敗させます(マスクしていない認証情報で署名したリクエストは影響を受けません)。これらの形のリクエストを代わりに転送するには、credentials.sigv4(v2.1.224 以降が必要)を使います。AWS はそのリクエストを拒否するので、呼び出したツールはプロキシのエラーでなく AWS 自身の拒否応答を受け取ります。
認証情報ファイルのマスク#
ファイルをマスクするには、その credentials.files の項目に "mode": "mask" を付けます。ファイルのマスクは v2.1.221 以降が必要です。サンドボックス内のコマンドが見るものはプラットフォームで違います。
- Linux・WSL2:サンドボックス内のコマンドは、ファイルの身代わり(sentinel)のコピーを読み、プロキシが外向きのリクエストで本物の値に置換する
- macOS:サンドボックス内のコマンドは、そのファイルをまったく読めない。Claude Code は身代わりのコピーを作らないので、そのファイルで認証するツールはサンドボックス内で動かない(
denyと同じ効果)。ファイルシステムの隔離を無効にしても、読み取りのブロックは保たれる
次の例は ~/.config/gh/hosts.yml の GitHub トークンをマスクします。extract のパターンが、ファイルのどの部分が秘密かを示すので、Linux・WSL2 では gh が設定の残りを引き続き解析できます。
{
"sandbox": {
"enabled": true,
"network": { "tlsTerminate": {}, "allowedDomains": ["*.github.com"] },
"credentials": {
"files": [
{
"path": "~/.config/gh/hosts.yml",
"mode": "mask",
"extract": "oauth_token:\\s*(\\S+)",
"injectHosts": ["api.github.com"]
}
]
}
}
}
マスクが効いているかは、サンドボックス内のコマンドで Claude に cat ~/.config/gh/hosts.yml を実行させて確かめます。Linux・WSL2 では出力にトークンの代わりに身代わりの値が出て、macOS では読み取りが失敗します。
extract も decode も無いと、Claude Code はファイル全体を 1 つの身代わりの値に置き換えます。裸の秘密 1 つだけを持つファイル向けです。部分的なマスクと、パターンが何にも一致しないときの動きは、extract・decode・maskClaims・onExtractNoMatch・maskDuplicates のフィールドで制御します(設定キー一覧 の「sandbox.credentials」)。
注意
マスクするものが見つからないとき、onExtractNoMatch の既定値 warn はその項目をスキップするので、サンドボックス内のコマンドは本物のファイルをマスクなしで読めます。macOS では、ファイルシステムの隔離がオンのあいだ、パターンが動く前に mask の項目を deny として適用するので、一致なしの結果が効くのは、ファイルシステムの隔離がオフのときだけです。既定は、認証情報が無くてもよい場合向けです。秘密があるかもしれないのにパターンが外すかもしれないなら、deny を使います。
mask は 1 つのファイルに適用されるので、認証情報のファイルは個別に挙げます。Claude Code は、安全にマスクできない mask の項目(ディレクトリのパス・glob パターン・8 MiB を超えるファイル・UTF-8 テキストでないファイル)を deny にフォールバックします。
サンドボックスの仕組み#
ファイルシステムの隔離#
- 既定の書き込み:現在の作業ディレクトリとそのサブディレクトリ、
--add-dir・/add-dir・permissions.additionalDirectoriesで足したディレクトリ、$TMPDIRが指すユーザーごとの一時ディレクトリへの読み書き - 既定の読み取り:特定の拒否ディレクトリを除く、コンピューター全体への読み取り。この既定では認証情報のファイルも読めるので、コマンドに読ませたくない認証情報は「認証情報を守る」で守る
- 読み取りのブロック:
permissions.blockReadsOutsideWorkingDirectoriesがオンなら、サンドボックス内のコマンドも、ホームディレクトリとユーザーのファイルを持つほかのディレクトリへの読み取りを失う(権限 の「Sandboxed commands under the block」に挙がるパスを除く) - git の worktree:作業ディレクトリが linked worktree のとき、
git commitが ref とインデックスを更新できるよう、メインリポジトリの共有の.gitディレクトリへの書き込みも許す。その中のhooks/とconfigへの書き込みは拒否されたまま
ネットワークの隔離は保ったままファイルシステムの隔離を丸ごと省くには、sandbox.filesystem.disabled を設定します(上の「ファイルシステムの隔離を無効にする」)。
保護されたパス#
サンドボックス内のコマンドが書けるディレクトリの中でも、Claude Code が設定とコードを読み込むファイルへの書き込みは拒否されたままです。これらを編集できるコマンドは、自分に権限を与えたり、サンドボックスの外で Claude Code が実行するフックや MCP サーバーを足したりできてしまうためです。権限システムにも保護されたパスがありますが、それは、ツールが動く前に Claude Code が承認するものを制御します。サンドボックスのリストは、すでに動いているコマンドに適用されます。次の 4 つのグループがあります。
-
作業ディレクトリとその上のディレクトリ:
.claudeの設定ファイル、.claude/skills・.claude/agents・.claude/commands・.claude/hooksディレクトリ、.mcp.json、.claude/workflowsや.claude/scheduled_tasks.jsonのように Claude Code が自分で実行するファイル -
作業ディレクトリだけ:
.bashrc・.zshrcなどのシェルの起動ファイル、.gitconfig、.vscodeと.ideaディレクトリ、.git内のhooksとconfig -
作業ディレクトリを bare な git リポジトリにしてしまうファイル:最上位の
HEAD・objects・refsと、HEADが並んでいるときの既存のconfigとhooksの項目(configというファイルはHEADが無くても拒否される)。Linux・WSL2 では、サンドボックス内のコマンドの実行中に現れた最上位のHEADファイルやobjects・refsディレクトリを、サンドボックスが削除する -
~/.claude(またはCLAUDE_CONFIG_DIRが指すディレクトリ):その内容の大部分と、~/.claude.json、認証情報のストアの.credentials.json -
保護された設定ファイルのパスにセッション中にシンボリックリンクが現れると、次のコマンドから、サンドボックスはそのリンク先への書き込みも拒否する
-
これらのパスを 1 つだけ除外する方法は無い。それを覆う
allowWriteの項目やEditの allow ルールも、保護を外さない。保護を外せるのは、すべてのパスのファイルシステムの隔離をオフにするfilesystem.disabledだけ -
これらのパスの大部分は、
/sandboxの「Config」タブの「Denied within allowed」に、自分のdenyWriteの項目と一緒に、マシンごとに解決されて並ぶ -
git mergeやgit checkoutがこれらのパスでunable to unlink oldで失敗したら、トラブルシューティングの「git のコマンドがunable to unlink oldで失敗する」を見る
ネットワークの隔離#
サンドボックス内のコマンドには、ネットワークへの直接の経路がありません。
- Linux と WSL2:コマンドは、自分のネットワークにつながらない別のネットワーク名前空間で動く
- macOS:Seatbelt が既定で、サンドボックスのプロキシへの接続以外をブロックする
Claude Code は、サンドボックスのプロキシをサンドボックスの外の自分のマシンで動かし、HTTP_PROXY・HTTPS_PROXY・ALL_PROXY などの環境変数でコマンドをそこへ向けます。プロキシは、接続ごとのホスト名を、許可ドメインと拒否ドメインに照らします。
ツールが届くものは、プロキシを使うかどうかで変わります。
- プロキシの変数を読むツール:
curl・npm・HTTPS 経由のgitなどは、ホストが許可されれば接続できる。ポートの無いallowedDomainsの項目は、そのホストのすべてのポートを許す - プロキシの変数を無視するツール:素の
ssh・多くのデータベースドライバーなどは、許可されたホストにも接続できない(トラブルシューティングの「データベースクライアントなど HTTP 以外のツールが、許可したホストに届かない」を参照) - TCP でないもの:UDP・QUIC 上の HTTP/3・
pingなどの ICMP のツールは、サンドボックスの外へ出られない
プロキシが許すホストは、次の設定と動作で決まります。
- ドメインの制限:許可ドメインは最初は空。コマンドが新しいドメインを初めて必要としたときの扱いは、下の「許可ドメイン外のホスト」にある
- 承認の選択:「Yes」ではそのセッションの残りのあいだ、そのホストが許可される。「Yes, and don't ask again」では、ローカル設定に
WebFetch(domain:...)の allow ルールが保存され、将来のセッションでもそのホストが許可される。サンドボックスが admin-required のあいだは、ルールがユーザー設定に保存され、全プロジェクトで有効になる - 事前に許可するドメイン:
allowedDomainsで事前に許可すると確認が出ない。Claude Code はWebFetch(domain:...)の allow ルールのドメインも事前に許可する - 厳格な許可リスト:ユーザー・管理・CLI の
--settingsでstrictAllowlistをtrueにすると、許可リストの外のホストへのサンドボックス内のコマンドのアクセスを、確認でなく拒否する。許可リストは、allowedDomainsとWebFetch(domain:...)の allow ルールのドメイン(allowManagedDomainsOnlyなら管理設定の項目だけ)。リポジトリの項目の扱いは、下の「admin-required でなくても効くロック」にある。サンドボックス内のコマンドにだけ強制され、WebFetchのようなプロセス内のツールは権限ルールに従う。リポジトリの.claude/settings.jsonなどに置いた値は効かない。v2.1.219 以降 - 管理設定でのロックダウン:管理設定で
allowManagedDomainsOnlyを設定すると、許可されないドメインは確認でなく自動でブロックされ、管理設定のallowedDomainsとWebFetch(domain:...)の allow ルールだけが有効になる - 社内プロキシ:ネットワークが社内プロキシ経由の外向きトラフィックを要求するなら、
HTTPS_PROXY・HTTP_PROXY・NO_PROXYを、バックグラウンドエージェントにも届くよう設定のenvブロックか、Claude Code を起動する環境に設定する。Claude Code はドメイン許可リストを強制してから、許可された接続を上流のプロキシへトンネルする。プロキシの URL はhttp://とhttps://が使え、必要なら URL に Basic 認証を入れられる WebFetch(domain:...)のルールで、サンドボックスが使えるワイルドカードは 2 つ:先頭の*.(*.example.com)と単独の*(v2.1.186 以降)。ほかの位置のワイルドカード(WebFetch(domain:example.*))は、取得には一致するがサンドボックス内のコマンドには効かない
補足
組み込みのプロキシは、要求されたホスト名に基づいて許可リストを強制し、既定では TLS を終端も検査もしません。実験的な network.tlsTerminate は、組み込みのプロキシに TLS を終端させます(mask の認証情報の項目に必要)。TLS の検査が要る脅威モデルなら、カスタムプロキシを使います。
許可ドメイン外のホスト#
サンドボックス内のコマンドが、許可ドメインに無いホストへ接続すると、コマンドはサンドボックス内にとどまって判断を待ちます。対話のターミナルセッションでは、判断は権限モードで決まります。
| 権限モード | 接続の扱い |
|---|---|
bypassPermissions モードと、bypass permissions が使える plan mode |
確認なしで許可 |
Manual モード・acceptEdits モードと、それ以外の plan mode |
確認が出る |
| auto mode | コマンドがホストを挙げ、分類器がそのリストを承認しないかぎり拒否 |
dontAsk モード |
拒否 |
strictAllowlist か allowManagedDomainsOnly がオンだと、組み込みのサンドボックスプロキシは、どの権限モードでも接続を拒否します。bypassPermissions モードでは、どちらかがオンでないかぎり、許可ドメイン外のホストが許可されます。そのモードでコマンドがサンドボックスを出られるのはいつかは、「サンドボックス外での再試行(逃げ道)」にあります。deniedDomains のホストへの接続も、どの権限モードでも拒否されます。
ローカルアドレスに解決されるホスト名#
ホスト名が許可リストを通ったあと、サンドボックスのプロキシは名前を解決し、ローカルのアドレスにだけ解決されるなら接続を拒否します。ローカルのアドレスは、127.0.0.1 のようなループバック・169.254.169.254 のクラウドメタデータのエンドポイントのようなリンクローカル・自分のマシンに割り当てられたアドレスです。localhost と *.localhost は、ループバックへの解決が許されます。
10.0.0.0/8 のようなプライベートの範囲に解決される、許可したイントラネットのホスト名は接続できます。拒否されるアドレスへ名前を解決させるには、そのアドレスを allowedDomains に足します("127.0.0.1:8080" など)。
この検査はホスト名に適用されます。IP アドレスへの接続は、許可ドメインと権限モードで決まります。プロキシが上流の社内プロキシ経由で送る接続では、名前を解決するのがそのプロキシなので、この検査も省かれます。
auto mode のコマンドごとの許可ドメイン#
サンドボックスをオンにした auto mode では、Claude は接続ごとのネットワーク承認を起こす代わりに、コマンドが必要とするホストをコマンド自体に名指しします。サンドボックスで動く各 Bash・PowerShell・Monitor のコマンドは、サンドボックスの許可リストを超えるホストのリストを持てます。ドメイン(registry.npmjs.org)・ワイルドカード(*.pythonhosted.org)・IP アドレスで、それぞれ任意の :port 付きです。分類器がホストをコマンドと一緒に審査します。v2.1.271 以降が必要です。
- 承認されたリストは、そのコマンドが動いているあいだ、そのコマンドだけにホストを開く。セッションの許可ホストにも設定にも何も足されず、次のコマンドは自分のホストを名指しする
- ホストを持つコマンドは、権限ルールやサンドボックスの自動許可モードでなく分類器に回る。ask ルールが確認を強制するなら、端末の権限ダイアログがコマンドの横にホストを一覧し、そこで承認すれば両方を覆う
- コマンドごとのリストが広げるのは、サンドボックスが既定で拒否するものだけ。
deniedDomainsの項目は引き続きブロックする。strictAllowlistやallowManagedDomainsOnlyが許可リストをロックしていると、Claude Code はコマンドごとのリストを拒否する - コマンドごとのリストが適用されるあいだ、承認されたコマンドのどれも挙げていないホストへの接続は、確認や分類器の検査なしで拒否される。拒否はコマンドの結果にホストを名指しして出て、Claude はそのホストを足してコマンドを再実行する
ドメインリストの IPv6 アドレス#
allowedDomains・deniedDomains・WebFetch(domain:...) のルールで IPv6 アドレスに一致させるには、アドレスを角括弧で囲みます。"[::1]" はそのアドレスのすべてのポート、"[::1]:443" は 443 番ポートだけに一致します。角括弧の形は v2.1.229 以降が必要です。
角括弧のない ::1:443 のような項目は、アドレスとも、アドレスとポートとも読めるので曖昧です。
- deny のリスト:項目が解釈できるすべての読みを拒否し、意図した読みがどちらでもブロックされる。解釈できる読みがない項目は何もブロックしない
- allow のリスト:書かれたより多くは許可しない。曖昧な項目は、ホストとポートの読みが問題なく解析できるときそれに書き換え、許可リストを広げるよりも項目を完全に捨てることがある
曖昧な項目を探すには、ターミナルで claude doctor を実行し、Sandbox network domain entries have unreliable spellings の警告を見ます。曖昧な項目は、角括弧の形に書き直します。
OS レベルの強制#
- macOS:Seatbelt
- Linux:bubblewrap
- WSL2:Linux と同じく bubblewrap
@anthropic-ai/sandbox-runtimeパッケージを単独で動かして、Claude Code のプロセスを包むこともできる(後半の「サンドボックスランタイム」を参照)
権限・権限モードとの関係#
サンドボックス・権限ルール・権限モードは、補い合う層です。
- 権限ルールは、Claude Code が使えるツールを制御し、どのツールが動く前にも評価される。Bash・Read・Edit・WebFetch・MCP などすべてのツールに適用される(ほかのツールが残っているあいだ
EndConversationを deny/ask でブロックできない点を除く) - サンドボックスは、シェルコマンドがファイルシステムとネットワークで何にアクセスできるかを OS レベルで制限する。Bash・PowerShell・Monitor のコマンドとその子プロセスにだけ適用される
- 強制の仕方も違う。権限の判断は、コマンドが動く前に、コマンドの文字列と(auto mode では)安全かどうかの別の分類器の判断で行われる。サンドボックスの境界は、OS が動いているプロセスに強制するので、モデルが何を実行したかや、許可されたコマンドが名前以上のことをしても、保たれる
ファイルシステムとネットワークの制限は、サンドボックス設定と権限ルールの両方で設定されます。
| 設定やルール | 動き |
|---|---|
sandbox.filesystem.allowWrite |
作業ディレクトリの外のパスへの、サブプロセスの書き込みを許す |
sandbox.filesystem.denyWrite・denyRead |
特定のパスへのサブプロセスのアクセスをブロックする |
sandbox.filesystem.allowRead |
denyRead の領域の中の特定のパスの読み取りを開き直す |
sandbox.filesystem.disabled |
ネットワークの隔離は保ったまま、ファイルシステム層を完全にオフにする |
Edit の allow ルール |
sandbox.filesystem.allowWrite と同じく、特定のパスへの書き込みを許す |
Read・Edit の deny ルール |
特定のファイルやディレクトリへのアクセスをブロックする |
WebFetch(domain:...) の allow・deny ルール |
ドメインのアクセスを制御する |
サンドボックスの allowedDomains |
Bash コマンドが届くドメインを制御する |
サンドボックスの deniedDomains |
広い allowedDomains のワイルドカードが許すはずのドメインも、特定してブロックする |
サンドボックス設定と権限ルールのパスとドメインは、最終的なサンドボックス設定にマージされます。
権限モードとの違い#
/sandbox は権限モードではありません。権限モードはツール呼び出しが動くか、先に確認するかを決め、サンドボックスは Bash コマンドが動いたあとにアクセスできるものを制限します。
| 制御するもの | 確認の代わりになるもの | |
|---|---|---|
/sandbox |
動いた Bash コマンドがアクセスできるもの | 自動許可モードでは、サンドボックスの境界そのもの |
| auto mode | 各ツール呼び出しが動くか | アクションを審査する分類器 |
--dangerously-skip-permissions |
各ツール呼び出しが動くか | なし(保護されたパスの検査も省かれる。どのモードも自動承認しないアクションは引き続き適用) |
サンドボックスの自動許可モードは auto mode とは別です。自動許可は、サンドボックスの境界が封じ込めるので Bash コマンドを承認し、auto mode は分類器でアクションを審査します。両者は独立に動き、「サンドボックスのモード」に挙げた例外を除いて組み合わせられます。無人の実行の隔離境界の選び方は、後半の「隔離と権限モードの関係」にあります。権限モードとサンドボックスのよくある組み合わせと、それぞれを始めるフラグは、権限モード の「Common setups」の表を見てください。
組織向けの設定#
管理者は、全ユーザーにサンドボックスを必須にし、開発者がポリシーを広げるのを防ぎ、サンドボックスのトラフィックを社内プロキシへ通せます。
管理設定でサンドボックスを強制する#
全開発者にサンドボックスを必須にするには、MDM が管理するファイル、または claude.ai のサーバー管理設定で、sandbox のキーを配ります。次の管理設定は、サンドボックスを有効にし、プラットフォームが非対応か依存が無いと Claude Code の起動を拒否し、モデルがサンドボックスの外でコマンドを再試行するのを防ぎます。
{
"sandbox": {
"enabled": true,
"failIfUnavailable": true,
"allowUnsandboxedCommands": false
}
}
-
failIfUnavailable:Linux の bubblewrap などの依存が無いとき、サンドボックスなしで動かさず、Claude Code の起動をブロックする -
allowUnsandboxedCommands: false:dangerouslyDisableSandboxの逃げ道を無視する。コマンドがサンドボックスで失敗しても、Claude はサンドボックスの外で再試行できない併せて次も検討します。 -
組織が承認した、隔離なしで動かす必要のあるツールのための
excludedCommandsを足す。この設定は、リポジトリの設定がコマンドをサンドボックスから出すのを止めるため -
~/.awsや~/.sshなどの認証情報のディレクトリと、秘密の環境変数のためのsandbox.credentialsの項目を足す(既定の読み取りのポリシーが読めるままにするため)
この設定は、Claude が実行するコマンドをサンドボックスに入れます。開発者は ! のシェルモードのプロンプトにコマンドを打って、Claude Code の外のどの端末でも持つのと同じアクセスで、サンドボックスの外で動かせます。打ったコマンドがサンドボックス内で動くセッションは、「厳格なサンドボックスモードで再試行を止める」にあります。
サンドボックスはネイティブ Windows では動かないので、failIfUnavailable を設定すると、それらのマシンでは Claude Code が起動時に終了します。Windows のホストが混じるなら、次の方法があります。
- OS ごとに設定を配る:MDM か管理設定ファイルで、macOS と Linux のマシンにだけ配る。サーバー管理設定は、組織のすべてのユーザーに適用される
- Windows のユーザーを対応する環境に移す:WSL2 かコンテナの中で Claude Code を動かしてもらう
開発者がポリシーを広げるのを防ぐ#
管理設定が enabled や failIfUnavailable などの Boolean のキーを設定すると、Claude Code は管理設定の値を使い、開発者がローカルに設定したものを無視します。allowRead などの配列のキーでは、セッションが読み込むスコープの項目を結合するので、そのキーを覆うロックがなければ、開発者はポリシーを広げる項目を足せます。
管理設定が設定していなければ、開発者のユーザー設定か --settings が、次のキーをオンにできます。サンドボックスが admin-required でなければ、リポジトリの .claude/settings.json もオンにできます。どれもサンドボックスを弱めるので、使わせたくなければ管理設定で false にします。
enableWeakerNestedSandboxenableWeakerNetworkIsolationnetwork.allowAllUnixSocketsnetwork.allowLocalBindingallowAppleEvents(リポジトリはオンにできない)
管理設定で allowManagedReadPathsOnly を true にすると、管理設定の allowRead の項目だけが有効になり、開発者が組織の承認したパスを超えて読み取りを広げられなくなります。
ネットワークのドメインを同じく管理値に固定するには、allowManagedDomainsOnly を設定します。ロックがオンのあいだ、プロキシのポートを設定できるのは管理設定だけです(「カスタムプロキシの設定」)。
管理設定が sandbox.filesystem を設定する、または "mode": "deny" の sandbox.credentials.files の項目を挙げると、管理設定だけが filesystem.disabled を設定できます(管理者が配ったファイルシステムの制限を開発者が外せないように)。有効な mask の項目はこのキーを固定しません(「ファイルシステムの隔離を無効にする」の「どの設定元がオフにできるか」)。
admin-required のサンドボックスでのリポジトリ設定#
次のどれかの設定が効いているあいだ、サンドボックスは admin-required です。
- 管理設定で
allowUnsandboxedCommandsをfalseにしている、または--settingsフラグでfalseにしている(管理設定がtrueにしている場合を除く) - 管理設定で
allowManagedDomainsOnlyをtrueにしている
これらの設定はサンドボックスをオンにしないので、enabled も設定します。
サンドボックスが admin-required のあいだ、Claude Code は、サンドボックスを緩める設定を、管理設定・--settings フラグ・各開発者の ~/.claude/settings.json からだけ受け付けます。リポジトリの .claude/settings.json と .claude/settings.local.json にある次の設定は無視します。
| リポジトリの設定 | Claude Code が無視するもの |
|---|---|
excludedCommands・ignoreViolations・network.allowedDomains・network.allowUnixSockets・network.allowMachLookup・network.httpProxyPort・network.socksProxyPort |
すべての項目 |
filesystem.allowWrite・Edit(...) の allow ルール・permissions.additionalDirectories |
各項目がサンドボックス内のコマンドに与える書き込みアクセス。Claude のファイルツールは Edit(...) のルールと追加ディレクトリに従い続ける |
WebFetch(domain:...) の allow ルール |
各ルールがサンドボックスの許可リストに足すホスト。WebFetch ツールはそのルールに従い続ける |
enableWeakerNestedSandbox・enableWeakerNetworkIsolation・network.allowAllUnixSockets・network.allowLocalBinding |
true。false は引き続き効く |
enabled・failIfUnavailable |
開発者の ~/.claude/settings.json が true のときの false |
filesystem.allowRead |
管理設定・--settings・ユーザー設定が読み取りを拒否したパスの、そのパスかその下の項目と、それに一致しうる glob |
サンドボックスが admin-required のあいだも、次の設定は引き続き適用されます。
- リポジトリのファイル内:deny の項目と
autoAllowBashIfSandboxedの値。リポジトリに変えさせないなら、管理設定でそのキーを設定する - 開発者自身の設定内:表の設定は、
allowManagedDomainsOnlyのような管理設定のみのロックが覆わないかぎり、~/.claude/settings.jsonか--settingsから引き続き適用される。excludedCommandsやfilesystem.allowWriteなど、ほとんどには管理設定のみのロックがない
「管理設定でサンドボックスを強制する」の設定は、サンドボックスを admin-required にします。承認したツールが必要とする excludedCommands・allowWrite・ソケットの項目は、リポジトリが与えられないので、管理設定に足します。
v2.1.285 以降が必要です。v2.1.282 から v2.1.284 では、同じ設定で Claude Code がリポジトリの excludedCommands の項目を無視しました。
admin-required でなくても効くロック#
サンドボックスが admin-required でなくても、一部の設定は、1 つの制限を直接上書きするリポジトリのキーを Claude Code に無視させます。それぞれが効くのは、行に書かれたファイルで設定したときだけで、リポジトリのほかのサンドボックス設定は引き続き適用されます。v2.1.285 以降が必要です。
| 設定 | 設定する場所 | Claude Code がリポジトリの設定で無視するもの |
|---|---|---|
network.deniedDomains か WebFetch(domain:...) の deny ルール |
管理設定・--settings |
httpProxyPort と socksProxyPort |
network.strictAllowlist |
管理設定・--settings・ユーザー設定 |
プロキシのポート・allowedDomains・WebFetch(domain:...) の allow ルール |
filesystem.denyRead・Read(...) の deny ルール・credentials.files の項目 |
管理設定・--settings |
管理設定・--settings・ユーザー設定が読み取りを拒否したパスの、そのパスかその下の allowRead・allowWrite・Edit(...) の allow・additionalDirectories の項目と、それに一致しうる glob |
これらのロックが変えるのは、サンドボックス内のコマンドが届くものです。WebFetch ツールと Claude のファイルツールは、リポジトリのルールと追加ディレクトリに従い続けます。
カスタムプロキシの設定#
自分のツールでサンドボックスのトラフィックを検査・フィルタリング・ログに残すには、組み込みのサンドボックスプロキシを、同じマシンで動かす自分のプロキシに置き換えます。
ネットワーク上の別の場所にある社内プロキシへサンドボックスのトラフィックを通すには、代わりに HTTPS_PROXY を設定します(「ネットワークの隔離」の「社内プロキシ」の項目)。そうすれば Claude Code の許可リストが引き続き適用されます。
サンドボックス内のコマンドを自分のプロキシへ向けるには、プロキシが待ち受けるローカルホストのポートをサンドボックス設定で指定します。
{
"sandbox": {
"network": {
"httpProxyPort": 8080,
"socksProxyPort": 8081
}
}
}
ポートを設定したうえで HTTPS_PROXY や HTTP_PROXY も設定すると、Claude Code は、サンドボックス内のコマンドが自分のプロキシへ送ったものを、それらの変数が指すプロキシへ転送しません。社内プロキシへ届けるには、自分のプロキシをそこへ転送するよう設定します。
ポートを設定できるファイルは、ほかのサンドボックス設定で決まります。最初に当てはまるものが適用されます。
allowManagedDomainsOnlyがオン:管理設定だけ- サンドボックスが admin-required、または、より狭いネットワークのロックが効いている:管理設定・
--settings・ユーザー設定 - それ以外:どの設定ファイルでも
ほかの場所で設定したポートは、Claude Code が無視します。v2.1.285 より前は、どの設定ファイルでもポートを設定できました。
注意
どちらかのポートが適用されると、自分のプロキシに送られるものすべてのフィルタリングが、そのプロキシの責任になります。allowedDomains・deniedDomains・strictAllowlist・承認の確認・ローカルアドレスの検査など、Claude Code 自身のネットワーク制御は、そのトラフィックには適用されなくなります。サンドボックス内のコマンドはどちらのプロキシにも接続できるので、ポートを 1 つだけ設定すると、もう一方のプロキシへの Claude Code のドメインリストは、自分のプロキシ経由でコマンドが届くものを制限しません。
トラブルシューティング#
サンドボックスの外では動くのに、中では失敗するコマンドがあります。症状かエラーメッセージに合う見出しを探してください。
組織のサンドボックスが admin-required なら、Claude Code はプロジェクトの設定ファイルにある、これらの対処が挙げる設定を無視するので、全プロジェクトで有効になる ~/.claude/settings.json に保存します。それでも効かないなら、組織の管理設定がそのキーを設定しているかもしれません。
excludedCommands のパターンを足す対処は、そのパターンに一致するコマンドからサンドボックスを外します(除外されたコマンドにできること:「excludedCommands でコマンドをサンドボックスの外で動かす」)。
ホストが許可されていないエラーでコマンドが失敗する#
多くの CLI ツールが特定のホストへ届く必要があります。確認が出たらホストを承認するか、allowedDomains に足します。組織が allowManagedDomainsOnly で許可リストをロックしていると確認は出ないので、管理者にホストを足してもらいます。
jest が固まる・失敗する#
watchman はサンドボックスと互換性がありません。代わりに jest --no-watchman を実行します。
macOS で Go 製の CLI が TLS の検証に失敗する#
gh・gcloud・terraform などが、Seatbelt の下で TLS の検証に失敗することがあります。これらのツールをサンドボックスの外で動かすには、gh * のようなパターンをツールごとに excludedCommands に足します。そのツールは自分の全アクセスと保存された認証情報で動きます。httpProxyPort で MITM プロキシとカスタム CA を使っているなら、代わりに enableWeakerNetworkIsolation を true にします。
macOS で open・osascript・ブラウザでの認証フローがエラー -600 で失敗する#
サンドボックスは既定で Apple Events をブロックします。ユーザー・管理・CLI の設定で allowAppleEvents を true にすると許せます。プロジェクト設定では、Claude Code はこのキーを無視します。
allowAppleEvents を有効にするとコード実行の隔離が外れます。サンドボックス内のコマンドが、ユーザーへの確認なしで他のアプリをサンドボックスの外で起動でき、動いているアプリに AppleScript のコマンドを送れるからです(macOS の自動化の同意確認(TCC)は引き続き働きます)。代わりに、open * のようなパターンを excludedCommands に足してもかまいません。その場合、open の呼び出しは権限の流れを通りますが、open は Claude が書いたものを含め、どのファイルやアプリも起動できます。
docker コマンドが失敗する#
docker はサンドボックスと互換性がありません。必要な docker コマンドは、docker compose * のような excludedCommands のパターンでサンドボックスから出します。除外された docker コマンドが届くものは「excludedCommands でコマンドをサンドボックスの外で動かす」にあります。パターンが狭いほど、サンドボックスから出るコマンドは少なくなります。
pbcopy・xclip・wl-copy がクリップボードを更新しない#
pbcopy・xclip・wl-copy のクリップボードのユーティリティは、サンドボックスの中からシステムのクリップボードに届かないことがあり、パイプしたテキストが届きません。
Claude の出力をクリップボードに置くには、Claude に応答に出力してもらい、/copy を実行します。/copy は、サンドボックス内のコマンドでなく Claude Code のプロセスからクリップボードに書きます。
Claude がこれらのツールにテキストをパイプするとき、そのツールを excludedCommands に足すだけでは、その呼び出しはサンドボックスの外に出ません。
git のコマンドが unable to unlink old で失敗する#
git merge・git checkout などは、サンドボックスが書き込みを拒否するファイルを置き換える必要があるとき、unable to unlink old で失敗します。Linux・WSL2 ではエラーが Read-only file system で終わります。ファイルは次のどれかにあります。
.claude/skillsなどの保護されたパスの下- 自分の
denyWriteの項目の下 - サンドボックスがコマンドに書かせるディレクトリの外
失敗の後、Claude がサンドボックスの外での再実行を提案することがあります。その再試行を承認するか、別の端末で自分で git コマンドを実行します。allowUnsandboxedCommands を false にしていると、Claude は再試行を提案できないので、自分で実行します。
コンテナの中で bubblewrap が起動しない#
権限のないコンテナでは、bubblewrap が新しい /proc ファイルシステムをマウントできず、サンドボックス内のコマンドが Can't mount proc on /newroot/proc: Operation not permitted のような bwrap エラーで失敗します。enableWeakerNestedSandbox を true にすると、サンドボックスがコンテナの既存の /proc を bind マウントします。外側のコンテナがすでに必要な隔離の境界を与えているときだけ使います(新しい /proc のマウントなら隠れるプロセス情報が、サンドボックス内のコマンドに見えるため)。
.claude の設定パスに 0 バイトの読み取り専用ファイルが現れ、「Yes, and don't ask again」が保存されない#
Linux・WSL2 では、サンドボックスは、まだ無いファイルへの書き込み拒否を、サンドボックス内のコマンドの実行中に 0 バイトの読み取り専用のプレースホルダーを作って保ち、あとで消します。そのクリーンアップの前にセッションが終了させられる(SIGKILL など)とプレースホルダーが残り、後のセッションが起動のたびにそれを読み取り専用で bind するので、権限の選択の保存など設定の書き込みが、プレースホルダーの残るパスで失敗します。
ターミナルで claude doctor を実行すると、残ったプレースホルダーが一覧されます。Stale sandbox mask files left by a killed session の警告がいくつかを挙げ、残りを数えます。そのプロジェクトで他の Claude Code セッションが動いていないときに、各ファイルを rm で消します。v2.1.257 より前は、同じプレースホルダーが警告なしで残りました。
サンドボックスをオンにすると SSH 経由の git が失敗する#
macOS では、SSH のリモートへの git fetch・git pull・git push が、ホストが許可されていてもサンドボックス内で失敗します。Linux・WSL2 では、ホストが許可されれば動きます。Claude Code は git の SSH 接続をサンドボックスのプロキシ経由でトンネルしますが、macOS のトンネルはそのプロキシに認証できないためです。
Linux・WSL2 で、それでも接続できないときは、次を確認します。
- ホストがポート 22 で許可されている:
"git.example.com"のようなポートの無いallowedDomainsの項目が覆う - 社内プロキシがポート 22 を許している:ネットワークが上流のプロキシを要求するなら、トンネルもそこを通る
- 鍵がファイルとして読める:サンドボックスが
ssh-agentのソケットをブロックすることがあり、~/.sshへのdenyReadやcredentialsの項目は鍵ファイルを隠す
macOS では、リモートを HTTPS に切り替えます。個人アクセストークンなど HTTPS の認証情報が要ります。
git remote set-url origin https://git.example.com/example-org/example-repo.git
SSH のリモートを保つ必要があるなら、excludedCommands で git のネットワークコマンドをサンドボックスから出します。
{
"sandbox": {
"excludedCommands": ["git fetch *", "git pull *", "git push *"]
}
}
これらの項目は git push origin main に一致します。cd を足す・git -C を使う・コマンド置換を含む呼び出しは、サンドボックス内にとどまります。除外された git コマンドは、allowedDomains のホストだけでなく、どのホストにも届きます。
素の ssh・scp・SSH 経由の rsync が失敗する理由は、次の「データベースクライアントなど」の項目にあります。
データベースクライアントなど HTTP 以外のツールが、許可したホストに届かない#
プロキシの環境変数を無視するツールは、allowedDomains のホストにも、サンドボックスの中から接続できません。サンドボックス内のコマンドにはネットワークへの直接の経路が無いので、自分で接続を開くツールは失敗します。多くのデータベースドライバー・素の ssh・UDP を使うツールがこれに当たります。
失敗は、ネットワークか名前解決のエラーに見えます。
- macOS:
Operation not permitted、またはCould not resolve hostのような名前解決のエラー - Linux・WSL2:
Network is unreachable、またはTemporary failure in name resolutionのような名前解決のエラー
プロキシを使うツールは、ホストが許可されていないときの失敗のしかたが違います。ネットワークの確認が出るか、ツールがプロキシから 403 の応答を受け取ります。
ツールが接続できるようにするには、それが必要なコマンドを excludedCommands でサンドボックスの外で動かします。次の例は 1 つのスクリプトを除外し、実行のたびに承認するための ask ルールを足します。
{
"sandbox": {
"excludedCommands": ["python scripts/load_orders.py *"]
},
"permissions": {
"ask": ["Bash(python scripts/load_orders.py *)"]
}
}
スクリプトは自分の全アクセスで動き、Claude は作業ディレクトリ内のスクリプトを編集できるので、確認が出たときに中身を見直します。
localhost のサーバーにコマンドが届かない#
既定では、サンドボックス内のコマンドは、サンドボックスの外の自分のマシンで動くサーバー(開発サーバーやコンテナ内のデータベースなど)に直接接続できません。変えられるものはプラットフォームで違います。
- macOS:
network.allowLocalBindingをtrueにする。サンドボックス内のコマンドがネットワークポートで待ち受けられ、localhost の任意のポートに接続できるようになるが、そこで待ち受けるほかのサービスもすべて含まれる。デバッガーのように認証を要しない localhost のサービスは、サンドボックスの外でコマンドの代わりに動けてしまい、ループバック以外のアドレスで待ち受けるコマンドは、ほかのマシンからの接続を受け付ける - Linux・WSL2:サンドボックス内のコマンドの
localhostは、そのコマンドの中だけのもの。コマンドはポートで待ち受けられ、自分で起動したサーバーには届くが、localhostや127.0.0.1への直接の接続はホストのサーバーに届かず、allowLocalBindingは効かない。ホストのサーバーが要るコマンドは、excludedCommandsでサンドボックスの外で動かす(ファイルシステムとネットワークの制限が無くなる)。サンドボックスのプロキシを通る接続は、「ローカルアドレスに解決されるホスト名」を参照
次の例は、macOS でこの設定をオンにします。
{
"sandbox": {
"network": {
"allowLocalBinding": true
}
}
}
localhost の allowedDomains の項目は、プロキシを通る接続に適用されるので、直接の接続は変わりません。Claude Code は、サンドボックス内のコマンドがプロキシ経由でなく localhost に直接接続するよう、NO_PROXY を設定します。この項目は、プロキシを使うコマンドに、自分のマシンの localhost のすべてのポートも露出します。127.0.0.1 を指す開発用のホスト名は、次の項目を参照してください。
許可したホスト名が resolved to a loopback address で拒否される#
サンドボックスのプロキシは、ローカルのアドレスに解決される、許可したホスト名を拒否します。127.0.0.1 を指す myapp.test のような開発用の名前が該当します。コマンドは、アドレスの種類を示す Connection to myapp.test blocked: resolved to a loopback address のような本文の 403 応答を見ます。
名前が解決される IP アドレスを、ホスト名と並べて allowedDomains に足します。それぞれにサーバーが待ち受けるポートを付けます。
{
"sandbox": {
"network": {
"allowedDomains": ["myapp.test:3000", "127.0.0.1:3000"]
}
}
}
ポートの無い IP アドレスの項目は、そのアドレスで待ち受けるすべてのサービスに、サンドボックス内のコマンドが届くようにします。
v2.1.284 より前は、プロキシは、許可したホスト名が解決されたどのアドレスにも接続しました。
/sandbox が Sandbox settings are overridden by a higher-priority configuration で失敗する#
より優先度の高い設定レベルが sandbox.enabled・sandbox.autoAllowBashIfSandboxed・sandbox.allowUnsandboxedCommands を設定していると、/sandbox はパネルを開かず、Error: Sandbox settings are overridden by a higher-priority configuration and cannot be changed locally. と出ます。パネルは選択を .claude/settings.local.json に保存し、そこに保存した値は、それらのレベルを上書きできないためです。
管理設定と --settings は、ローカル設定より上位です。このセッションがどれを読み込んだかは、/status を実行して Setting sources の行を見ます。
Command line arguments:--settingsで起動したなら、渡したファイルか JSON がそれらのキーを設定していないか確かめる。していれば、そこで値を変えるか、それらのキーを外して Claude Code を起動し直すEnterprise managed settings:組織の管理設定が読み込まれている。それらのキーを設定しているなら、/sandboxからも自分で扱える設定ファイルからも、そのキーは変えられないので、管理者に頼む
限界#
サンドボックスはリスクを減らしますが、完全な隔離境界ではありません。ハードなセキュリティ制御として頼る前に、次の限界を確認してください。
セキュリティ上の限界#
- ネットワークのフィルタリング:サンドボックスはプロセスが接続できるドメインを制限する。組み込みのプロキシは、既定では外向きの TLS を終端も検査もしないので、暗号化された接続の中身は調べられない。実験的な
network.tlsTerminateはmaskの認証情報の置換のためにプロキシで TLS を終端するが、内容のフィルタリングは加えない。許可するドメインが信頼できるものだけであることは、自分の責任
注意
github.com のような広いドメインを許可すると、データの持ち出しの経路になりえます。プロキシは、TLS を検査せず、クライアントが示すホスト名から許可を決めるので、サンドボックス内で動くコードが、ドメインフロンティングなどの手法で許可リストの外のホストへ届く可能性があります。より強い保証が要る脅威モデルなら、TLS を終端してトラフィックを検査するカスタムプロキシを設定し、その CA 証明書をサンドボックス内にインストールします。TLS を理解するより強いネットワーク隔離は、開発が進められている領域です。
- Unix ソケット経由の権限昇格:
allowUnixSocketsの設定は、サンドボックスの回避につながるシステムサービスへのアクセスを意図せず与えうる。例えば/var/run/docker.sockへのアクセスを許すと、Docker のソケット経由でホストシステムへのアクセスを与えることになる。サンドボックスを通す Unix ソケットは慎重に検討する - ファイルシステムの権限昇格:広すぎる書き込み権限は、権限昇格の攻撃を可能にしうる。
$PATHの実行ファイルのあるディレクトリ・システムの設定ディレクトリ・.bashrcや.zshrcなどのユーザーのシェル設定ファイルへの書き込みを許すと、ほかのユーザーやシステムのプロセスがそれらにアクセスするとき、別のセキュリティコンテキストでコードが実行されうる - Linux のサンドボックスの強さ:Linux の実装は強いファイルシステムとネットワークの隔離を提供するが、特権のない名前空間なしで Docker の環境内で動かすための
enableWeakerNestedSandboxモードがある。このオプションはセキュリティをかなり弱めるので、ほかの隔離が別に強制されているときだけ使う - macOS の Apple Events:macOS のサンドボックスは既定で Apple Events をブロックする。
allowAppleEventsはこの制限を外してopenやosascriptなどを動かすが、コード実行の隔離を外す。サンドボックス内のコマンドが、ユーザーへの確認なしで他のアプリをサンドボックスの外で起動でき、動いているアプリに AppleScript のコマンドを送れる(アプリごとの macOS の自動化の同意確認(TCC)は働く)。ユーザー・管理・CLI の設定からだけ有効で、プロジェクト設定では有効にできない
対象範囲#
サンドボックスが隔離するのは、シェルコマンドとその子プロセスです。サンドボックスが覆わないツールと補助プロセスは、「サンドボックスの外で動くもの」に挙げています。コンピューター操作・サブエージェント・Mod は、サンドボックスと次のように関わります。
- コンピューター操作:Claude がアプリを開いて画面を操作するとき、隔離された環境でなく実際のデスクトップで動く。アプリごとの権限の確認が各アプリを制御する
- サブエージェント:サブエージェントは親セッションと同じプロセスで動き、同じサンドボックス設定を使う。親セッションでサンドボックスが有効なら、サブエージェント内の Bash コマンドもサンドボックス内で動く
- Mod:Mod(モッド)は、Claude Code の中で自分のコードを動かすプラグインで、Mod が起動するプロセスはサンドボックスの外で動く。詳しくは Mod(モッド)を使う を参照
注意
有効なサンドボックスには、ファイルシステムとネットワークの両方の隔離が要ります。ネットワークの隔離がないと、侵害されたエージェントが SSH 鍵などの機密ファイルを持ち出せます。ファイルシステムの隔離がない(緩いポリシーや、ファイルシステム層のオフのため)と、侵害されたエージェントがシステムのリソースにバックドアを仕込んで、ネットワークへのアクセスを得られます。既定を広げるときは、allowWrite のパス・広い allowedDomains の項目・excludedCommands の例外が、反対側の制限を打ち消さないか確かめます。
サンドボックス環境の選び方#
隔離は、セッションが読める・書ける・ネットワークで届くものを制限します。権限確認を減らして Claude に作業させるとき、無人で動かすとき、完全には信頼できないコードを扱うときに特に重要です。Claude Code は、コマンドごとの軽いサンドボックスから、完全に別の仮想マシンまで、いくつかの隔離された環境で動かせます。
| 方法 | 隔離されるもの | Docker が要るか | 準備の手間 |
|---|---|---|---|
| サンドボックス内の Bash ツール | Bash・PowerShell・Monitor のコマンドとその子プロセス | 不要 | macOS では最小、Linux・WSL2 では小 |
| サンドボックスランタイム(sandbox runtime) | Claude Code のプロセス全体(ファイルツール・MCP サーバー・フックを含む) | 不要 | 小 |
| 開発コンテナ(dev container) | 開発環境全体 | 必要 | 中 |
| カスタムコンテナ | 開発環境全体 | 必要 | 中〜大 |
| 仮想マシン | OS 全体 | 不要 | 大 |
| クラウドセッション | Anthropic がホストする OS 全体 | 不要 | なし(Claude のサブスクリプションが必要。claude --cloud で起動しないかぎり GitHub アカウントの接続も必要) |
- 最初の 2 つは、コンテナなしでホストの OS で動く。残りは Claude Code をコンテナか仮想マシンの中に置く
- サンドボックス内の Bash ツールだけが Claude Code に組み込まれ、Bash コマンドを制限する。組み込みのファイルツール・MCP サーバー・フックはホストで直接動く。表のほかの方法は、Claude Code のプロセス全体を隔離の境界の中に置くので、ファイルツール・MCP サーバー・フックも制限される
注意
サンドボックスの隔離は侵害の影響を減らしますが、リスクをなくしません。ネットワークの出口を許す方法は、エージェントが読めるデータを漏らしえ、プロジェクトのディレクトリを書き込み可能でマウントする方法は、そのコードを変更しえます。ハードな制御として頼る前に、セキュリティ上の限界を確認します。隔離は、モデルに送られるものも変えません。プロンプトと Claude が読むファイルは、サンドボックスの有無にかかわらず Anthropic の API か設定したプロバイダーに送られます。
目的から選ぶ#
| やりたいこと | 最初に試すもの |
|---|---|
| 自分のマシンでの日常作業の権限確認を減らす | /sandbox で設定するサンドボックス内の Bash ツール |
--dangerously-skip-permissions か auto mode で Claude を無人で動かす |
事前設定された開発コンテナ・任意のコンテナか VM・サンドボックスランタイム |
| Docker なしで、Bash に加えて MCP サーバーとフックも隔離する | サンドボックスランタイム |
| 信頼できないリポジトリで作業する | 専用の仮想マシン。Claude のサブスクリプションがあればクラウドセッション(claude --cloud で起動するなら GitHub は不要) |
| チームでサンドボックスの環境を標準化する | リポジトリにコピーした、事前設定の開発コンテナ |
| ローカルの準備なしのデバイスから Claude Code を使う | クラウドセッション(Claude のサブスクリプションと、接続した GitHub アカウントが必要) |
| 組織の全開発者に隔離を必須にする | 下の「組織全体で隔離を強制する」 |
| ネイティブ Windows のホストで作業する | コンテナか VM、または WSL2 の中で Bash サンドボックスを動かす |
隔離と権限モードの関係#
権限モードは、ツール呼び出しが動くか、先に確認するかを決めます。隔離は、コマンドが動いたあとにアクセスできるものを制限します。権限モードが確認なしでアクションを動かすとき、隔離の境界がそれらのアクションが届く範囲を限ります。
--dangerously-skip-permissionsでは、Claude は先に尋ねずに動く(どのモードも自動承認しないアクションは引き続き適用される)。ミスを捉える確認がないので、選んだ隔離の境界がシステムを守る。このセッションは必ず、コンテナ・VM・サンドボックスランタイムの中で動かし、ファイルツール・MCP サーバー・フックも境界の中に入れる。Linux と macOS では、root で動かすとこのフラグで起動を拒否されるので、コンテナ・VM・サンドボックスランタイムを非 root ユーザーで動かす- auto mode は、確認を、アクションを審査する分類器に置き換える。分類器はアクション単位の制御で、隔離の境界ではない。無人の実行では隔離の境界が多層防御になるが、
--dangerously-skip-permissionsのようには必須でない - サンドボックス内の Bash ツールだけではシェルコマンドしか制約しないので、どちらのモードでも、完全な無人の実行には足りない。方法は重ねられる(コンテナや VM の中でサンドボックス内の Bash ツールを動かすと、外側の環境の境界の上に、OS レベルのコマンド制限が加わる)
サンドボックス内の Bash ツール#
補足
ネイティブ Windows はサポートされません。Windows のホストでは、WSL2 か、下のコンテナ・VM の方法を使います。
Claude が実行するすべての Bash・PowerShell・Monitor コマンドのファイルシステムとネットワークのアクセスを、OS の仕組みで制限します。/sandbox でパネルを開いてモードを選びます。コマンドごとのサンドボックスは、セッションで動くすべてを覆うわけではありません。
- Read・Edit・WebFetch など、ほかの組み込みツールは Claude Code のプロセスの中で動き、任意のコードを起動しない。パスやドメインの権限ルールがそれらを制御する
- MCP サーバーとコマンドフックは、ホストで制約なしに動く別のプロセス
- 組み込みツール・MCP サーバー・フックを 1 つの OS の境界の後ろに置くには、Claude Code のプロセス全体を、サンドボックスランタイム・開発コンテナ・カスタムコンテナの中で動かす
サンドボックスランタイム#
@anthropic-ai/sandbox-runtime パッケージは、プロセス全体を、組み込みの Bash サンドボックスと同じ Seatbelt か bubblewrap の隔離で包みます。ランタイム経由で Claude Code を動かすと、シェルコマンドだけでなく、セッションのすべてのツール・フック・MCP サーバーが制約されます。ランタイムはベータの research preview で、設定の形式はパッケージの更新で変わることがあります。
準備と起動:
- Linux・WSL2 では、組み込みのサンドボックスと同じ
bubblewrapとsocatに加えてripgrepが要る(Claude Code は同梱するが、単体のランタイムは PATH から見つける)。macOS では追加のパッケージは不要(組み込みの Seatbelt を使う) - 既定では、ランタイムはネットワークアクセスを拒否し、書き込みを組み込みのいくつかのランタイムのパスに限るので、Claude Code を通す前に設定する。設定は
~/.srt-settings.jsonか、--settingsで渡すファイルに置く(設定の形式の全体はパッケージの README にある) - 書き込みを許す先は少なくとも、プロジェクトのディレクトリ、Claude Code の設定のパス
~/.claudeと~/.claude.json、Claude Code が実行時ファイルを書くディレクトリ(CLAUDE_CODE_TMPDIRを設定していなければ、Linux・WSL2 では/tmp、macOS では/private/tmp。/tmpはそこへのシンボリックリンクで、Seatbelt は解決後のパスを検査する) - 許すネットワークのドメインは、
api.anthropic.com(または設定したプロバイダーのエンドポイント。第三者プロバイダーでも、skipWebFetchPreflight: trueにしないかぎり WebFetch のドメイン安全性チェックが呼ぶのでapi.anthropic.comも残す)と、OAuth のサインインとトークン更新に必要なclaude.aiとplatform.claude.com(API キーで認証した実行ではこの 2 つを外せる) - Linux・WSL2 では、ランタイムは書き込みの許可を、すでに存在するパスにだけ適用する。新しい環境では、最初の起動の前に Claude Code の設定のパスを作る
mkdir -p ~/.claude && { [ -f ~/.claude.json ] || echo '{}' > ~/.claude.json; }
設定ファイルを置いたら、npx で起動し、包むコマンドとして claude を渡します。同じコマンドで、単体の MCP サーバーなどの補助プロセスも隔離できます。
npx @anthropic-ai/sandbox-runtime claude
ランタイムが設定なしでブロックするもの:
denyWriteがallowWriteより優先される- プロジェクトルートで、
.git/hooksを拒否し、filesystem.allowGitConfig: trueにしないかぎり.git/configを拒否し、.mcp.json・.claude/commands・.claude/agents・シェルの起動ファイルを拒否する - macOS では、これらの拒否は書き込みの時点で検査されるので、セッション中に作られた入れ子のファイルとリポジトリも覆う
- Linux・WSL2 では、ランタイムは起動時に一度だけ拒否リストを作る。プロジェクトルートは確実に覆い、その時点で存在する入れ子のコピーを浅くベストエフォートでスキャンするが、セッションが後で作るもの(
git init・git clone・スキャフォールディング)は覆わない(スキャンの正確な意味は README のmandatoryDenySearchDepthの節) ~/.srt-settings.jsonが無く--settingsも渡さないとき、ランタイムはそれでも起動し、ネットワークアクセスをブロックし、書き込みを/tmp/claude・~/.npm/_logs・~/.claude/debugなどの組み込みのランタイムのパスに限る。クリーンな起動を、設定が読み込まれた証拠と受け取らない- 設定ファイルがあるが空・読めない・無効のときは(
~/.srt-settings.jsonでも--settingsで渡したファイルでも)、起動を拒否する。--settingsのファイルが無い場合も起動を拒否する - 書き込みを許したパスには、Claude Code が設定を読み込むほかのパスも含まれうるので、
denyWriteで拒否する。それらを書けるサンドボックス内のセッションは、次に Claude Code を起動したとき、サンドボックスなしで動くフック・権限ルール・MCP サーバーを残せてしまう - 無人の実行のあと:書き込み可能のままにしたパスを見直す。Linux・WSL2 では、セッションが作ったものも見直す
開発コンテナ#
開発コンテナは、VS Code などの互換エディタが管理する Docker コンテナの中で、プロジェクトをマウントして Claude Code を動かします。リポジトリの .devcontainer/ ディレクトリで自分のものを定義できます。claude-code のリポジトリは、出口を既定で拒否する iptables のファイアウォール付きの例を公開しています。リポジトリにコピーして、ファイアウォールの許可リスト・ベースイメージ・固定する Claude Code のバージョンを環境に合わせて調整します。ファイアウォールが承認されていない外向き通信をブロックするので、この構成は、無人の作業で --dangerously-skip-permissions を付けて Claude Code を動かすことに向きます。詳しくは 開発コンテナ を見てください。
カスタムコンテナ#
自前のネットワークポリシー・マウントしたボリューム・seccomp プロファイルを持つ、任意の Docker か OCI のコンテナイメージで Claude Code を動かせます。既存のコンテナ基盤や CI ランナーを持つ組織で最も多い経路です。
- コンテナをホストするマネージドなサンドボックスやリモート実行のサービスもある。自分で運用するコンテナと同じチェックリストが当てはまる:書き込み可能でマウントされているもの、コンテナの中で届く認証情報とトークン、ネットワークの出口ポリシーが許すもの
- 組み込みの Bash サンドボックスを、コンテナの中に重ねてコマンドごとの制限を加えられる。権限のないコンテナには
enableWeakerNestedSandboxが要る(サンドボックスのトラブルシューティングの「コンテナの中で bubblewrap が起動しない」)
仮想マシン#
専用の仮想マシンは、自分のカーネル(クラウドや microVM では自分の仮想化されたハードウェア)を持ち、最も強い分離を与えます。クラウドのインスタンス・ローカルのハイパーバイザー・Firecracker などの microVM があります。信頼できないコードを評価するとき、セキュリティポリシーがエージェントとホストのあいだのカーネルレベルの分離を求めるとき、ホストレベルの方法ではコンプライアンスを満たせないときに使います。Docker Sandboxes は、自分の Docker デーモンとワークスペースの同期を持つ microVM で、Docker Sandboxes を入れた任意のホストで Claude Code を動かせます(Docker 社の無償の単体製品で、Docker Desktop は不要)。
クラウドセッション#
クラウドセッションは、Anthropic が管理する隔離された仮想マシンで動きます。ネットワークプロキシが既定の許可リストを強制し、別のプロキシが GitHub トークンをサンドボックスの外に保ち、サンドボックスの中のリポジトリアクセスにはスコープを絞った認証情報を発行します。組織が自前の環境に回すセッションは、自分で用意した基盤で動き、その隔離・出口の制御・git の認証情報は自分のデプロイの責任です。
- 基盤を用意せずに VM の完全な隔離が欲しいとき、またはローカルの開発環境がないデバイスからタスクを任せるときに使う。Claude のサブスクリプションが要る。CLI から起動するのでないかぎり、サンドボックスがリポジトリを clone できるよう、接続した GitHub アカウントも要る。CLI から
--cloudで起動すると、Claude Code がローカルのリポジトリをバンドルしてアップロードできる。詳しくは クラウド(Web)で使う を見る
組織全体で隔離を強制する#
開発者は、このページのどの方法も自分で選べます。組織が何をどのツールで強制できるかは、方法で変わります。
- 組み込みの Bash サンドボックス:Claude Code 自身が強制できる唯一の方法。MDM が管理するファイルか、Claude.ai のサーバー管理設定で、
sandboxの設定キーを配る。配るキーと、開発者がポリシーを広げるのを防ぐ方法は、上の「組織向けの設定」にある - 開発コンテナ:例の開発コンテナをリポジトリにコミットして、チームの環境を標準化する。Claude Code はコンテナを要求しないので、強制の境界でなく慣習。開発者が外で Claude Code を動かせないようにするには、組織のデバイス管理やソフトウェアの許可リストのツールで強制する
- カスタムコンテナと VM:承認したイメージで Claude Code を配り、組織のデバイス管理やソフトウェアの許可リストのツールで、その外へのインストールを防ぐ
関連ページ#
- セキュリティとデータの扱い:セキュリティの全体像
- 権限ルール:権限の設定とアクセス制御
- 設定キー一覧:サンドボックスの全設定キー
- 開発コンテナ:事前設定された Docker の開発コンテナ
- CLI のコマンドとフラグ:コマンドラインのオプション
- Agent SDK の本番運用:Agent SDK アプリケーションの隔離の指針
公式ドキュメント(英語)
2026年10月5日時点の内容をもとに、日本語でまとめています。