MF Blogs 便利ツール
Claude Codeのサンドボックス境界に囲まれたターミナルと、四方の壁ロックを示した立方体イラスト

記事

Claude Codeの/sandboxでBashコマンドをOSレベル隔離する設定ガイド

Claude Codeの/sandboxはmacOSのSeatbeltとLinux/WSL2のbubblewrap+socatでBashコマンドの読み書きとネットワークをOSレベルに隔離します。auto-allow/regular permissions、allowWrite/denyRead/excludedCommands、managed settings、permissions/permission modesとの関係を公式仕様で整理します。

0:00 0:00

Claude Code/sandboxは、Bashツール経由のシェルコマンドをOSレベルで隔離する仕組みです。macOSは標準のSeatbelt、Linux/WSL2はbubblewrap + socatを使い、ファイルシステムとネットワークの境界をプロセス階層全体に適用します。承認待ちのプロンプトを減らしながら、想定外のディレクトリ書き込みや未許可ドメインへのアクセスを止められるのが本質的な価値です。

結論を先に書くと、/sandboxは**「Bashコマンドをまとめて自動承認したいが、bypassPermissionsAuto Modeでは保護が足りない領域でも安全に動かしたい」**ときの既定の解です。とくに、依存インストールやkubectl/terraformのようにファイル書き込みとネット通信が混ざるコマンド群を扱うときに、permissions.allowを1つずつ書いていくより劇的に運用が楽になります。

サンドボックスが対象にするもの・しないもの

最初に押さえておきたいのがスコープです。サンドボックスはBashサブプロセスを隔離する仕組みで、Claude Codeの他のツールは別の境界で動きます。

ツールサンドボックス対象か境界
Bashサブプロセス対象OSレベル(Seatbelt/bubblewrap)
Read / Edit / Write(組み込みファイルツール)対象外permissionsシステムが直接制御
Computer use(画面操作)対象外アプリ単位のpermissionプロンプト
サブエージェント親と同じ設定を継承親セッションでサンドボックスがONなら同じく適用
環境変数デフォルトで親から継承CLAUDE_CODE_SUBPROCESS_ENV_SCRUBで剥がせる

つまり「Claude CodeのEditツールはサンドボックス外側で動く」点だけは別途permissionsでRead deny/Edit denyを設定する必要があります。サンドボックスはBashのcat .envを止められても、組み込みReadは別経路で動くからです。

対応OSと依存パッケージ

サンドボックスはmacOS、Linux、WSL2で動きます。ネイティブWindowsは非対応で、WindowsではWSL2内でClaude Codeを動かす必要があります。

  • macOS: 何もインストール不要。SeatbeltはOS標準
  • Linux/WSL2: bubblewrap(フィルシステム隔離)とsocat(ネットワークプロキシのリレー)が必要

Ubuntu/Debian系の場合は次のコマンドで導入します。

sudo apt-get install bubblewrap socat

Fedoraの場合は次のとおりです。

sudo dnf install bubblewrap socat

インストール後にClaude Codeを再起動してから/sandboxを起動すると、Dependenciesタブでripgrepbubblewrapsocat、seccompフィルタの可用性が確認できます。seccompフィルタは任意でUnixドメインソケットブロックを追加するものですが、有効化を推奨します。

npm install -g @anthropic-ai/sandbox-runtime

WSL2ではwsl -l -vでバージョン確認し、WSL1ならWSL2にアップグレードする必要があります。Ubuntu 24.04以降では既定のAppArmorポリシーがbubblewrapのユーザー名前空間作成を妨げるため、bwrap専用のAppArmorプロファイルを追加する必要があります(公式ドキュメントに手順あり)。

モード選択:auto-allowとregular permissions

/sandboxを起動するとパネルが開き、まずModeタブでサンドボックスの動作を選びます。

  • auto-allow: サンドボックス内で動くBashコマンドを承認なしで自動実行。サンドボックス境界自体がセキュリティガードになる
  • regular permissions: サンドボックス内でも通常のpermissionプロンプトを使う。サンドボックスは追加防御として動く

Auto Mode(permission modeの方)と名前が似ていますが別物です。Auto Modeは「各ツール呼び出しをclassifierがレビューして承認」する仕組み、サンドボックスのauto-allowは「サンドボックス境界に閉じ込められた上でBashコマンドを承認」する仕組みです。両者は独立して動き、組み合わせて使えます。

