Claude CodeのallowManagedDomainsOnlyで許可ドメインを管理設定に固定する
allowManagedDomainsOnlyをtrueにすると、managed settings以外が指定したallowedDomainsは無視され、非許可ドメインは自動遮断されます。設定例とv2.1.282までの修正履歴を扱います。
managed settings(組織が配布する設定ファイル)でsandbox.network.allowedDomainsに許可ドメインを並べても、開発者はユーザー設定やプロジェクト設定に同じキーを1行追記するだけで、そのリストを自分の手元だけ広げられます。allowManagedDomainsOnlyはこの拡張の経路を潰す設定です。trueにすると、サンドボックス化されたコマンドが通信できるドメインはmanaged settings由来のallowedDomainsとWebFetch(domain:...)許可ルールだけになり、それ以外のスコープが指定したドメインは無視されます。許可リスト外のドメインへの接続はプロンプトを出さず、自動的に遮断されます。
allowManagedDomainsOnlyは何を固定するのか
sandbox.network.allowManagedDomainsOnlyはBoolean型の設定で、書けるスコープはmanaged settingsだけです。既定値はfalseで、この場合allowedDomainsはユーザー設定・プロジェクト設定・ローカル設定・--settingsフラグを含む全スコープからマージされ、開発者が追加したドメインもそのまま通信を許可されます。
trueにすると挙動が変わります。Claude Codeはmanaged settingsに書かれたallowedDomainsとWebFetch(domain:...)の許可ルールだけを有効なドメインとして扱い、それ以外のスコープのallowedDomainsは完全に無視します。あわせて、許可リスト外のドメインへの接続は承認プロンプトを一切出さず、自動的に遮断されます。管理者が定義した通信先の外へは、開発者がプロンプトで「Yes」を選ぶ余地すら残りません。
ロックが有効な間、非許可ドメインへの接続はそもそも承認プロンプトの対象になりません。ロック前にプロンプトで「Yes, and don't ask again」を選んでローカル設定に保存済みのWebFetch(domain:...)ルールも、managed settings由来でないため評価から外れます。
開発者側からallowedDomainsが広がってしまう理由
既定のサンドボックス化されたBashコマンドは、通信可能なドメインを何も持たない状態から始まります。新しいドメインへ最初に接続しようとしたとき、Claude Codeは承認を求めるプロンプトを出します。ここで「Yes, and don't ask again」を選ぶと、WebFetch(domain:...)という許可ルールがローカル設定に保存され、次回以降そのドメインへの接続はプロンプトなしで通ります。
allowedDomains・WebFetch(domain:...)のどちらも、ロックがない状態ではセッションが読み込む全設定ファイルからマージされます。組織側がmanaged-settings.jsonでallowedDomainsに社内リポジトリだけを並べていても、開発者が自分のユーザー設定に別のドメインを1行足すか、プロンプトへの承認を重ねるだけで、その分だけ通信先は静かに広がります。ファイルシステム側で同じ役割を果たすのがallowManagedReadPathsOnlyで読み取り再許可を管理設定に限定する設定で、こちらはallowReadという別のリストを狙い撃ちします。
managed-settings.jsonで許可ドメインを固定する
公式ドキュメントが示す例は、GitHubとnpmだけを許可し、開発者が追加したドメインは無視する構成です。
{
"sandbox": {
"network": {
"allowManagedDomainsOnly": true,
"allowedDomains": ["github.com", "*.npmjs.org"]
}
}
}この状態で開発者が自分のユーザー設定にallowedDomains: ["api.internal-tool.example.com"]を足しても無視されます。サンドボックス化されたコマンドが通信できるのはgithub.comと*.npmjs.orgの配下だけで、それ以外のドメインへの接続は試行された時点で遮断されます。
allowedDomainsのエントリはワイルドカードと:port指定を受け付けます。github.comは全ポートを許可し、api.example.com:443のように書けば443番だけに絞れます。IPv6アドレスを含める場合は"[::1]"のように角括弧で囲む書き方が必要で、詳しい構文はIPv6ドメイン許可リストの書き方で扱っています。WebFetch(domain:...)ルール側のワイルドカードは*.example.comのような先頭形式と、素の*の2種類だけをサンドボックスが解釈します。素の*はv2.1.186以降が必要で、それより古いバージョンでは全ドメイン許可のつもりで書いても効きません。
strictAllowlistとの違い
sandbox.network.strictAllowlistも、非許可ドメインをプロンプトなしで拒否する設定です。ここだけ見るとallowManagedDomainsOnlyと同じに見えますが、狙いが異なります。strictAllowlistはv2.1.219以降で使え、ユーザー設定・managed settings・--settingsから設定できます。拒否の対象はallowedDomainsとWebFetchの許可ルールを全スコープからマージした通常の許可リストで、開発者が自分のユーザー設定にallowedDomainsを追記すれば、strictAllowlistが有効でもその追記分はそのまま許可リストに乗ります。
両者の違いを3行にまとめます。
| 観点 | strictAllowlist | allowManagedDomainsOnly |
|---|---|---|
| 設定できるスコープ | strictAllowlistユーザー設定・managed settings・--settings | allowManagedDomainsOnlymanaged settingsのみ |
| 許可リストの出所 | strictAllowlist全スコープからマージ(開発者の追記も有効) | allowManagedDomainsOnlymanaged settingsのallowedDomainsのみ |
| 非許可時の挙動 | strictAllowlistプロンプトを出さず自動拒否 | allowManagedDomainsOnlyプロンプトを出さず自動拒否 |
管理者の意図が「拒否か許可かを毎回聞かれたくない」だけならstrictAllowlistで足り、「開発者側からの拡張そのものを禁じたい」ならallowManagedDomainsOnlyが必要です。両方を同時に有効にすると、許可リストの中身がmanaged settings限定になったうえで非許可ドメインは自動拒否されます。strictAllowlistは該当スコープのどこか1つがtrueにすればセッション全体で有効になり、他のソースがfalseを指定していても無効化されません。
allowManagedDomainsOnlyが対象にしないもの
このロックが縛るのはallowedDomainsという「許可を広げる方向」のリストだけです。deniedDomainsで明示的にブロックする設定は、ロックの有無にかかわらずセッションが読み込む全スコープから常にマージされ続けます。開発者は組織が許可したドメインの中から、自分の判断でさらに個別のホストを塞ぐことは常にできます。逆方向、つまり組織が決めた許可範囲を広げる操作だけが、このロックで封じられます。deniedDomainsのエントリは完全修飾ドメイン名を示す末尾ドットを付けても(example.com.)、付けない書き方(example.com)と同じ接続を遮断します。
オートモードでサンドボックスが有効なとき、Claudeはコマンドごとに必要なホストを名指しして、その場限りで通信を開く「コマンド単位の許可ドメイン」という仕組みを使えます。allowManagedDomainsOnlyが有効な間は、この仕組みも拒否されます。コマンド単位でホストを追加しようとしても、ロックされた許可リストを一時的にも広げることはできません。
カスタムプロキシの設定(httpProxyPort・socksProxyPort)はallowManagedDomainsOnlyと独立して機能し、詳しい手順はClaude Codeプロキシ設定で扱っています。ただし既定のビルトインプロキシはTLSを終端しないため、allowedDomainsにgithub.comのような広いドメインを許可すると、ドメインフロンティングのような手法でその配下から許可リスト外のホストへ通信が抜ける余地は、allowManagedDomainsOnlyを有効にしても残ります。許可ドメインの発行元を固定することと、許可したドメインの中身まで安全にすることは別の課題です。
導入時によくあるつまずき
v2.1.69より前は自動遮断でなくプロンプトが出ていた
allowManagedDomainsOnlyを有効にしていても、v2.1.69より前のバージョンには非許可ドメインへの接続時に承認プロンプトが表示される不具合がありました。ロックの狙いは「開発者の承認なしに遮断すること」なので、この不具合が残ったバージョンではプロンプトへの応答次第で意図しない通信が通る余地がありました。v2.1.69でこの挙動は修正され、非許可ドメインは回避策なしに自動遮断されるようになっています。
上位の設定ソースにsandboxブロックが無いとロックごと無視される
v2.1.126より前のバージョンには、複数のmanaged settingsソースを読み込む環境で、優先度の高いソースがsandboxブロックを一切持たない場合にallowManagedDomainsOnly(およびallowManagedReadPathsOnly)自体が無視されるセキュリティ上の不具合がありました。組織のMDM配布とclaude.aiのserver-managed settingsを併用している場合、両方のソースにsandboxブロックが実際に存在するか確認しておく価値があります。
excludedCommandsとの関係はv2.1.282で変わった
sandbox.excludedCommandsはサンドボックスを経由させずに実行するコマンドの指定で、allowManagedDomainsOnlyを有効にしても単体では手が届かない別枠のキーです。v2.1.282で、managed settingsまたは--settingsがallowUnsandboxedCommands: falseを指定しているか、managed設定側でallowManagedDomainsOnly: trueが有効な場合に限り、プロジェクト設定とローカル設定のexcludedCommandsエントリを無視するよう変更されました。この変更より前のバージョンでは、allowManagedDomainsOnlyで通信を固定していても、開発者がexcludedCommandsにコマンドを追記すればそのコマンドはサンドボックスの境界そのものから外れ、通信制限ごと迂回できていました。
対応プラットフォームはmacOS・Linux・WSL2まで
サンドボックス自体がネイティブのWindowsでは動作しません。allowManagedDomainsOnlyを含むネットワーク側のロックはmacOS・Linux・WSL2の環境にだけ適用され、Windowsホストを含む開発者には別の統制手段を用意する前提になります。
まとめ
allowManagedDomainsOnlyは、sandbox.network.allowedDomainsという1つのリストの発行元をmanaged settingsだけに固定し、リスト外への接続を自動遮断する設定です。効果を出すには3点の確認が要ります。managed settingsの複数ソースいずれにもsandboxブロックがあること、excludedCommandsのロックはv2.1.282以降でなければ別枠のままであること、そして許可したドメイン自体が広すぎればロックの有無に関係なく抜け道が残ることです。ファイルシステム側の同種のロックとの違いはallowManagedReadPathsOnlyの記事で扱った通りで、組織全体のネットワークアクセス設計はクラウド環境のネットワークアクセス設定で扱っています。