Claude Media
sandbox.excludedCommandsが効かない3つの原因 — Claude Codeの既知バグ

sandbox.excludedCommandsが効かない3つの原因 — Claude Codeの既知バグ

sandbox.excludedCommandsを設定してもコマンドがサンドボックスから外れない3つの既知バグをGitHub Issueから読み解きます。

sandbox.excludedCommandsとは何か

sandbox.excludedCommandsは、Bashサンドボックスの制約下では動かないコマンドを名指しで除外し、サンドボックスの外で実行させる設定キーです。docker *のようなパターンを指定すると、そのコマンドは通常の権限フローだけを通り、ファイルシステムやネットワークの隔離を受けません。

ところが2026年9月に入り、この設定が意図どおりに働かない3つの既知バグがGitHub Issueに報告されました。除外設定そのものが無視されるケース、git -Cのようなサブコマンド前のフラグが付くと除外が外れるケース、単一コマンドへのファイルリダイレクトが除外を無効化するケースです。バグ2はv2.1.277で入った修正の副作用として、バグ3はv2.1.278で観測が確認されています(バグ1の原因となった版は特定されていません)。いずれのIssueもオープンのままです。

バグ1: 除外リストがそのまま無視される(Issue #95813)

Issue #95813は、excludedCommandsに列挙したコマンドが、それでもサンドボックス内で実行され失敗する事例です。報告者はmacOS 24.6.0で、managed settingsに次のブロックを設定していました。

{
  "sandbox": {
    "enabled": true,
    "excludedCommands": ["docker *", "gh *", "ps *", "pgrep *", "sudo *"]
  }
}

この状態でps -p 1を実行するとoperation not permitted: ps、pgrep -x nodeはsysmond service not found、gh pr viewはTLS証明書検証エラーで失敗します。同じps -p 1をdangerouslyDisableSandbox: trueで実行すると1 /sbin/launchdが正しく返るため、コマンド自体は動作し、除外リストがまったく適用されていないことが確認できます。

報告者はallowUnsandboxedCommands: falseが原因かも疑いましたが、そのキーを外して再起動しても3つのコマンドの失敗は変わりませんでした。このキーはドキュメント上もdangerouslyDisableSandboxの可否だけを管理するとされており、excludedCommandsとは独立した設定です。

コメント欄では、Linux/Debian・v2.1.280でも同じ症状が再現したという報告が付いています。dockerグループのソケットにアクセスするためexcludedCommandsにdocker*を並べても無視され、bwrapが補助グループを全て落とすためdocker.sockへの接続が権限エラーになる、という具体例です。このissueにはduplicateラベルが付いており、Anthropic側は既存の別issueと同一の不具合として扱っています。

バグ2: git -Cのようなサブコマンド前のフラグで「全部一致」判定が壊れる(Issue #95455)

Issue #95455は、v2.1.277で入った修正が副作用を持つケースです。v2.1.277のchangelogには次の記載があります。

Fixed a sandbox.excludedCommands glob exempting an entire compound Bash command from the sandbox when only one part matched; every part must now match

これは、複合コマンドの一部だけが除外パターンに一致していても全体をサンドボックス外に出してしまうバイパスを塞ぐ、正当な修正です。ところが、パイプもチェインもリダイレクトも持たない単一コマンド、つまり「部分」が1つしかないコマンドまで、サブコマンドの前に値を取るフラグが付くだけで一致しなくなりました。

excludedCommands: ["git *"]を設定した状態での実測が、issueの表にまとまっています。

コマンドv2.1.276v2.1.277
git status --porcelainv2.1.276除外v2.1.277除外
git --no-pager status --porcelainv2.1.276除外v2.1.277除外
git -C . status --porcelainv2.1.276除外v2.1.277サンドボックス化
git -c core.pager=cat status --porcelainv2.1.276除外v2.1.277サンドボックス化
git --git-dir=<path>/.git --work-tree=<path> status --porcelainv2.1.276除外v2.1.277サンドボックス化

値を取らない真偽値フラグ(--no-pagerなど)は影響を受けず、値を取るフラグ(-C、-c、--git-dir、--exec-path)を挟むと除外が外れます。影響は2段階あり、git statusはサンドボックスに入ったまま終了コード0で「動いているように見える」出力を返す点が特に厄介です。ホームディレクトリの.bashrcや.gitconfigなど、サンドボックスがマスクしたパスが未追跡ファイルとして表示され、通常のワークツリーの雑音と誤認されます。報告者自身、この誤判定によりステージング判断を1つ誤ったと書いています。git -C <path> fetchのような認証系操作は、認証情報を読めずに失敗し、エラーメッセージが証明書やネットワークの問題に見えてしまう点も紛らわしい挙動です。

なお報告者は当初、この現象が非決定的(同じコマンドが失敗・失敗・成功と揺れる)だと書きましたが、後の訂正コメントで撤回しています。実際には失敗した呼び出しには2>&1 | head -20が付いており、成功した呼び出しには付いていなかっただけで、v2.1.277のルールどおり複合コマンドとして扱われた結果でした。git -C単体の過剰一致そのものはv2.1.278でも再現しており、決定的な挙動です。

バグ3: 単一コマンドへのリダイレクトが除外を無効化する(Issue #95532)

Issue #95532は、v2.1.278で観測された別の過剰一致です。excludedCommands: ["gh *"]のもとで、gh api user --jq .loginは除外されて動きますが、同じコマンドの標準出力をファイルへリダイレクトすると、サンドボックス内に戻ってしまいます。

コマンドサンドボックス外で動くか
gh api user --jq .loginサンドボックス外で動くか動く
gh api user --jq .login 2>&1サンドボックス外で動くか動く
gh api user --jq .login > "$TMPDIR/out.txt"サンドボックス外で動くか動かない
gh api user --jq .login > /dev/nullサンドボックス外で動くか動かない
gh api user --jq .login 2>/dev/nullサンドボックス外で動くか動かない

ファイルディスクリプタの複製(2>&1)は許容される一方、/dev/nullを含むファイルへのリダイレクトは何であれ除外を外します。macOSでは、ghのようなGoベースのCLIがSeatbelt配下でTLS検証に失敗するx509: OSStatus -26276が公式のトラブルシューティング項目として知られており、その回避策がexcludedCommandsです。リダイレクトを使っただけで元のTLSエラーへ逆戻りするため、ghの出力をファイルへ書き出して後続コマンドで読む、という「パイプが使えないなら代わりにリダイレクトする」自然なワークアラウンドが機能しません。

公式ドキュメントはどこまでこの挙動を認めているか

sandbox.excludedCommandsの設定リファレンスには、除外が効かないままサンドボックスに留まるコマンドの形が具体的に列挙されています。

  • sudo、eval、xargsで始まるコマンド
  • cd、pushd、popdをどこかに含むコマンド
  • コマンド置換・サブシェル・ifやforなどの制御構文
  • ファイルディスクリプタの複製(2>&1)以外のリダイレクト
  • コマンド名が変数由来のもの

この一覧は、バグ3(単一コマンドへのリダイレクト)を文字どおり言い当てています。つまりIssue #95532が報告した挙動は、現在の設定リファレンスでは「意図した仕様」として明文化されています。issueが求めているのは仕様の撤回ではなく、excludedCommandsをTLS回避策として案内するトラブルシューティング項目側にも、このリダイレクトの制約を書き足すことです。現状のトラブルシューティング項目は「GoベースのツールはexcludedCommandsに載せる」とだけ書いており、リダイレクトで無効化される注記がありません。

一方、バグ2(git -Cのようなサブコマンド前フラグ)は、この「サンドボックスに留まる形」の一覧に載っていません。値を取るフラグを挟むと一致しなくなる挙動は、設定リファレンスからは読み取れない未文書化の副作用です。バグ1(除外リストが全く効かない)に至っては、リファレンス上そもそも失敗する条件が存在しないため、実装側の不具合と見るほかありません。3つの既知バグは、公式ドキュメントとの整合性で見ると性質が異なります。

影響の出方は用途によって変わる

excludedCommandsをどう使っているかによって、3つのバグが刺さる度合いは変わります。

使い方影響
docker *のように単純なプレフィックスだけを除外している影響バグ1が起きれば全滅する。バグ2・3は関係が薄い
git *を除外し、-Cや--git-dirで別ディレクトリを操作するスクリプトがある影響バグ2が直撃する。git statusが誤った出力を返す点が特に危険
gh *など、出力をファイルに保存してから加工するツールを除外している影響バグ3が直撃する。--jqのようなオプションで整形しきれない出力は詰まる
CI的な自動化で、除外コマンドの成否をログにリダイレクトして残している影響バグ3によりリダイレクトを足した瞬間にサンドボックス内へ戻り、ghならログにはTLSエラーが記録される

現状のワークアラウンドとその限界

バグ2については、issueの報告者がcd <dir> && git ...ではなく、ディレクトリ移動を別のBash呼び出しに分けてcd <dir>の後に素のgitを実行する方法を挙げています。(cd <dir> && git ...)はそれ自体が複合コマンドになりv2.1.277のルールで正しくサンドボックス化されるため、回避策にはなりません。より根本的な対処として、git -Cを別名のラッパー(例: gitc)にして、そのラッパー名をexcludedCommandsに登録する方法も報告されています。

バグ3については、ファイルディスクリプタの複製(2>&1)だけは除外を保ったまま使えるため、--jqのような整形オプションで標準出力に必要な形を出し切り、リダイレクトを避けるのが現実的な回避策です。ファイルへの永続化がどうしても必要な場合の根本的な回避策は、Issue #95532の時点では報告されていません。

バグ1は設定側でどうにもならない不具合です。コメント欄では、bubblewrapとseccompをコマンド実行の前段で検知して素通しするラッパースクリプトが有志によって公開されていますが、これはClaude Code本体の挙動を書き換えるサードパーティの回避策であり、公式のサポート対象ではありません。dangerouslyDisableSandboxでの個別実行は動きますが、そのコマンドだけサンドボックスの保護を丸ごと外すことになり、excludedCommandsが本来担うはずだった「特定コマンドだけを狭く除外する」目的からは外れます。

まとめ

sandbox.excludedCommandsを設定しても効かないという報告は、少なくとも3系統に分かれます。除外リストそのものが無視される#95813、git -Cなど値を取るフラグを挟むと単一コマンドでも過剰一致する#95455、単一コマンドへのファイルリダイレクトが除外を無効化する#95532です。このうちリダイレクトの挙動は既に設定リファレンスに仕様として明記されており、issueが求めているのはトラブルシューティング欄への注記追加です。残る2つは未文書化の副作用または実装不具合で、いずれもオープンのままです。近接した時期の修正としてv2.1.281ではgit rev-parse --git-dir等の不一致が直っていますが、これは本記事の3バグとは無関係な別件です。バグ2の-C・-cなど値を取るフラグの過剰一致、バグ3のリダイレクトによる過剰一致は、いずれも最新のv2.1.283時点のchangelogに修正記載がありません。excludedCommandsに依存した自動化を組んでいる場合、gitやghをどう呼び出しているかを見直し、コマンド形が単純なプレフィックス一致から外れていないかを確認する価値があります。設定の基本的な使い方はsandbox.excludedCommandsでdockerなど非対応コマンドを対象外にするにまとめています。

サンドボックス自体の隔離が失敗するケースは、除外設定とは別の原因で起きることもあります。apply-seccompのsetgroups書き込みがLinuxで失敗する件はapply-seccompのsetgroups書き込みがLinuxで失敗する原因と対処、そもそもBash確認をスキップするautoAllowBashIfSandboxedの条件はautoAllowBashIfSandboxedでBash確認をスキップする条件と無効化で扱っています。抜け道を管理設定で塞ぐallowUnsandboxedCommandsとの違いはallowUnsandboxedCommandsは抜け道を管理設定で塞ぐ設定を参照してください。

この記事を共有:XはてブLinkedIn