
Claude CodeのSandbox機能を改めて整理してみた
はじめに
今回はClaude CodeのSandbox機能について紹介します。登場当初と比べて最近(2026年4月時点)はかなり洗練されてきた印象があるので、改めてまとめて紹介します。
Claude CodeでCLIコマンドを実行する際、PlanモードやAcceptEditsモードだと許可するコマンドを逐次していするためのダイアログが表示されていました。またClaude Codeにプロジェクト外のファイルや外部ネットワークのアクセスをどこまで許可するのか、settings.jsonで管理していました。これは、逐次許可を与える負担が人間にあるのと、承認がどんどん曖昧になっていくという課題もあります。
Sandbox機能を使うと、事前にファイルシステムとネットワークの境界を設定でき、安全なコマンドは自動で実行できるようになっています。
対応プラットフォーム
macOSはSeatbeltというファイルアクセスやネットワーク通信を細かく制限できる機能が組み込まれているため追加インストールは不要です。LinuxとWSL2はbubblewrapを使用します。WSL1は非対応です。bubblewrapがWSL2のカーネル機能を必要とするためです。なお、Windowsネイティブは現時点では非対応でとなります。
Claude CodeのSandbox機能とは
Claude CodeのSandbox機能は、おおまかに以下の3つを制御できます。
- CLIコマンドの自動実行
- ファイルシステム(ディレクトリ/ファイル単位)読み書き
- ネットワークアクセス(ローカル/外部)
事前に境界を定義することで、その範囲内は許可ダイアログなしで実行できるようになります。
Sandbox範囲内の安全なコマンドは許可不要で実行できるため、承認疲れを軽減できます。アクセス可能なディレクトリやホストは事前に指定でき、Sandbox外へのアクセス試行はOSレベルでブロックされます。
CLIコマンドの自動実行
Claude CodeのSandboxには2つのモードがあります。※Claude CodeのPlanモードやAcceptEditsモードなどとは別
-
Auto-allowモード:Sandbox内のCLIコマンドは自動的に許可されます。外部ホストへのアクセスが必要なコマンドなど、Sandboxに対応できないケースは通常の許可フローにフォールバックします。明示的な拒否ルールは常に優先して適用されます。
-
Regular permissionsモード:Sandbox内でも全コマンドが通常の許可フローを通ります。CLIコマンドをより細かく制御したい場合に使います。
両モードとも、ファイルシステムとネットワークの制限は同じです。違いはSandbox内のコマンドを自動承認するかどうかのみです。Claude Codeの利用に慣れてきて、段々と承認疲れが発生して来た際はAuto-allowモードを検討するとよいです。
具体的には、/sandboxコマンドを実行すると切り替えられます。また以下のようにsettings.jsonなどの設定ファイルのsandbox.autoAllowBashIfSandboxedオプションを使うことで起動時の基本設定にできます。値のデフォルトがtrueでAuto-allowモード、falseにするとRegular permissionsモードになります。
{
"sandbox": {
"enabled": true,
"autoAllowBashIfSandboxed": true
}
}
ファイルシステムの権限制御
ファイルシステムに関しては、基本的に書き込みはカレントディレクトリとサブディレクトリのみ。読み込みはLinuxのユーザーが持つ権限の範囲になります。明示的な許可がある場合は、範囲外へのアクセスが出来ます。
また細かく設定するために、4つのプロパティで特定のディレクトリを読み込み許可/不許可、書き込み許可/不許可を設定できます。現在のプロジェクトへの書き込みを許可し、ほかの特定のディレクトリだけ読み込み/書き込みができるように制限などができます。以下は設定例です。
{
"sandbox": {
"enabled": true,
"filesystem": {
"allowWrite": ["/tmp","."],
"denyWrite": ["/etc"],
"allowRead": ["~/.zshrc"],
"denyRead": ["~/.aws/credentials"]
}
}
}
ネットワークアクセスの権限制御
ネットワークアクセスの設定では、ドメインのアクセス許可/不許可とローカル環境との通信、通信がプロキシーを経由するように設定などができます。localhostポートへのバインド許可もnetwork.allowLocalBindingで設定でき、Sandbox外とのネットワークアクセスを細かく制御できます。
{
"sandbox": {
"enabled": true,
"network": {
"allowedDomains": ["github.com", "*.npmjs.org"],
"allowLocalBinding": true
}
}
}
上記のように記載するとローカルで立ち上げているサービスへのアクセスを許可できます。またネットワークアクセスが必要なCLIツールは、初回実行時にホストへのアクセス許可を求めてきます。許可を与えると以降はSandbox内で動くようになります。
SandboxとPermissionの棲み分け
Sandboxと別にClaude Codeにはファイル読み取りや編集の許可を制御するPermissionがあります。それらの棲み分けについては以下に記載があります。
Permissionは、Bash、Read、Edit、WebFetch、MCPなどのツールに適用されます。Sandboxは、OSレベルでファイルシステムおよびネットワークレベルでBashコマンドがアクセスできる範囲を制限します。Bashコマンドと子プロセスにも適用されます。
注意が必要なのは、Sandboxでブロックされていても、ツール経由であれば許可される場合があることです。例えば、Sandboxで特定ディレクトリのアクセスを禁止していても、Readツールを利用して読み取りできないツールを読み取る場合があります。ツール利用の承認は入るので、その部分は誤って承認しないよう注意しましょう。
使い始める手順
事前準備(Linux/WSL2の場合)
macOSはSeatbeltが組み込まれているため、追加インストールは不要です。Linux/WSL2の場合は以下のパッケージをインストールしてください。
Ubuntu/Debianの場合:
sudo apt-get install bubblewrap socat
Fedoraの場合:
sudo dnf install bubblewrap socat
/sandboxコマンドで有効化
Claude Codeのチャット上で/sandboxを実行するとモード選択メニューが開きます。以下のようにコマンドの自動実行を許可するか、Sandbox自体を無効化するかユーザーは選択できます。
1. Sandbox BashTool, with auto-allow
2. Sandbox BashTool, with regular permissions
3. No Sandbox
Sandboxを強制する方法
デフォルトでは、Sandboxが起動できなかった場合(依存関係不足、未対応プラットフォームなど)は警告を表示しつつSandboxなしで起動を継続します。Sandbox起動失敗をClaude Codeを終了させたい場合は、設定でsandbox.failIfUnavailableをtrueにします。
{
"sandbox": {
"enabled": true,
"failIfUnavailable": true
}
}
組織でSandboxを活用していく際は、MDMで端末にmanaged-settings.jsonを配布することでSandboxを必須要件として強制できます。
Claude Code settings - Claude Code Docs
Sandboxをバイパスする動作について
Sandboxの制限でコマンドが失敗した場合、Claude Codeはエスケープハッチ(dangerouslyDisableSandboxパラメータ)を使ってSandbox外で再試行を提案することがあります。この場合は通常の許可フローが適用されます。組織の管理下の環境でこのエスケープハッチを無効化したい場合は、allowUnsandboxedCommands: falseを設定します。
リリース初期は自動でエスケープハッチが動いたので、信頼性が気になりましたが現在は外側からエスケープハッチを無効化できるので、いよいよDevContainerの代わりに使えるものになってきている印象です。
ユースケースに沿ってやってみた
詳細な設定は以下に記載があります。ここからは用途に応じた設定例を紹介します。
Claude Code settings - Claude Code Docs
ファイル書き込みを許可するパスを追加する
デフォルトでは、Sandbox内のCLIコマンドは現在の作業ディレクトリ配下のみ編集できます。terraform、npmなどのCLIツールが作業ディレクトリ外に書き込む場合は、sandbox.filesystem.allowWriteで対象パスを追加します。
{
"sandbox": {
"enabled": true,
"filesystem": {
"allowWrite": ["/tmp"]
}
}
}
GitHub上のコードを参照させる際、別のディレクトリにgit cloneして解析する動作があります。そのために/tmpを登録するもの良さそうです。
設定するパスのプレフィックスによって解決先が変わります。
| プレフィックス | 解決先 | 例 |
|---|---|---|
/ |
ファイルシステムルートからの絶対パス | /tmp |
~/ |
ホームディレクトリからの相対パス | ~/.zsh |
./ またはプレフィックスなし |
プロジェクト設定ならプロジェクトルート、ユーザー設定なら~/.claude |
./output |
複数の設定スコープ(ユーザー設定・プロジェクト設定など)にallowWriteがある場合、配列はマージされます。上位スコープの設定を上書きするのではなく、全スコープのパスが合わせて適用されます。ツール全体をSandboxから除外するexcludedCommandsより、allowWriteで必要なパスだけを許可する方法が推奨です。
設定前にClaude Codeに以下のように依頼するとファイル作成がブロックされます。
> /tmpにファイルを作って。ツールを使わずに
ツール(Bash や Write)を使わずにファイルを作成することはできません。ファイルシステムへのアクセスはすべてツール経由で行う必要があります。
ご自身で実行する場合は、ターミナルで以下のコマンドを使用してください。
touch /tmp/test.txt
> ! touch /tmp/test.txt
⎿ touch: /tmp/test.txt: Operation not permitted
/tmpを追加すると、書き込み可能になります。Macの場合は、/tmp直下への書き込みができないので、$TMPDIRを使って書き込んでいます。
> /tmpにファイルを作って。ツールを使わずに
⏺ Bash(touch /tmp/hoge.txt && echo "作成成功")
⎿ Error: Exit code 1
touch: /tmp/hoge.txt: Operation not permitted
[rerun: b1]
⏺ やはり失敗します。$TMPDIR を使うと:
⏺ Bash(echo $TMPDIR && touch $TMPDIR/hoge.txt && echo "作成成功")
⎿ /tmp/claude-502
作成成功
⏺ $TMPDIR は /tmp/claude-502 に解決されていて、こちらは書き込めます。
/tmp 直下への書き込みが Operation not permitted になる理由は、macOS の SIP(System Integrity Protection)や実際のファイルシステム権限によって /tmp ルート直下への書き込みが制限されているためです。設定の allowWrite にかかわらず OS レベルで弾かれています。
/tmp への書き込みが必要な場合は /private/tmp/任意サブディレクトリを使うか、$TMPDIR を使うのが確実です。
denyRead + allowWrite でホームディレクトリを保護
ホームディレクトリ配下は拒否し、現在のディレクトリのみファイル書き込みを許可してみます。
{
"sandbox": {
"enabled": true,
"filesystem": {
"denyRead": ["~/"],
"allowWrite": ["."]
}
}
}
以下のようにプロンプトを実行すると、Claude Codeのエージェント自体はホームディレクトリのファイルにアクセスできないことが確認できました。
> ホームディレクトリのshell関連のファイルを読んで
サンドボックスの制限により /Users/user.name 直下へのアクセスがブロックされています。~/.zshrc などのシェル設定ファイルが読めない状態です。
/sandbox コマンドで /Users/user.name の読み取りを許可リストに追加していただければ読み取れるようになります。
ただ直接ファイルを指定した場合は以下のようにツールを使ったアクセスの許可を求めてきます。これを許可するとファイルが読み取れました。
> ホームディレクトリのshell関連のファイルを読んで ~/.zshrc
Read(~/.zshrc)
Do you want to proceed?
❯ 1. Yes
2. Yes, allow reading from sato.tomoki/ during this session
3. No
読めました。内容の概要は以下の通りです。
- anyenv の遅延初期化(node/ruby/python 等)
...
これはSandboxがClaude Codeのプロセスや子プロセスのみに制御が行われ、Read/Editなどのツールには関与しないことが確認できます。ツール側の処理を制限する場合には、Permissionを使うことでブロックできます。
おまけ:denyRead設定に/を設定すると、CLIコマンドの裏側でのファイル読み込みができなくなります。例としてcurlコマンドはSSL証明書ファイル読み込みが必要なので動かなくなります。curl自体は-kオプション(SSL検証スキップ)を使えば利用できますが、ほかのCLIコマンドにも影響が出る可能性があるので、制限範囲は注意が必要です。
ローカル環境への通信を制御
基本設定の場合では、ローカルのソケットのbindができず、ローカルアプリの起動が失敗することを確認します。
{
"sandbox": {
"enabled": true,
}
}
以下のような非常に簡易なプログラムをpython3 server.pyで起動させてみます。
from http.server import HTTPServer, SimpleHTTPRequestHandler as H
HTTPServer(("localhost", 8000), H).serve_forever()
Claude Codeに以下を依頼します。
以下を実行して
python3 server.py
すると以下のようにブロックされます。その後、Sandboxを解除すると実行できることは解釈してくれて、Sandbox解除の判断をユーザーに委ねてくれます。
⏺ Background command "Run server.py in background" failed with exit code 1
⏺ サンドボックス内では bind がブロックされるため、サンドボックスを外して再実行します。
⏺ Bash(python3 server.py)
⎿Running…
─────────────────────────────────────────────────
Bash command (unsandboxed)
python3 server.py
Run server.py in background without sandbox
This command requires approval
Do you want to proceed?
❯ 1. Yes
2. Yes, and don’t ask again for: python3:*
3. No
以下のように設定をいれると、正しくサーバが起動することが確認できました。
{
"sandbox": {
"enabled": true,
"network": {
"allowLocalBinding": true
}
}
}
カスタムプロキシで通信ログを収集
組織のセキュリティポリシーで通信の検査やロギングが必要な場合、カスタムプロキシを指定できます。
{
"sandbox": {
"network": {
"allowedDomains": ["google.com"],
"httpProxyPort": 8080
}
}
}
既存のセキュリティ基盤(監査ログや通信フィルタリングシステムなど)が実装済みで連携したい場合に活用できます。上記のように設定して、mitmproxyをローカルで以下のコマンドで立ち上げると通信がプロキシー側に流れます。
# インストール
brew install mitmproxy
# プロキシ立ち上げ(別ターミナル)
mitmproxy --listen-port 8080
# Claude Code上で指示
> google.comのデータをサンプルとして取得して

所感
承認疲れを起こさずにエージェントの自律性を高められるのは、実用的な機能だと感じます。特にエンタープライズ環境での導入において、ネットワーク分離とカスタムプロキシの組み合わせはセキュリティ要件を満たす上で有効です。WSL1非対応やWindowsネイティブの未対応といった制限はありますが、今後対応が進むことに期待しています。
注意点としては、Sandboxでファイル読み込みを禁止しても、ツールによる読み込み可能かはPermissionによって決まる点です。Sandboxで塞いでいるから問題ないと思っていると、思わぬ落とし穴にはなりそうなのでご注意ください。
この記事がどなたかの参考になれば幸いです。








