Claude Codeのガードレールとは、危険なコマンドの実行を抑えるための仕組みの総称。単一機能ではなく、権限ルール(permission rules)・承認プロンプト・Hook・/sandbox・コンテナ/VMといった複数の層で成り立っています。
軽さとポータビリティ(持ち運びやすさ)を優先するなら、自前の小さなHook(フック)が向いています。ファイルやネットワークごと隔離して事故の被害を抑え込みたいなら、/sandbox かコンテナ/VMが候補。守り方は1つではありません。状況に合わせて選ぶものです。
なぜ守りが要るのか。Claude CodeはBashを実行できます。便利な反面、rm -rf(ファイルやフォルダを強制削除するコマンド)のような危険なコマンドも実行できてしまう、という裏返しがある。たとえばビルド用フォルダを片付けるつもりが、ワイルドカード(* などの自動展開)の解釈がずれて、意図より広いパスを指す rm -rf が組み立てられる――こうした取り違えは起こり得ます。文法上は正しいので、実行判定だけでは止まりません。そこでコマンドを実行直前に横取りして拒否を返すのがHook。これがこの記事で扱う守りの一つです。なお先に断っておくと、ここで紹介するHook・/sandbox・コンテナ/VMはいずれも自律実行のリスク(被害範囲)を狭める層であって、完全に安全にする仕組みではありません。リスクをゼロにするのではなく、踏んだときの被害を小さく抑えるのが目的です。
- 主な守り方は4つ。自前のPreToolUse Hook、ビルトインの
/sandbox、コンテナ/VMでの隔離、コミュニティ製のHook集(ただし他者製Hookはユーザー権限で動くので導入前にレビュー必須)。公式にはこのほか sandbox runtime や Claude Code on the web も隔離選択肢として案内されています。 - 選ぶ基準は「軽さ」と「隔離の強さ」のトレードオフ。最小から始めて、足りなければ隔離を上げる。
- Hookは exit code 2 を返すとそのコマンドを止められる。ただし単純な文字列一致は回避され得るため、典型的な危険パターンを減らす一層と位置づけ、
/sandboxやコンテナ/VMと重ねて使う。
Claude Codeはどのコマンドを実行してよいか、どう判断しているか
守りを足す前に、Claude Codeがそもそも「何を実行してよいか」をどう決めているのかを押さえておくと、各手法がどこに効くのかが見えてきます。鍵になるのが権限モデル(permission model)。ツールを使うたびに走る、許可・拒否の判定の仕組みです。
allow / deny ルールと手動承認の流れ
Claude Codeは、何かツールを使おうとするたびに権限チェックを通します。Bashコマンドの場合、設定済みのルールに照合される、という流れ。公式ドキュメントによれば、ルールには拒否(deny)・確認(ask)・許可(allow)の3種類があり、評価順は deny → ask → allow(先に一致したものが優先)です。読み取り専用ツールは承認不要、Bashコマンドとファイル編集は既定で承認の対象になります。なお権限はモデルではなくClaude Code側で強制されます(プロンプトやCLAUDE.mdでは緩められない)。ルールは次のようなワイルドカード付きの書式で書けます。
{
"permissions": {
"allow": [
"Bash(npm run test *)",
"Bash(git commit *)"
],
"deny": [
"Bash(rm -rf *)",
"Bash(curl *)"
]
}
}
Bash(npm run test *) は「npm run test で始まるコマンドを許可」という意味。ls や cat のような読み取り専用コマンドは、設定しなくても最初から自動で通ります。
通常モードでは、ルールに当てはまらない危険そうなコマンドが出るたびに、画面に確認が出て、1件ずつ承認する形になります。安全ではありますが、ここに落とし穴があるのも事実。
自律実行に切り替えると何が変わるか
実際に長いセッションを回すと、承認、承認、また承認、とプロンプトが延々と続きます。耐えきれず、確認をスキップする自律実行(bypassモードなど)に切り替えて作業を進める。そうした運用に寄せたくなる場面は出てきます。
ここで何が起きるか。通常の手動承認が大きく省略されます。正確には、bypassPermissions でも明示的な ask ルールや、ルート・ホームディレクトリの削除(rm -rf / や rm -rf ~)は最後の安全装置として確認が残ります。とはいえそれ以外の大半は素通りになり、取り違えたコマンドが組み立てられても止め手が薄くなる。冒頭で触れた取り違えのようなケースは、まさにこの状況で効いてきます。自律実行に寄せるほど、人の代わりにコマンドを止める仕組みが必要になる、というわけです(無人運用なら隔離境界を別途用意する前提で考えます)。
この記事で扱う4つの守り方は、すべてこの「外れた安全弁」を別の形で埋めるためのものです。承認するかゼロか、の二択ではなく、Claudeには自由に動いてもらいつつ、本当に危ないケースだけを自動で止める発想に立っています。
4つの守り方を「軽さ・隔離の強さ」で選ぶ
この記事では、実務で使いやすい守り方として主に4つを扱います。自前のPreToolUse Hook、ビルトインの /sandbox、コンテナ/VMでの隔離、コミュニティ製のHook集です。なお公式には、Claude Codeプロセス全体を囲う sandbox runtime や Claude Code on the web も隔離選択肢として案内されています。なお同じ「隔離」でも、通常のコンテナ(Docker)はホストとカーネルを共有するのに対し、VM/microVMは別カーネルで動くぶん分離が強い、という差があります。
4手法の比較表
選ぶときの軸は3つ。コマンドをどこまで封じ込められるかの「隔離の強さ」、入れるのにどれだけ手がかかるかの「導入の手間」、別のPCやチームへ持ち運べるかの「ポータビリティ」。値が大きいほど意味が一方向に決まる軸でそろえています。
| 軸 | PreToolUse Hook | /sandbox | コンテナ/VM隔離 | コミュニティ製Hook集 |
|---|---|---|---|---|
| 隔離の強さ | 弱〜中(コマンド単位で拒否) | 中(BashコマンドのFS・ネットワーク) | 中〜強(コンテナはカーネル共有でmount/通信次第・VM/microVMは別カーネルで最強) | 弱〜中(Hookと同等) |
| 導入の手間 | 小(数行のスクリプト) | 小(コマンド1つで起動) | 中〜大(コンテナ構築) | 小(導入して有効化) |
| ポータビリティ | 高(設定ファイルごと共有) | 中(対応OSに依存) | 高(イメージごと配布) | 高(配布物を取り込むだけ) |
| 向いている場面 | 特定の危険コマンドをピンポイントで止めたい | BashのFS・通信を手早く囲いたい | 未信頼のコードを隔離して走らせたい | 既存の防御を一括で取り込みたい |
PreToolUse Hookは、Claudeがツールを使う直前に割り込んで、コマンドの中身を見て止めるかどうかを判断する仕組み。/sandbox は、Bashコマンドとその子プロセスについて、書き込めるフォルダと通信先をあらかじめ制限する方式です(後述のとおり対象はBash中心で、読み取りの既定は広めなので別途絞り込みが要る)。コンテナ/VMは、作業環境そのものを箱の中に入れて被害範囲を狭めます――ただしDockerなどのコンテナはホストとカーネルを共有し、マウントしたワークスペースはホスト側ファイルとして変更され、コンテナ内に置いた認証情報や許可した通信先にも到達できるため「中なら何でも安全」ではありません。より強い分離が要るならVM/microVMを検討します。コミュニティ製Hook集は、誰かが整備した既存の防御ルールをまとめて取り込む選択肢ですが、Hookはユーザー権限で任意のコマンドを実行できるため、配布元・中身・更新履歴を確認し信頼できる版に固定してから入れます。
迷ったときの選び方
最初から最強の隔離を目指す必要はありません。手間と防御は基本的に比例するからです。
まずPreToolUse Hookを1つ仕込み、rm -rf のような「これだけは絶対に走らせたくない」コマンドを止める。これだけでも典型的な事故の入口は一段減らせます(ただし単純一致はすり抜け得るので、これを最終防衛線にはしない)。次に、ファイルやネットワークまで広く囲いたくなったら /sandbox を足す。さらに、出所の確認できない(未信頼の)リポジトリやスクリプトを動かす段では、コンテナ/VMで丸ごと隔離する。公式は未信頼リポジトリの開始点として専用VMやClaude Code on the webを挙げており、dev container は信頼できるリポジトリ向けの隔離と位置づけています。被害が読めないコードほどVM寄りに、という順番です。必要が出てから隔離を一段ずつ上げる、という流れが無理なく続きます。
自律エージェントを本番運用に出す段階になると、守りの設計は安全だけにとどまらず、暴走範囲やコストをどう抑えるかまで含めた制御設計が前提になってきます。ただ、入口でそこまで身構える必要はない。まずは小さなHook1つから始めるのが現実的です。
自前のPreToolUse Hookを最小構成で書く
4つのうち、いちばん軽くて扱いやすいのがPreToolUse Hook。十数行のスクリプトで、危険なコマンドをピンポイントで止められます。ここでは中身を分解しながら、コピペで動く最小構成を見ていきます。
Hookの登録場所と発火タイミング
Hookは設定ファイル settings.json に登録します。Claude Code公式ドキュメント(2026年6月時点)によると、書式は次の形。matcher で「どのツールに対して」発火するかを指定し、command に実行したいスクリプトのパスを書きます。なお settings.json はユーザー設定・プロジェクト設定・ローカル設定の階層があり、チームで共有するなら下の例のような個人環境依存の絶対パス(/home/user/...)でなく 起点の参照にすると環境差で壊れにくくなります。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/.claude/hooks/block-rm.sh"
}
]
}
]
}
}
matcher に "Bash" を指定すると、ClaudeがBashコマンドを実行しようとするたびに、その直前で block-rm.sh が呼ばれます。「PreToolUse」という名前のとおり、ツールを使う前(Pre)に割り込むタイミング。だから実際にコマンドが走る前に止められる、という理屈です。
危険コマンドを弾く判定ロジックと再試行の挙動
肝心の判定スクリプト。Hookは標準入力(stdin)から、これから実行されるコマンドの情報をJSONで受け取ります。tool_input.command に実際のコマンド文字列が入っているので、そこを見て危険なパターンなら止める、という流れ。
#!/bin/bash
# block-rm.sh — rm -rf を含むコマンドを拒否する最小フック
COMMAND=$(jq -r '.tool_input.command')
if echo "$COMMAND" | grep -q 'rm -rf'; then
echo "rm -rf is blocked by hook" >&2
exit 2
fi
exit 0
ポイントは終了コード(exit code)。公式ドキュメントによれば、exit code 0 は「Hookとしては異議なし」を意味し、通常の権限フローに戻ります。exit code 2 は「ブロック」を意味します。
Exit code 2: Blocking error. stderr is shown and the tool call is stopped. Claude Code 公式ドキュメント(Hooks)
exit code 2 を返すと、標準エラー出力(stderr)に書いたメッセージが表示され、そのツール呼び出しは止まります。公式に確認できるのは「PreToolUseで呼び出しがブロックされ、stderrの内容がClaudeに渡る」という挙動です。Claudeは拒否された理由を受け取れるので、それを手がかりに範囲を絞った別のコマンドへ組み直して続行できる場合があります。止めるだけでなく軌道修正のきっかけを渡せるのが、この方式の効きどころです。より構造化した制御が要る場合は、Hookの標準出力にJSONで判定(許可・確認・拒否)を返す出力形式も公式に用意されています。ただしこのJSONが処理されるのは exit code 0 のときで、exit 2 の場合は stdout のJSONは無視されます(両者を混ぜない)。また PreToolUse Hook が allow を返しても、明示的な deny / ask の権限ルールは上書きできません(denyが優先)。
なお jq はJSONを扱うコマンドラインツール。多くの環境で標準では入っていないため、apt-get install jq などで先に用意しておいてください。
grep 'rm -rf' のような単純なパターンマッチは、スペースの入り方や別名コマンド、変数経由の組み立てなどで簡単にすり抜けます。「Hookを入れたから何でも自律実行して大丈夫」と過信するのは禁物。Hookは「致命的な一発を減らす一層」であって、これ単体を最終防衛線にしないでください。 隔離を強める――/sandbox と Docker の使い分け
Hookはコマンド単位の守りなので、書き込み先のフォルダを丸ごと守ったり、想定外の通信先へのアクセスを止めたり、といった面の防御は苦手です。そこを埋めるのが /sandbox とDocker。封じ込める範囲が一段広くなります。
/sandbox はClaude Codeに組み込まれた機能で、コマンド1つで起動できます。ただし対象範囲に注意が必要で、公式によれば /sandbox がOSレベルで制限するのは「Bashコマンドとその子プロセス」のファイルシステム・ネットワークアクセスです。ビルトインのファイルツールやMCPサーバー、hooksは同じ境界には入りません。Claude Codeプロセス全体(file tools・MCP・hooksを含む)まで囲いたい場合は、コンテナやVMでプロセスごと隔離するか、公式が用意する @anthropic-ai/sandbox-runtime(プロセス全体を囲うサンドボックスランタイム)を使います。ただし @anthropic-ai/sandbox-runtime は現時点では新しい隔離選択肢であり、今後仕様や設定方法が変わる可能性があります。ファイルシステムは、デフォルトで書き込みが作業フォルダとセッション用一時フォルダに制限される一方、読み取りは既定で広く許可され、~/.ssh や ~/.aws/credentials なども読めてしまう場合があります。認証情報を守るには sandbox.filesystem.denyRead で明示的に閉じてください。ただし読み取りを閉じても万全ではありません。サンドボックス下のBashは親プロセスの環境変数を既定で引き継ぐため、APIキーやクラウド資格情報を環境変数で渡していると、ファイル読み取りを塞いでもそちら経由で参照され得ます。資格情報を環境変数に置きっぱなしにしない運用も併せて検討してください。ネットワークはホワイトリスト方式で、許可していないドメインへ初めてアクセスしようとしたときに承認を求めます。
{
"sandbox": {
"enabled": true,
"filesystem": {
"allowWrite": ["/tmp/build"]
},
"network": {
"allowedDomains": ["github.com"]
}
}
}
ただしこの例はそのままコピーしないでください。github.com のような広いドメイン許可は、そこ経由でデータが外に出る抜け道になり得ます。許可先は必要なホストだけに絞り、前述のとおり読み取りも既定では広いので denyRead で ~/.ssh や ~/.aws を閉じる、という組み合わせで初めて実用になります。
注意したいのが対応環境。/sandbox はmacOSとLinux、WSL2(Windows上でLinuxを動かす仕組み)で使えますが、ネイティブのWindowsでは動きません。Windowsの場合はWSL2の中で使う形になります。Linux/WSL2では内部で bubblewrap と socat といった依存が要るため、これらの導入が前提です。さらに重要な落とし穴として、既定ではサンドボックスが使えない環境だと警告を出したうえでサンドボックスなしのままコマンドを実行します。未サンドボックス実行を許したくない場合は、sandbox.failIfUnavailable: true や sandbox.allowUnsandboxedCommands: false で厳格化してください。
もっと広く隔離したいときがコンテナ/VMの出番。Dockerはアプリを「コンテナ」という箱の中で動かす技術で、被害範囲をその箱に寄せられます。ただし前述のとおりコンテナはホストとカーネルを共有し、bind mountしたワークスペースはホスト側ファイルとして変更され、コンテナ内の認証情報や許可した通信先にも到達できます。したがって「箱の中なら何でも安全」ではなく、マウント範囲・秘密情報・通信(egress)の設計が要ります。より強い分離が必要なら、別カーネルで動くVM/microVMが選択肢です。出所の確認できないコードを走らせる、未知のリポジトリを試す、といった被害が読めない場面で効きます。公式には、開発用コンテナ(.devcontainer)構成での分離が案内されています。手元のマシンを汚さずにローカルで安全に試したい場合のコンテナまわりの注意点は、姉妹サイトのCodex CLI 推奨スペック|GPU不要でも要注意なローカルサンドボックスとWindows・Node.js環境でも、ローカルサンドボックスとWindows・Node.js環境の観点から整理しています。
手間と強度は引き換えの関係。/sandbox は起動が手軽な分、対応OSに縛られ、囲える範囲もBash中心です。コンテナはひと手間かかる代わりに被害範囲を箱に寄せられますが、最も強い分離は別カーネルで動くVM/microVM。どれを選ぶかは、守りたい範囲と、どこまで手間をかけられるかのバランスで決めるものです。
まとめ
Claude Codeの守り方は、軽さと隔離の強さのトレードオフで選びます。特定の危険コマンドをピンポイントで止めたいなら自前のPreToolUse Hook。BashのファイルやネットワークをOSレベルで手早く囲いたいなら /sandbox。出所の読めない(未信頼の)コードを動かすなら、公式が第一候補に挙げる専用VMやClaude Code on the webでの隔離(dev containerは信頼できるリポジトリ向け)。既存の防御を一括で取り込みたいならコミュニティ製のHook集(ただし他者製は導入前にレビュー)。これらが主な選択肢で、Claude Codeプロセス全体を囲う公式の @anthropic-ai/sandbox-runtime も加わります。
迷ったら最小から始めるのが堅実。まずPreToolUse Hookを1つ書き、rm -rf のような絶対に走らせたくないコマンドを exit code 2 で止めるところから着手すると、典型的な事故の入口を一段減らせます。そこから、面の防御が要るタイミングで /sandbox を足し、隔離をもっと上げたくなったらコンテナ/VMへ。いずれも単体を最終防衛線にしない、という前提だけは外さずに、必要に応じて一段ずつ守りを重ねていく形が無理なく続きます。最後に一点。Hook・/sandbox・コンテナ/VMはどれも「ローカルで実行されるコマンドの被害範囲」を狭める仕組みであって、Claude Codeが読み込んだプロンプトやファイルの内容がAnthropic API(または設定したプロバイダ)へ送られること自体は別問題です。機密の取り扱いはその前提で設計してください。
よくある質問
Q. Hookとサンドボックスはどちらを先に入れるべきですか?
まずPreToolUse Hookから入れるのがおすすめです。数行のスクリプトで rm -rf のような致命的コマンドを止められ、設定ファイルごとチームで共有もできます。ファイルやネットワークまで広く守りたくなった段階で /sandbox を足す、という順番が手間と効果のバランスが取れます。
Q. PreToolUse Hookだけで自律実行は安全になりますか?
なりません。単純なパターンマッチはスペースの入り方や別名コマンド、変数経由の組み立てですり抜けます。Hookは「致命的な一発を減らす一層」であって最終防衛線ではない、と考えてください。重要な作業や無人実行では、/sandbox 単体ではなく、sandbox runtime・コンテナ・VMなど、Claude Codeプロセス全体を囲える仕組みと組み合わせてください(/sandbox はBashと子プロセス中心で、Claude Code全体を囲うものではありません。未対応環境では既定で警告後に非サンドボックス実行へ落ちるため、sandbox.failIfUnavailable: true での厳格化も検討します)。
Q. コンテナ/VMでの隔離はどんな場面で必要ですか?
出所の確認できないコードや、見知らぬリポジトリのスクリプトを動かすときです。未信頼リポジトリについては、公式も専用VMやClaude Code on the webを第一候補に挙げています。コンテナ(Docker / dev container)は被害範囲を箱に寄せられますが、マウントしたワークスペース・コンテナ内の認証情報・許可した通信先には影響が残り、公式の位置づけも「信頼できるリポジトリ向け」。より強い分離が必要なら別カーネルで動くVM/microVMを使います。逆に、信頼できる自作コードを動かすだけなら、まずはHookや /sandbox で十分なことが多いです。
Q. 既存のコミュニティ製Hook集を使うのと自作はどちらがよいですか?
よくある危険コマンドをまとめて防ぎたいなら既存のHook集が手早く、特定のプロジェクト固有のルールを足したいなら自作が向きます。両立も可能で、既存のHook集で土台を作り、プロジェクトに必要なルールだけ自前のHookで追加する、という重ね方が現実的です。ただしHookはユーザー権限で任意のコマンドを実行できるため、他者製を使うなら配布元・中身・更新履歴を確認し、信頼できる版に固定してから入れてください(無監査のHook集をそのまま安全策にしない)。
参考資料
- Anthropic 公式: Claude Code Hooks リファレンス
- Anthropic 公式: Configure permissions(allow / ask / deny・permission modes)
- Anthropic 公式: Configure the sandboxed Bash tool(/sandbox)
- Anthropic 公式: Choose a sandbox environment(コンテナ / VM の選択)
- Anthropic 公式: Development containers(.devcontainer)

