/sandbox(サンドボックス)

スラッシュコマンド
/sandbox
サンドボックス
Claude Code の Bash を、OSが提供する分離機能で囲った砂場(サンドボックス)の中だけで走らせるためのスラッシュコマンド。コマンドだけ叩くと「Auto-allow / Regular permissions」の2モード選択メニューが開く。

Claude Code で npm install や terraform / kubectl を勝手に走らせるのが怖い人向け

npm install や terraform、kubectl のようにファイルやネットを書き換えるコマンドを Claude Code に任せたい初日や、git clone してきたばかりの初見プロジェクトを触らせる場面で、毎回の許可ダイアログをやめつつホームや SSH 鍵を守りたい時に <code>/sandbox</code> を叩いてモードを選ぶ。macOS は標準で動き、Linux/WSL2 は事前に <code>bubblewrap</code> と <code>socat</code> を入れる。WSL1 とネイティブ Windows は現状非対応。

Claude Codeに npm installterraform apply を任せるとき、毎回毎回「これ走らせていいですか」のYes/Noダイアログが出ると、しまいには中身を見ずにエンターを連打する自分に気づきます。だからといって全許可にすると、悪意あるパッケージや書き換えられた手順を踏んだとき、家のドット設定ごと吹き飛ばされかねない。私もこの「許可疲れ」と「全許可の怖さ」の板挟みで2回ほど作業を止めました。

/sandbox は、その挟まれた状態を1コマンドで仕切り直すためのスラッシュコマンドです。OSの仕組みを使って「ここから先のファイルは触らせない」「このアドレス以外のネットは見せない」と境界線を引いた箱の中でだけ、Claude CodeのBashを動かす。境界の中なら自由に走ってもらって、外に手を出した瞬間にだけ私が呼び出される、という設計に切り替わります。

噛み砕くと

イメージは「マンションの一室を仕事用に借りた」状態に近いです。部屋の中なら家具の配置を変えても落書きをしても構わない。でも玄関の外に出ようとした瞬間に管理人が止めにくる。Claude Codeにとっての「部屋」が今いるプロジェクトフォルダ、「玄関の外」がホームディレクトリや別ドライブ、「玄関の鍵」をあらかじめ管理人(私)が許可した相手にだけ渡す。それが /sandbox の世界観です。

/sandbox を叩くと、その境界線をどのくらいきっちり敷くかをメニューで選ばされます。「中で動く分は自動でOKにする」モードか、「箱の中であっても1回ずつ私に聞く」モードか。境界線の硬さは同じで、違うのは「中で起きることの自動承認」だけ、というのが地味だけど大事な勘所です。

大事な前提:使えるのは macOS と Linux と WSL2 だけ

これは公式が明確に線を引いている部分なので最初に潰しておきます。/sandbox は OS が持っている分離機能を借りる作りなので、対応OSが限られます。

  • macOS: 標準搭載の Seatbelt をそのまま使う。追加で何かを入れる必要なし
  • Linux: bubblewrapsocat を別途インストールが必要。Ubuntu/Debian なら apt、Fedora なら dnf のパッケージで入る。具体的なコマンドは公式 sandboxing docs の Prerequisites 節にあります
  • WSL2: 中身は Linux と同じ。bubblewrapsocat を入れる
  • WSL1: 非対応。公式いわく「bubblewrap が必要とするカーネル機能が WSL2 にしかない」
  • ネイティブ Windows: 現状なし。公式は将来予定とだけ書いている

もうひとつ Ubuntu 24.04 以降の落とし穴があります。bubblewrap を入れただけでは AppArmor が bwrap の名前空間作成をブロックします。AppArmor 設定ディレクトリの中に bwrap 用の小さい profile を1枚足して、AppArmor サービスを読み直させる必要がある。「動かない」と感じる人の大半はこれが原因です。

「料理ブログを Hugo で立ち上げる」を例に、実際の手順を見る

題材は「料理ブログを Hugo というサイトジェネレータで作る」想定です。npm installhugo server を Claude Code に任せたいけど、ホームフォルダの設定ファイルや SSH 鍵まで触られるのはイヤ、というよくあるシーン。/sandbox をどう叩いて、どっちのモードを使い分けるかを順に見ます。

