sandbox.excludedCommandsでdockerなど非対応コマンドを対象外にする
sandbox.excludedCommandsは、dockerやosascriptなどサンドボックス内で動かないコマンドだけを外で実行させる設定です。書き方と安全境界にならない理由をまとめました。
Claude Codeのサンドボックスを有効にすると、通信やファイルアクセスに制限がかかり、dockerやgh、osascriptのような一部のコマンドが正常に動かなくなることがあります。sandbox.excludedCommandsは、こうした特定のコマンドだけをサンドボックスの外で実行させる設定です。全体の隔離は保ったまま、動かないコマンドだけを個別に逃がせます。
excludedCommandsは何を除外する設定か
sandbox.excludedCommandsは、Claude Codeが実行するBashコマンドのうち、常にサンドボックスの外で動かすものを名前で指定する配列です。既定値は未設定で、何も対象外になりません。各エントリの書式は、許可ルールBash(...)の中身と同じです。dockerのような完全一致のコマンド名、docker *のようなプレフィックス、あるいはワイルドカードパターンを書けます。複合コマンドの一部分がどれかのエントリに一致すると、コマンド全体がサンドボックス外で実行されます。たとえばexcludedCommandsにdocker *とだけ書いた状態で、Claudeがdocker build . && npm testを実行すると、docker部分がエントリに一致するため、後半のnpm testも含めたコマンド全体がサンドボックスの外で動きます。npm testだけをサンドボックス内に残す、という部分的な適用にはなりません。
dockerを対象外にする書き方
サンドボックスは既定でファイルシステムの一部と外向き通信を制限するため、dockerのようにデーモンとソケット通信するツールは、サンドボックス内から起動できないことがあります。設定にexcludedCommandsを追加すると、dockerコマンドだけをサンドボックスの外で動かせます。
{
"sandbox": {
"enabled": true,
"excludedCommands": ["docker *"]
}
}この書き方では、dockerで始まるすべてのコマンドが対象になります。docker buildとdocker psのように後ろの引数が変わっても、プレフィックスが一致していれば同じ扱いです。特定のサブコマンドだけに絞りたい場合は、docker psのように完全一致のエントリを書きます。Claude CodeでDockerを実行するようなコンテナ中心の開発フローでは、CLIツールの大半をこの設定で救うことになりがちです。
dockerがサンドボックス内で動かない理由は、サンドボックスが既定でUnixソケットへの接続をブロックすることにあります。dockerデーモンは/var/run/docker.sockというソケット経由で操作するため、この接続がふさがれるとコマンドが失敗します。excludedCommandsはdockerコマンドそのものをサンドボックスの外へ出しますが、sandbox.network.allowUnixSocketsに/var/run/docker.sockを追加すれば、dockerをサンドボックス内に置いたまま、このソケットへの接続だけを許可することもできます。ただし、このソケットへのアクセスを許すこと自体が、サンドボックス化されたコマンドにdockerデーモンの操作を丸ごと渡すことになる点は変わりません。
複数のツールをまとめて対象外にする
docker以外にも動かないツールがある場合は、同じ配列に複数のエントリを並べます。
{
"sandbox": {
"enabled": true,
"excludedCommands": ["docker *", "gh *", "osascript *"]
}
}エントリの並び順に意味はなく、すべて同じ扱いで評価されます。動かないと分かっているツールをプレフィックスで先に洗い出しておけば、実行するたびに失敗して初めて気づくという手戻りを避けられます。
filesystemやnetwork設定と組み合わせる例
excludedCommandsは単独ではなく、filesystemやnetworkの設定と一緒に書くことが多い項目です。次の例は、サンドボックスを有効にして確認プロンプトを省略し、dockerだけをサンドボックス外で動かし、ビルド用ディレクトリと~/.kubeへの書き込みを追加で許可し、AWSの認証情報ファイルを読み取り不可にし、GitHubとnpmへの通信だけを許可する構成です。
{
"sandbox": {
"enabled": true,
"autoAllowBashIfSandboxed": true,
"excludedCommands": ["docker *"],
"filesystem": {
"allowWrite": ["/tmp/build", "~/.kube"],
"denyRead": ["~/.aws/credentials"]
},
"network": {
"allowedDomains": ["github.com", "*.npmjs.org"]
}
}
}excludedCommandsが担っているのは、この構成のうちdockerの部分だけです。残りの制限は、サンドボックス化されたコマンドに対してそのまま効き続けます。
excludedCommandsが安全境界にならない理由
excludedCommandsに書いたコマンドも、通常の許可フローはそのまま通ります。外れるのはサンドボックスの隔離だけです。権限ルールでaskやdenyにしているコマンドは、対象外にしても確認や拒否の対象のままです。
sandbox.autoAllowBashIfSandboxedをtrueにしていても、その恩恵はexcludedCommandsには及びません。この設定がスキップするのは、サンドボックス化されたコマンドに対するBashの素のaskルールだけです。excludedCommandsのコマンドはサンドボックスの外で動くため、通常のBash許可ルールがそのまま適用され、確認プロンプトが減ることはありません。
この設定は安全境界ではなく、あくまで利便性のための仕組みです。ツールが特定のパスへの書き込みだけを必要としているなら、sandbox.filesystem.disabledの記事で扱っているfilesystem.allowWriteのように書き込み先を個別に追加するほうが、隔離の範囲を狭く保てます。excludedCommandsはコマンドそのものを丸ごと隔離の外に出すため、本来は不要な権限までツールに与えてしまうことがあります。
サンドボックスの他の一覧設定には、allowManagedReadPathsOnlyやallowManagedDomainsOnlyのように、managed設定からのエントリだけに絞り込むオプションがあります。excludedCommandsにはこれに相当する仕組みがありません。
他のサンドボックス除外設定とどう使い分けるか
サンドボックスには、excludedCommands以外にも隔離を緩める設定がいくつかあります。効果と適用範囲が違うため、目的に合わせて選び分けます。
| 設定 | 効果 | 使うべき場面 |
|---|---|---|
sandbox.excludedCommands | 効果指定したコマンドだけをサンドボックス外で実行 | 使うべき場面特定のツールだけがサンドボックス内で動かない |
sandbox.filesystem.allowWrite | 効果書き込み範囲を個別に追加(隔離は維持) | 使うべき場面ツールが特定パスへの書き込みだけを必要とする |
sandbox.allowUnsandboxedCommands | 効果falseでClaudeによる再試行を禁止 | 使うべき場面strict sandbox modeでexcludedCommands以外の抜け道を塞ぐ |
sandbox.enableWeakerNetworkIsolation | 効果macOSのTLS信頼サービスへの到達を許可 | 使うべき場面MITMプロキシとカスタムCAでGo製CLIの証明書検証が必要 |
sandbox.allowAppleEvents | 効果Apple Eventsの送信をサンドボックス全体で許可 | 使うべき場面openやosascriptなど複数ツールで恒常的に必要 |
enableWeakerNetworkIsolationとallowAppleEventsは、どちらもサンドボックス全体に効くグローバルな緩和です。問題になっているツールが1つだけなら、次に説明するようにexcludedCommandsへ寄せたほうが隔離の範囲を狭く保てます。たとえばCI環境でterraformだけがTLS証明書の検証に失敗するなら、ネットワーク全体を緩める代わりにexcludedCommandsへterraform *を1行加えるほうが、影響範囲は小さく済みます。ドメイン単位でネットワークを絞る設定は、IPv6ドメイン許可リストの書き方の記事でも扱っています。
Go製CLIとosascriptが失敗する理由
ghやgcloud、terraformのようなGo製のCLIツールは、network.httpProxyPortでMITMプロキシとカスタムCAを使う構成のとき、サンドボックス内ではTLS証明書の検証に失敗することがあります。原因は、これらのツールがmacOSのシステム信頼サービスcom.apple.trustd.agentにサンドボックスから到達できないことです。MITMプロキシを使っていないなら、enableWeakerNetworkIsolationでサンドボックス全体の隔離を弱めるのではなく、失敗するツールをexcludedCommandsに列挙するほうが影響範囲を絞れます。
openやosascriptのようにブラウザでURLを開いたり、他のアプリケーションを操作したりするツールは、Apple Eventsを送信できないためサンドボックス内ではエラー-600で失敗します。allowAppleEventsを有効にすると、サンドボックス化されたコマンドはユーザーへの確認なしに他のアプリケーションを起動できるようになり、コード実行の隔離そのものが崩れます。隔離を保ったまま特定の1つのツールだけを動かしたいなら、excludedCommandsに加える方法が残ります。
sandboxが起動できないときとの違い
excludedCommandsは、サンドボックス自体は有効なまま特定のコマンドだけを外に出す設定です。これは、サンドボックスが起動できない状況とは別物です。LinuxやWSL2でbubblewrapやsocatが入っていない、あるいはプラットフォームが未対応といった理由でサンドボックスが起動できないと、Claude Codeは警告を出したうえで全コマンドをサンドボックスなしで実行します。この状態を許さず起動時にエラーで止めたいなら、sandbox.failIfUnavailableをtrueにします。excludedCommandsは個別のコマンドを選んで対象外にする仕組みで、サンドボックスが丸ごと機能しない状況の代わりにはなりません。
strict sandbox modeで抜け道が変わる
sandbox.allowUnsandboxedCommandsをfalseにすると、Claudeはサンドボックスに阻まれたコマンドをdangerouslyDisableSandboxパラメータで再試行できなくなります。/sandboxパネルのOverridesタブは、この状態をStrict sandbox modeと表示します。
/sandboxstrict sandbox modeでは、Claudeが実行するすべてのコマンドがサンドボックス化されるか、excludedCommandsに載っているかのどちらかになります。通常モードではexcludedCommandsは単なる利便性のショートカットです。strict modeに切り替えた瞬間、それは合法的な抜け道が存在する唯一の入り口に変わります。
シェルモードの!コマンドは対象外
!から始まる入力でユーザー自身がタイプするコマンドは、strict sandbox modeのセッションでない限り、サンドボックスを有効にしていても既定でサンドボックスの外を走ります。サンドボックスが対象にしているのは、Claudeが自分で実行するコマンドだからです。excludedCommandsは後者だけに効く設定で、ユーザーが手で打つコマンドを制限したり緩めたりする仕組みではありません。
まとめ
sandbox.excludedCommandsは、dockerやgh、osascriptのようにサンドボックス内で動かないコマンドだけを、隔離の外へ個別に逃がす設定です。書式は許可ルールBash(...)と同じで、完全一致・プレフィックス・ワイルドカードのいずれかを配列に並べます。安全境界ではなく通常の許可フローも隔離もそのままなので、書き込み先を絞りたいだけならfilesystem.allowWriteのほうが、dockerのようにUnixソケット経由のツールを隔離内に残したいならnetwork.allowUnixSocketsのほうが、範囲を狭く保てます。allowUnsandboxedCommandsをfalseにしたstrict sandbox modeでは、excludedCommandsがサンドボックスをすり抜ける唯一の手段になります。管理者専用ロックが無いため、組織で使うときはリストの中身を定期的に見直す運用が必要です。