auto-allowモードでも次の3つは例外として常に適用されます。

  • 明示的なdenyルールは常に尊重される
  • /・ホームディレクトリ・他のクリティカルなシステムパスを対象とするrm/rmdirは依然プロンプトを出す
  • askルールはサンドボックス外フォールバックしたコマンドに適用される

つまり「サンドボックスは囲い、その中だけ自動承認、外に出るときは通常のpermissionフローに戻る」という二段構成です。

ファイルシステム境界の設計

サンドボックス内のBashコマンドは、既定で次の境界を持ちます。

  • 書き込み既定: 作業ディレクトリ+サブディレクトリのみ
  • 読み取り既定: コンピュータ全体を読める(denyしたディレクトリを除く)。~/.aws/credentials~/.ssh/も既定で読めるのでdenyReadに追加が必須
  • ブロック既定: 作業ディレクトリ外の変更、~/.bashrc/bin/配下システムバイナリ
  • gitワークツリー: リンクされたワークツリーでは共有.gitへの書き込みも許可(hooks/configは依然deny)

このうち読み取り既定がコンピュータ全体という点が、初見だと意外な落とし穴です。資格情報やSSHキーを守るには明示的にdenyReadを書く必要があります。プロジェクトの.claude/settings.jsonに次のように書くと、ホームディレクトリ全体を読み取り禁止にしつつ、プロジェクトディレクトリは読めるように再許可できます。

{
  "sandbox": {
    "enabled": true,
    "filesystem": {
      "denyRead": ["~/"],
      "allowRead": ["."]
    }
  }
}

.はプロジェクト設定ではプロジェクトルートに解決されます。同じ設定を~/.claude/settings.jsonに置くと.~/.claudeに解決され、プロジェクトファイルはdenyReadでブロックされ続けます。設定スコープと相対パスの解決ルールは、ここでつまずきやすいので意識しておくと事故が減ります。

書き込みを追加で許可したい場合はallowWriteを使います。kubectl~/.kubeに、ビルドが/tmp/buildに書く必要があるケースの例です。

{
  "sandbox": {
    "enabled": true,
    "filesystem": {
      "allowWrite": ["~/.kube", "/tmp/build"]
    }
  }
}

複数の設定スコープで同じ配列キーが定義されるとマージされます(上書きではない)。これは便利な一方、開発者が個人スコープで広く許可してしまうリスクもあるため、後述のmanaged settingsで防御します。

ネットワーク境界とドメイン許可

ネットワークアクセスはサンドボックス外で動くプロキシサーバ経由で制御されます。

  • 既定ではどのドメインも事前許可されていない: 新しいドメインに最初にアクセスしたとき、Claude Codeがプロンプトを出す
  • 事前許可: allowedDomainsにホスト名を書いておくとプロンプトを回避できる
  • 管理ロックダウン: managed settingsでallowManagedDomainsOnlyを有効化すると、未許可ドメインは自動ブロック(プロンプトなし)。allowedDomainsは管理設定の値だけが採用される

プロキシはホスト名ベースで判定し、TLS終端や検査は行いません。これは「github.comのような広いドメインを許可すると、ドメインフロンティングで他のホストに到達される可能性がある」というセキュリティ制約に直結します。脅威モデル上厳しい要件があるなら、カスタムプロキシでTLS終端+CA証明書インストールが必要です。

サンドボックス互換性のあるツール・ないツール

公式ドキュメントが明示しているサンドボックス非互換のツールと回避策をまとめます。