ステップ1: 対応OSと依存を確認する

macOS なら追加作業なし。Ubuntu 24.04 以降を使っている場合は最低でも次の 3 つを通す必要がある。

  1. Ubuntu/Debian なら管理者権限で apt-get install bubblewrap socat を実行してパッケージを入れる。Fedora の場合は dnf install bubblewrap socat
  2. AppArmor の profile を 1 ファイル足す: bwrapuserns(名前空間作成)を許可する短い profile を AppArmor 設定ディレクトリの中に置く。具体的な書式は 公式 sandboxing docs の Prerequisites 節にコピペできる雛形があるので、そこから取ってきて貼る
  3. AppArmor サービスを管理者権限で読み直させる。reload コマンドの正確な形は同じ公式 docs に1行で載っている

この AppArmor 設定が抜けていると、次のステップでメニューがエラーメッセージを返してきます。動かない時はだいたいこの 3 つのどれかが抜けていると思っていい。

ステップ2: 料理ブログのプロジェクトで Claude Code を起動する

プロジェクト直下に cd してから claude を起動。「私はこの cooking-blog/ フォルダの中だけで作業させたい」という前提を、ここで物理的に成立させておきます。

$ cd ~/projects/cooking-blog
$ claude

ステップ3: /sandbox を叩いてモードを選ぶ

Claude Code が立ち上がったら、入力欄に /sandbox と打って Enter。すると2択メニューが出ます。

> /sandbox

  Choose a sandbox mode:
  1. Auto-allow mode  - Run sandboxed commands automatically
  2. Regular permissions mode - Sandbox + per-command approval

料理ブログを立ち上げる初日なら、私は Auto-allow を選びます。npm installhugo new sitehugo server も全部「フォルダの中で完結する作業」なので、いちいち聞かれずに走ってくれた方がリズムが出る。逆に本番デプロイ用の鍵を扱うフォルダなら Regular permissions 側にする、という使い分けになります。

ステップ4: npm install が砂場の中で走るのを確認する

Hugo は Go 製ですがテーマで npm を要求するものが多いので、テーマインストール用の npm install を Claude に頼みます。

> テーマフォルダで npm install を実行して

  Bash(npm install) [sandboxed]
  added 312 packages in 14s

普段なら「npm install 実行していい?」のダイアログが出るところが、今回は [sandboxed] マークがついて勝手に走り、ホームの ~/.bashrc~/.ssh/ には指1本触れない状態で終わります。これが「Auto-allow なのに安全」の正体です。書ける範囲が ~/projects/cooking-blog/ 以下に物理的に絞られているから、自動承認してもダメージ範囲が決まっている。

ステップ5: ホームの ~/.kube に書きたい時だけ穴を開ける

あとでサイトを Kubernetes にデプロイする予定があり、kubectl~/.kube/config を書き換える必要が出てきたとします。素のままだと砂場の外なので失敗する。.claude/settings.json に追記して、その1か所だけ書き込みを許可します。

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

ポイントは 「広く開けず、必要なフォルダだけ開ける」 こと。「ホームディレクトリ全体を許可」みたいな書き方をすると、~/.bashrc~/.zshrc も書ける範囲に入ってしまい、攻撃された時にターミナル起動時の自動読み込みファイルを書き換えて次回ログイン時に任意コードが走る、という古典的な攻撃が成立してしまいます。

ステップ6: ネットの行き先を registry.npmjs.org だけに絞る

ファイルだけじゃなくネットの行き先もこの段階で絞っておきます。npm install が触りに行く先は基本的に registry.npmjs.org なので、そこだけ通せばいい。

{
  "sandbox": {
    "enabled": true,
    "network": {
      "allowedDomains": ["registry.npmjs.org"]
    },
    "filesystem": {
      "allowWrite": ["~/.kube", "/tmp/build"]
    }
  }
}

ここで初心者がやりがちな勘違いがあります。「github.com だけ通せばだいたい大丈夫」と書きたくなる。これがやばい。Claude Code 公式は明確に警告していて、github.com のような広い行き先は domain fronting という手口で外に抜けられる可能性がある。書く時はサブドメインまで細かく指定するのが正解です。

