allowUnsandboxedCommandsは抜け道を管理設定で塞ぐ設定
サンドボックスが弾いたコマンドをClaudeがdangerouslyDisableSandboxで再試行する抜け道を、allowUnsandboxedCommandsで管理設定から塞ぐ方法と、それでも残る2つの穴を解説します。
Claude Codeのサンドボックスがコマンドをブロックしても、ClaudeはdangerouslyDisableSandboxパラメーターを付けて同じコマンドをサンドボックス外で再試行できます。これは標準の挙動です。sandbox.allowUnsandboxedCommandsをfalseにすると、この再試行そのものを無効化でき、/sandboxのOverridesタブは状態をStrict sandbox modeと表示します。ただしこの設定が塞ぐのはClaude自身が実行するコマンドの再試行だけです。開発者が自分で打つコマンドやexcludedCommandsに載せたツールは別扱いで、そこを知らずに「厳格モードにした」と思い込むと抜け道が残ります。
allowUnsandboxedCommandsは何を止める設定か
サンドボックスがコマンドをブロックすると、Claude Codeはブロックされたコマンドの実行結果に違反内容(拒否したパスやホスト)を記録し、Claudeに何が弾かれたかを伝えます。Claudeはその情報をもとに、タスクを失敗させる代わりにdangerouslyDisableSandboxパラメーターを付けて同じコマンドをサンドボックス外で再試行することがあります。公式ドキュメントはこれを「アンサンドボックス再試行の脱出口(escape hatch)」と呼んでいます。
sandbox.allowUnsandboxedCommandsはこの脱出口そのもののスイッチです。
true(既定値): サンドボックスがブロックした後、ClaudeはdangerouslyDisableSandboxで再試行できるfalse: Claude Codeはこのパラメーターを完全に無視する。以降Claudeが実行できるのは、サンドボックス化されたコマンドかexcludedCommandsに列挙済みのコマンドだけ
再試行がサンドボックス外で実行される以上、それは通常の権限フローに戻ります。つまりfalseにする前から、再試行は無条件で通っていたわけではありません。次の節で権限モードごとの違いを扱います。
管理設定でStrict sandbox modeを強制する
組織全体に強制したいときのmanaged settingsの構成は次の形です。
{
"sandbox": {
"enabled": true,
"failIfUnavailable": true,
"allowUnsandboxedCommands": false
}
}3つのキーはそれぞれ役割が違います。enabledはサンドボックス自体のスイッチで、これがtrueでなければ再試行という概念自体が発生しません(コマンドが最初からサンドボックス化されないため)。failIfUnavailableは、bubblewrapのような依存が欠けてサンドボックスを起動できない環境で、警告を出して非サンドボックス実行にフォールバックする既定動作を止め、Claude Codeの起動自体を失敗させます。allowUnsandboxedCommands: falseは、この2つが揃ってサンドボックスが実際に動いている前提のもとで、ブロック後の再試行だけを塞ぎます。
このキーのスコープは「Any file」、つまりユーザー設定・共有プロジェクト設定・プロジェクトのローカル設定のどこからでも書けます。ではプロジェクト側の.claude/settings.jsonでtrueに戻せば無効化できるかというと、そうはなりません。Claude CodeはBoolean型キーの値を、そのキーを設定している中で最も優先度の高いスコープから採用します。設定の優先順位は高い順にmanaged settings・コマンドラインの--settings・プロジェクトのローカル設定・共有プロジェクト設定・ユーザー設定で、managed settingsが最上位です。managed settingsでfalseにしておけば、開発者側の設定ファイルが何を書いていても無視されます。
公式ドキュメントはこの構成にもう1つ、sandbox.credentialsへの追記を勧めています。デフォルトのファイル読み取り許可は~/.awsや~/.sshのような認証情報ディレクトリも含んだままなので、再試行を塞いだだけでは認証情報の読み取りそのものは守られません。sandbox.credentialsではファイルパス・環境変数それぞれにmodeとしてdeny(遮断)かmask(値を隠したまま見せる)を指定できます。
もう1つ見落としやすいのが対応プラットフォームです。サンドボックスはネイティブのWindowsでは動作しません。Windows機を含む組織にこの構成を配布する場合は、対象をmacOSとLinuxに絞るか、Windows側のユーザーにはWSL2かコンテナの中でClaude Codeを実行してもらう必要があります。
厳格モードでも抜けられる2つの穴
allowUnsandboxedCommands: falseが塞ぐのは、Claudeが実行するコマンドの再試行だけです。公式ドキュメントは残る2つの経路を明記しています。
1つ目は!シェルモードです。開発者が自分で!プレフィックス付きのコマンドを入力した場合、そのコマンドは通常サンドボックスの対象外です。サンドボックスはあくまでClaudeが実行するコマンドに適用される仕組みで、開発者自身が打つコマンドには元から及びません。これが変わるのは次の2種類のセッションだけです。
| セッションの種類 | !シェルモードコマンドの扱い |
|---|---|
| 通常のセッション | !シェルモードコマンドの扱いサンドボックス化されない(従来どおり) |
| バックグラウンドセッション | !シェルモードコマンドの扱いStrict sandbox modeがシェルモードコマンドにも及ぶ |
CLAUDE_CODE_SUBPROCESS_ENV_SCRUBを設定したLinuxセッション | !シェルモードコマンドの扱いシェルモードコマンドを含め全実行がサンドボックス化される |
v2.1.260より前は、Strict sandbox modeが有効なあらゆるセッションでシェルモードコマンドもサンドボックス化されていました。現行バージョンでは対象がこの2種類のセッションに絞られています。管理設定で厳格化したつもりでも、通常セッションで開発者が!から打つコマンドは、Claude Code以外のターミナルで実行するのと同じアクセス権のまま残ります。
2つ目はexcludedCommandsです。docker *のようなパターンをここに登録すると、該当コマンドはサンドボックス化を免除されて通常の権限フローに回ります。各エントリの照合はBash(...)権限ルールと同じ構文で、完全一致・docker *のようなprefix・ワイルドカードパターンのいずれかを使えます。複合コマンドの一部でもエントリに一致すれば、そのコマンド全体がサンドボックス外で実行される点には注意が必要です。単純な文字列条件のゆるさが、そのまま抜け道の広さに直結します。この一覧には管理者専用ロックがありません。allowReadをallowManagedReadPathsOnlyでmanaged設定だけに縛ったり、許可ドメインをallowManagedDomainsOnlyで固定したりする仕組みは用意されていますが、excludedCommandsには同等のロックがなく、開発者は自分の設定ファイルにいつでもコマンドを追加してサンドボックスの外へ逃がせます。組織側でこの一覧を使うときは、管理設定のリストを狭く保つ運用自体が唯一の対策になります。
Manual modeとAuto modeで再試行の扱いが変わる
allowUnsandboxedCommandsを既定のtrueのままにしていても、再試行は無条件で通るわけではありません。サンドボックス外での実行は必ず通常の権限フローに戻るため、権限モードによって挙動が変わります。
Manual modeでは、再試行のたびに確認プロンプトが表示されます。Auto modeでは、プロンプトの代わりに分類器が再試行対象のコマンドそのものを評価します。たとえば許可リスト外のホストへ接続しようとしてブロックされた場合、Claudeはそのホスト名を根拠として再試行を提案し、Manual modeのユーザーはその根拠を見た上で許可するかどうかを判断できます。毎回の再試行を確認したい場合は、Bash(dangerouslyDisableSandbox:true)という入力パラメーター指定のaskルールを追加すると、Auto modeでも再試行のたびにプロンプトが出るようになります。permissions.blockReadsOutsideWorkingDirectoriesを有効にしている間は、作業ディレクトリ外への再試行にAuto modeでも確認が必要になります。
dangerouslyDisableSandboxとdisableBypassPermissionsModeは別物
「Claude Codeの安全装置を外させない」という目的で似た名前の設定を混同しやすい組み合わせがもう1つあります。permissions.disableBypassPermissionsModeです。
| 設定 | 塞ぐ対象 | 塞いだ後の状態 |
|---|---|---|
sandbox.allowUnsandboxedCommands: false | 塞ぐ対象サンドボックスがブロックしたコマンドの再試行(dangerouslyDisableSandbox) | 塞いだ後の状態Claudeが実行するコマンドはサンドボックス化されるかexcludedCommandsのみ |
permissions.disableBypassPermissionsMode: "disable" | 塞ぐ対象bypassPermissionsモードへの遷移(--dangerously-skip-permissions) | 塞いだ後の状態このフラグ自体をClaude Codeが拒否し、サブエージェント定義のpermissionMode: bypassPermissionsも無視される |
前者はサンドボックスという1つの防御層の中の脱出口を塞ぎ、後者はサンドボックスを含む権限確認そのものを丸ごと素通りさせるモードへの入口を塞ぎます。組織のポリシーとして両方を求めるなら、どちらか一方だけでは足りません。名前が似ているために、片方だけを設定して「対応済み」と思い込みやすい組み合わせです。
よくある質問
allowUnsandboxedCommands: falseだけ設定すればサンドボックスは強制されますか
されません。sandbox.enabledがtrueでなければ、そもそもコマンドはサンドボックス化されず、ブロックも再試行も発生しません。allowUnsandboxedCommandsは、既に動いているサンドボックスの再試行経路だけを制御する設定です。
allowUnsandboxedCommands: falseにすると、サンドボックス化されたコマンド自体にも毎回確認が必要になりますか
なりません。サンドボックス化されたコマンドを確認なしで実行するかどうかはautoAllowBashIfSandboxedが決める独立した設定で、既定はtrueのままです。allowUnsandboxedCommandsが制御するのは、サンドボックスがブロックした後の再試行だけです。
まとめ
sandbox.allowUnsandboxedCommandsをfalseにすると、Claudeが実行するコマンドのdangerouslyDisableSandbox再試行を無効化し、/sandboxのOverridesタブが示すStrict sandbox modeになります。Boolean型キーなのでmanaged settingsに書けば開発者側の設定を無条件に上書きでき、enabledとfailIfUnavailableをセットにするのが公式が示す組織向けの構成です。ただしこれで塞がるのはClaude自身が再試行する経路だけで、開発者が!シェルモードで打つコマンド(バックグラウンドセッションとCLAUDE_CODE_SUBPROCESS_ENV_SCRUB設定時のLinuxを除く)やexcludedCommandsに載せたツール、bypassPermissionsモードそのものへの遷移は対象外です。サンドボックスの二層分離の全体像はClaude Codeのサンドボックス設計、ファイルシステム分離だけを外す設定はsandbox.filesystem.disabledはファイルシステム分離だけ外す設定、ネットワーク許可リストの書式はIPv6ドメイン許可リストの書き方、settings.json全体の構成はClaude Code設定ガイドで確認できます。