ツール問題回避策
docker完全に非互換excludedCommandsdocker *を追加
watchmanjestが依存)サンドボックスで動かないjest --no-watchmanで起動
Go製CLI(ghgcloudterraformmacOSのSeatbeltでTLS検証が失敗することがあるexcludedCommandsに追加
MITMプロキシ+カスタムCATLS検証が複雑enableWeakerNetworkIsolation: true(要セキュリティトレードオフ理解)

特にWSL2固有の罠として、サンドボックス内のBashからcmd.exepowershell.exe/mnt/c/配下のWindowsバイナリを起動できません。WSLがUnixソケット経由でWindowsホストに引き渡す経路をサンドボックスがブロックするためです。これらを呼ぶ必要があればexcludedCommandsに追加します。

permissions・permission modesとの関係

サンドボックス・permissionsルールpermission modesは補完的なレイヤーです。コントロール対象が違うことを把握しておくと、設計時の判断がぶれません。

レイヤーコントロール対象評価タイミング
permission rulesどのツールが使えるかコマンド実行前
permission modes各ツール呼び出しが走るか・プロンプトを出すかコマンド実行前
sandboxBashコマンドが何にアクセスできるかコマンド実行中(OS強制)

特に重要なのが「サンドボックスはモデルの判断や許可ルールの内容に関係なくOSが強制する」点です。「許可されたnpm installが想定外に/etc/を書き換える」ような事故も、サンドボックス境界が物理的に止めます。

sandbox.filesystem.allowWriteEditの許可ルールと同じ役割(パスへの書き込み許可)、WebFetchの許可ルールとsandbox.allowedDomainsは別のドメイン許可(前者はWebFetchツール、後者はBashのネット通信)です。それぞれのスコープを意識して使い分けます。

組織での運用:managed settings

エンタープライズで「全開発者にサンドボックスを強制」したい場合、managed settingsに次のキーを置きます。

{
  "sandbox": {
    "enabled": true,
    "failIfUnavailable": true,
    "allowUnsandboxedCommands": false
  }
}

3つのキーの意味は次のとおりです。

  • enabled: true: サンドボックス有効化
  • failIfUnavailable: true: 依存パッケージ欠如でサンドボックスが起動できない場合にClaude Code自体を起動させない
  • allowUnsandboxedCommands: false: モデルがdangerouslyDisableSandboxパラメータでサンドボックス外実行を試みる「エスケープハッチ」を無効化

ブール値キー(enabledfailIfUnavailable)はmanaged値が優先され、開発者ローカル設定は無視されます。一方、配列キー(excludedCommandsallowRead)はマージされるため、開発者が広げてしまうリスクがあります。これを防ぐにはallowManagedReadPathsOnly: trueを設定して「管理者のallowReadのみ採用」とします。allowManagedDomainsOnlyも同様にネットワーク許可を管理者ロックします。

excludedCommandsには管理者ロック専用のキーがないため、ここは「最小限のリストに留める」運用が現実解です。

トラブルシュートと既知の制約

最後に、運用中によくある問題と公式の対処を整理します。

  • jestがハングする: watchmanが非互換。jest --no-watchmanを使う
  • Go製CLIがTLS検証失敗(macOS): excludedCommandsに追加。MITMプロキシ+CA証明書併用ならenableWeakerNetworkIsolation: true
  • dockerコマンド失敗: excludedCommandsdocker *を追加
  • コンテナ内でbubblewrap起動失敗: enableWeakerNestedSandbox: true(外側コンテナが既に隔離を提供している前提で)
  • seccompフィルタ欠如: npm install -g @anthropic-ai/sandbox-runtimeで追加
  • rootでの--dangerously-skip-permissions失敗: 設計上の制約。devcontainer構成で非rootユーザとして動かす

セキュリティ上の重要な制約として、TLS非終端、Unixソケット経由の権限エスカレーション(docker.sock許可で実質ホストアクセス)、過度に広いallowWriteによるシェル設定書き換え、Linux版のenableWeakerNestedSandboxによるセキュリティ低下が明示されています。

運用前チェックリスト

最後に、サンドボックスを実プロジェクトで回す前の9項目チェックリストを置いておきます。

  • OSはmacOS、Linux、WSL2のいずれかか?(WSL1とネイティブWindowsは非対応)
  • Linux/WSL2ならbubblewrapsocatをインストールし、/sandboxのDependenciesタブで緑になっているか?
  • Ubuntu 24.04以降ならAppArmorプロファイルを追加したか?
  • auto-allowとregular permissionsのどちらが運用ポリシーに合っているか?
  • denyRead~/.aws/~/.ssh/~/.config/gcloud/を追加したか?(既定で読めるため)
  • allowWriteは必要最小限か?シェル設定ファイルを書き込み可能にしていないか?
  • 既知の非互換ツール(dockerwatchman、Go製CLI)への対応を入れたか?
  • 組織展開ならmanaged settingsfailIfUnavailableallowUnsandboxedCommands: falseを設定したか?
  • permissions・permission modes・サンドボックスの3層が何を止めるかを区別して設計したか?

サンドボックスは「Bashの境界を物理的に閉じ込める」ものです。組み込みファイルツール(Read/Edit/Write)やサブエージェント経由の操作は別レイヤーで止める必要があり、3層防御の1層として位置付けるのが安全運用の基本です。

次に読むなら、サンドボックスでカバーしきれない領域を埋めるセキュリティ横断チェックリスト、機密情報の3層防御を整理する秘密情報の取り扱い、サンドボックスとの組み合わせで効くClaude CodeのAuto Modeが直接効きます。