つまり /sandbox は何をしてくれるのか

  • やってくれる: 今のプロジェクトフォルダの中だけで Bash を動かす境界線を引く。npm installterraform plan を自動承認しても、ホームの設定ファイルや SSH 鍵には触れない
  • やってくれる: ネットの行き先を allowedDomains で絞る。専用の中継サーバー経由で外行きの通信が監視され、リスト外は弾かれる
  • やってくれる: Auto-allow モードでも、rm /rm -rf ~ のようにシステム上の大事な場所(/ 直下やホームディレクトリ ~ 全体など)を狙うコマンドには必ず確認が出る。「自動承認している = 何でも走る」ではなく、危険コマンドへの安全装置は Auto-allow でも効いている
  • やってくれない: Read / Edit / Write といった Claude Code 組み込みのファイルツールの監督。これらは砂場の外にいて、permissions の許可設定で別管理になる
  • 意味が薄い場面: WSL1 環境、ネイティブ Windows 環境、Docker 中で動かしている開発環境(後者は enableWeakerNestedSandbox で動くが強度がガクッと落ちる)

Auto-allow と Regular permissions、何が違うのか

ここで2モードの違いを表にしておきます。境界線の硬さは同じで、違うのは「中の自動承認」だけ、というのが見えれば十分。

モード 箱の中の Bash ファイル制限 ネット制限 deny ルール rm / / rm ~ 向いてる人
Auto-allow 自動で走る 同じ 同じ 常に効く 必ず確認が出る 初日のセットアップ・OSS取得直後
Regular permissions 1個ずつ確認 同じ 同じ 常に効く 必ず確認が出る 本番用フォルダ・秘匿情報を扱う場面

「Auto-allow にしたら全自動で何でも走る」と聞こえがちですが、箱の外に出る通信は普通の許可フローに戻されるし、明示的な deny ルールは何があっても効く。rmrmdir がシステム重要フォルダを狙っている場合も普通に止まります。安全装置は意外と多重に効いている。

使いどころ3シナリオ(具体題材で再現)

シナリオ1: 料理ブログを Hugo で立ち上げる初日

テーマ選定、hugo new sitenpm install でテーマの依存を入れる、hugo server で確認、の流れを止めずに回したい。プロジェクトフォルダ ~/projects/cooking-blog/ の中で完結する作業なので、Auto-allow にして、allowedDomainsregistry.npmjs.orgthemes.gohugo.io を入れておく。これだけで「npm install していい?」のダイアログが消え、3〜4時間の試行錯誤が止まらない。私はこの組み合わせをデフォルトの初日設定にしています。

シナリオ2: OSS を git clone してきた直後

awesome-go-cli みたいな初見のプロジェクト一式を git clone で自分のパソコンに取り寄せて、まず Claude Code に構造を読ませる」場面。中の package.json に怪しい postinstall が仕込まれているかもしれない、というのは現実にある話。/sandbox を Auto-allow で有効化、allowedDomainsregistry.npmjs.org 限定にしておくと、もし postinstall が攻撃者のサーバーに通信しようとしても外で弾かれます。プロジェクトフォルダの外にも書けないので、最悪でも被害はそのフォルダの中で止まる。

シナリオ3: terraform plan を試したい時

インフラ系のコマンドは「クラウドの認証情報を ~/.aws/~/.kube/ から読む」「ローカルの .terraform/ に状態ファイルを書く」が混在します。Regular permissions モードに切り替えて、sandbox.filesystem.allowWrite~/.kube./.terraform を足し、AWS の SDK が叩くドメインだけ allowedDomains に入れる。Auto-allow よりは打鍵回数が増えるけど、本番リソースを動かすコマンドが混じる場合は私は Regular permissions 側に倒します。これ正直、心の平穏のためです。

初心者が踏みやすい落とし穴

  • WSL1 で /sandbox を期待する。公式が「bubblewrap が必要とするカーネル機能が WSL2 にしかない」と明言しているので動きません。WSL2 にアップグレードするか、/sandbox を諦めるかの2択
  • Linux で bubblewrapsocat を入れ忘れる。Ubuntu/Debian なら apt の、Fedora なら dnf のパッケージマネージャから入る。メニューが「インストール手順を表示」と言ってくる場合はこれが原因
  • Ubuntu 24.04+ で AppArmor profile を書き忘れるbwrap に名前空間作成を許可する小さい profile(本文ステップ1)を AppArmor 設定ディレクトリに置き、AppArmor サービスを再読み込みさせる。これを抜くと「動かない」しか分からないので踏みやすい
  • allowedDomainsgithub.com のような広いドメインを書く。中継サーバーが https:// の中身まで見ない仕様なので、広い許可は domain fronting で抜けられる余地がある。書く時はサブドメインまで細かく
  • sandbox.filesystem.allowWrite にホーム配下を雑に書く~/.bashrc~/.zshrc が書ける範囲に入ると、攻撃者がそれを書き換えて次回ログイン時に任意コードを走らせるルートが開く。必要な1か所だけ開ける
  • /sandbox を有効にしたから permissions は緩めていい」と誤解する。両者は二層構造で、permissions は全ツールの最初のゲート、/sandboxBash 系だけの OS レベル壁。両方有効にして初めて意味が出る
  • Auto-allow を「全部勝手に走る」と思い込む。明示的な deny ルール、rm / rmdir/ やホームを狙う場合、外向き通信が許可外、これらは全部止まる。多重の安全装置がある前提で設計されている
  • Read / Edit / Write のファイル系ツールが砂場で守られると思い込む。これらは砂場を通らず permissions で直接管理される。denyRead / denyWrite ルールは砂場と Read / Edit 両方にマージされる、というのが正しい理解
  • watchmandocker をそのまま走らせて失敗する。砂場と相性が悪いツールがあって、Jest なら jest --no-watchmandocker なら excludedCommandsdocker * を入れて砂場の外で走らせる、という回避策が公式の Tip に書いてある

書き方

/sandbox

やってみるとこうなる

入力

/sandbox

出力例

Choose a sandbox mode:
  1. Auto-allow mode  - Run sandboxed commands automatically
  2. Regular permissions mode - Sandbox + per-command approval

# モード選択後、以降の Bash は [sandboxed] マークつきで走る
Bash(npm install) [sandboxed]
added 312 packages in 14s

このページに出てきた言葉

サンドボックス
プログラムを動かす範囲を「砂場」のように囲って、外のファイルやネットに触れないようにする仕組み
Seatbelt
macOS が標準搭載している、アプリの動きを箱に閉じ込めるための機能。<code>/sandbox</code> が macOS で使う土台
bubblewrap
Linux 上で「このプログラムには見せるフォルダだけ見せる」を実現するツール。<code>/sandbox</code> が Linux/WSL2 で使う土台。コマンド名は <code>bwrap</code>
socat
通信の入口と出口をつなぎ直す道具。Claude Code が砂場の中と外をやり取りするときの配管役
AppArmor
Ubuntu 系 Linux の標準ルール集。Ubuntu 24.04 以降は <code>bwrap</code> を unconfined にする profile を別途書く必要がある
WSL2
Windows の中で Linux を動かす公式の仕組みの第2世代。<code>/sandbox</code> は WSL2 では使えるが WSL1 では使えない
allowedDomains
<code>/sandbox</code> 設定の中で「ここへの通信だけは通す」と指定するドメインの一覧。<code>github.com</code> のような広い指定は <code>domain fronting</code> で抜けられるリスクがある
domain fronting
通信の最初の宛先と実際の中身の宛先をズラして、許可されたドメインのフリをして許可外の場所と通信する手口
permissions
Claude Code が全ツールに対して「許す/聞く/禁止」を決める仕組み。<code>/sandbox</code> より広く、最初のゲートになる層
dangerouslyDisableSandbox
個別コマンドだけ砂場の外で走らせる逃げ道。完全に塞ぐ場合は <code>allowUnsandboxedCommands: false</code> で無効化する
excludedCommands
<code>/sandbox</code> 設定の中で「このコマンドだけは砂場の外で走らせる」と指定するリスト。<code>docker *</code> や WSL2 上の <code>cmd.exe</code> をここに入れる

関連項目

公式ドキュメント

https://code.claude.com/docs/en/sandboxing

-

← 戻る