
Claude初心者がAutoModeでも安心できるセキュリティ設定をしてみた話
はじめに
こんにちは。リテールアプリ共創部の中村です。
Claude Codeを使って開発していると、コマンドを実行するたびに確認プロンプト(Permission Request)が表示され、作業の流れが止まってしまいがちです。この確認を減らし、開発のテンポを大きく上げてくれるのが**自動モード(auto mode)**です。
自動モードには危険な操作を抑止する安全機能が備わっていますが、使い始めた当初は「本当に破壊的な操作を確実に防ぎきれるのか?」という不安がありました。「効率化はしたいけれど、取り返しのつかない破壊的操作だけは絶対に防ぎたい」――そう考え、Claude Codeに実装されているセキュリティ機能の仕様を詳しく調べてみました。
この記事では、自動モードの仕組みを整理したうえで、Claude Codeのセキュリティ機能(hooks・permissions・サンドボックス)を組み合わせた多層防御の設定例をご紹介します。
自動モードでできること
自動モードとは、ユーザーが都度手動でプロンプトを承認する代わりに、独立した分類器(Classifier)モデルがコマンド実行前に各操作のリスクを評価・判定する権限モードです。
ユーザーの指示から逸脱した操作や、想定外のインフラに対する変更、プロンプトインジェクション(ファイルや外部リソースに仕込まれた不正な指示など)の兆候を検知し、自動で実行を中断してくれます。CLI上では Shift + Tab を押すことで手軽にモードを切り替えられます(※利用可能なプランやモデル等の条件は公式ドキュメントをご参照ください)。
初期設定における主な判定の例は以下のとおりです。
| 初期設定でブロックされる例 | 初期設定で許可される例 |
|---|---|
curl | bash など、外部スクリプトを取得してそのまま実行する操作 |
ワークツリー(作業ディレクトリ)内のファイル操作 |
強制プッシュ(git push --force 等) |
ロックファイル等に定義された依存パッケージのインストール |
git reset --hard や git clean -fd など、未コミットの変更を破棄する操作 |
.env を読み取り、該当APIへ認証情報を送信する操作 |
本番環境へのデプロイや cdk destroy などのインフラリソース破壊 |
読み取り専用のHTTPリクエスト(GETなど) |
| 機密データの外部ネットワークへの送信 | 作業ブランチへの通常のプッシュ(git push) |
どこまで防いでくれるのか(限界とリスク)
非常に便利な自動モードですが、公式ドキュメントにも記載があるとおり、これは「確認プロンプトの頻度を減らすための機能」であり、安全性を完全に保証するものではありません。
- AIによる判定の限界
判定を行うのがAI分類器である以上、誤検知やすり抜けを完全にゼロにすることはできません。 - 指示(文脈)の消失リスク
対話の中で「リモートにはプッシュしないで」と伝えていても、会話履歴が圧縮・要約されると、その指示が抜け落ちてしまうリスクがあります(※確実に防ぎたい場合は明示的なdenyルールの併用が推奨されています)。 - 初期設定で許可されている操作の存在
.envの読み取りなど、初期設定のポリシーではそのまま通ってしまう操作も存在します。
つまり、自動モードはあくまで「AIの判断に委ねる確率的な防御層」に過ぎません。プロダクト開発において「絶対に実行されては困る操作」は、ルールとして明文化し、決定論的(確実)にブロックする必要があります。そのための仕組みが、次に紹介する hooks・permissions・サンドボックス です。
参考:権限モードを選択する - Claude Code Docs
Claude Codeのセキュリティ機能
Claude Codeには、実行を制御するための仕組みとして以下の3つが用意されています。
| 機能 | 概要と役割 |
|---|---|
| hooks | コマンド実行直前などに自作のスクリプトを割り込ませ、コマンドの内容を解析して動的に判定します。今回は危険なコマンドを検知した時点で deny を返し、安全な操作のみを通過させる用途で使用します。 |
| permissions | 操作パターンを allow(自動実行)・ask(都度確認)・deny(拒否)の3つで制御するアクセス制御ルールです。評価は deny → ask → allow の優先順位で行われます。 |
| サンドボックス | Claudeが実行するプロセスをOSレベルで隔離し、アクセス可能なファイルやネットワーク通信を制限します。分離のレベルに応じていくつかの選択肢が存在します。 |
サンドボックスの選び方
公式ドキュメントでは、サンドボックスはClaude Codeの実行環境を分離するアプローチの総称として扱われており、分離する範囲に応じて複数の選択肢が用意されています。
| アプローチ | 分離する範囲 | Docker | 導入・運用の手間 |
|---|---|---|---|
Bashサンドボックス(/sandbox) |
Bashプロセスおよびその子プロセス | 不要 | 低 |
| サンドボックスランタイム | Claude Codeのプロセス全体(Read/Editツール、MCP、hooks等) | 不要 | 低〜中 |
| DevContainer / カスタムコンテナ | 開発環境全体 | 必要 | 中〜高 |
| 仮想マシン(VM) | OS全体 | 不要 | 高 |
| Web版 Claude Code | OS全体(Anthropicホスト環境) | 不要 | なし |
下に行くほど保護できる範囲は広がりますが、コンテナの構築やマウント設定、環境維持の手間などの負担も大きくなります。
参考:サンドボックス環境を選択する - Claude Code Docs
今回「Bashサンドボックス」を採用した理由
- ローカルで画面を見ながら作業するスタイルに合っている
ドキュメントでも、日常の開発で確認プロンプトを減らしたい場合の第一候補としてBashサンドボックスが推奨されています。確認を完全にスキップする--dangerously-skip-permissionsを使う場合はコンテナによる厳格な隔離が必須ですが、自動モードにおけるサンドボックスは「追加の防御層」という位置付けです。そのため、今回は環境丸ごとのコンテナ化までは不要と判断しました。 - 導入の手間が少なく、Dockerも不要
macOS環境であれば追加のソフトウェアなしで動作し、settings.jsonに数行追加するだけで有効化できます。まずは小さく試してみたい段階に最適です。 - 組織の設定としてチームに強制できる(managed settings)
上記の選択肢のうち、Claude Code自身の設定配信によってチーム全体へ一括適用を強制できるのはBashサンドボックスです。DevContainerもリポジトリ単位で環境定義を共有できますが、ローカル環境で「コンテナの外で動かすこと」自体を防ぐのは難しいためです。
割り切った点
Bashサンドボックスが隔離するのはあくまでBashコマンドの実行プロセスのみです。Claudeの組み込みツール(FileRead、FileEdit、WebFetch など)はサンドボックスの対象外となり、permissions のルールによって制御されます。また、MCPサーバーやhooksスクリプト自体はホストOSのユーザー権限で直接実行されます。
そのため、「Bashサンドボックスでカバーできない範囲は、permissionsとhooksを組み合わせて塞ぐ」というのが今回の設計方針です。将来さらなる安全性を求めたくなった場合は、DevContainerの内側でBashサンドボックスを併用する多重化も可能です。
3つの機能の役割分担
今回採用した「Bashサンドボックス」「permissions」「hooks」の役割分担を整理すると、以下のようになります。
(◎=主な役割、○=対応、△=スクリプト等の追加実装が必要、✕=対象外)
| 項目 | Bashサンドボックス | permissions | hooks |
|---|---|---|---|
| ファイルアクセスの制限 | ○(Bash経由のみ) | ○(組み込みツール) | △ |
| ネットワーク通信の制限 | ○(Bash経由のみ) | ○(組み込みツール) | △ |
| 実行可否の判定 | △(間接的なOSエラー) | ◎ | ○ |
| コマンド内容の構文解析 | ✕ | ✕ | ◎ |
| チームへのルール強制 | ○ | ○ | ○ |
| 対応OS | macOS / Linux / WSL2 | 全OS | 全OS |
| メンテナンスの手間 | 低 | 低 | 中〜高 |
これらはどれか1つを選べばよいというものではなく、防ぐ対象も動くタイミングも異なるため、組み合わせて初めて多層防御として機能します。なお、Bashサンドボックスは初期状態では無効になっているため、/sandbox コマンドか設定ファイルの sandbox.enabled で明示的に有効化する必要があります。
実行ライフサイクルと評価される順序
以下は公式ドキュメントに掲載されている、Claude Codeのコマンド実行ライフサイクルです。ツール実行の流れ(PreToolUse → PermissionRequest → [tool executes])に、今回導入した3つの機能がそれぞれ対応しています。

出典:Hooks reference - Claude Code Docs
- PreToolUse(hooksによる解析)
登録したスクリプトがコマンド実行の直前に割り込みます。仕様上はallow/deny/askを返せますが、今回は「危険なコマンドを検知した時点で即座にdenyで遮断し、安全な操作のみを通過させる」というシンプルな実装にしています。ここでdenyされた場合、処理はその場で中断され、以降のステップには進みません。 - PermissionRequest(permissionsおよびAI分類器による評価)
PreToolUseを通過したコマンドに対し、設定したpermissions(deny→ask→allowの優先順)が適用されます。git commitやgit pushなどaskに設定したコマンドは、ここで確認プロンプトが表示されます。なお、hooks側がallowを返していても、permissions側でaskに該当していれば確認プロンプトが出ます(hooksの判定でpermissionsの制限を打ち消すことはできません)。 - [tool executes](サンドボックス環境下での実行)
実際にコマンドが実行されるフェーズです。Bashコマンドの場合、ここでOSレベルのBashサンドボックスが機能します。万が一hooksやpermissionsをすり抜けるようなコマンドがあっても、機密ファイルの読み取りや不正なディレクトリへの書き込みはOSレベルで遮断されます。
つまり、「hooksとpermissionsは実行前に論理的に止めるフィルター」「Bashサンドボックスは実行時の物理的なアクセスを制限する最後の砦」という順序で多層防御を構成しています。
※自動モードを利用している場合、ステップ2(PermissionRequest)ではプロンプトを出す代わりにAI分類器が判定を行いますが、明示的に ask ルールに設定した操作については自動モード下でも必ず人間の確認プロンプトが表示されます。
参考:
設定ファイル(settings.json)
実際に ~/.claude/settings.json(グローバル設定)に記述している内容の抜粋です。
{
"permissions": {
"allow": [
"Bash(gh *)",
"Bash(git fetch *)",
"Bash(git pull *)"
],
"ask": [
"Bash(git commit *)",
"Bash(git push *)"
]
},
"sandbox": {
"enabled": true,
"filesystem": {
"denyRead": [
"**/.env", "**/.env.*",
"~/dev/**/.env", "~/dev/**/.env.*"
// ほかにもSSH秘密鍵やAWS認証情報などを同様のパターンで追加
],
"allowRead": [
"**/.env*.example",
"~/dev/**/.env*.example"
]
}
},
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "python3 ~/.claude/hooks/block-destructive-bash.py"
}
]
}
]
}
}
permissions.allow:ghコマンドやgit fetch、git pullなど、環境を破壊するリスクのないコマンドを登録し、確認なしで自動実行させます。permissions.ask:git commitやgit pushなど、実行前に人間が内容を確認したいコマンドは毎回確認プロンプトを出します。sandbox.filesystem:.envや秘密鍵などの機密ファイルへのアクセスを拒否します。hooks.PreToolUse:Bash実行直前にPythonスクリプトを実行し、破壊的コマンドを検知します。目視確認だけでは見落とすリスクのある本当に危険な操作を、一律で弾きます。
hooksスクリプトで遮断するコマンド一覧
フック用のPythonスクリプトで検知・遮断している主なコマンドです。
| 対象コマンド | ブロックする理由 |
|---|---|
git reset --hard |
未コミットの変更をすべて破棄してしまうため |
git clean -f(強制削除オプション) |
バージョン管理外のファイルを完全に削除してしまうため |
git checkout . / git restore . |
ワークツリー全体の差分を一括破棄してしまうため |
git branch -D(強制削除) |
未マージのコミットを失ってしまう可能性があるため |
git push --force / --force-with-lease / -f |
指定ブランチを問わず、リモートのコミット履歴を上書きしてしまうため |
--no-verify / --no-gpg-sign / git -c commit.gpgsign=false |
コミット前のフックや署名検証を意図せずスキップしてしまうため |
スコープの広すぎる rm -rf(/、~、ホーム直下のワイルドカードなど) |
想定外の広範囲なファイルを一括削除してしまうため |
gh repo delete |
リモートのGitHubリポジトリ自体を削除してしまうため |
gh secret delete / gh variable delete |
CI/CDに必要なシークレットや環境変数を削除してしまうため |
gh release delete / gh gist delete / gh ssh-key delete 等 |
取り消しが困難なリソース削除操作のため |
gh api -X DELETE / --method DELETE |
専用コマンドを通さず、API経由で直接リソースを削除できてしまうため |
なお、このスクリプトは単なる文字列の一致だけでなく、クォートによる文字列の分断('g'it や "rm")、エイリアスの利用、オプションの順序の入れ替え、bash -c や sh -c によるサブシェル実行、sudo や eval でのラップといった、典型的な検知回避の手口にも対応できるようにコマンドを分解・解析しています。
設定手順
- Permissionsの設定
~/.claude/settings.jsonを開き、安全なコマンドをpermissions.allowに、人間が確認したい操作をpermissions.askに追加します。 - サンドボックスのファイルアクセス制限
同ファイルのsandbox.filesystemにdenyRead(読み取り拒否パターン)とallowRead(例外許可パターン)を設定します。開発ディレクトリ配下の全プロジェクトに適用したい場合は、**/.envだけでなく~/dev/**/.envのように起点パスを明示すると確実です。 - hooksスクリプトの配置
~/.claude/hooks/ディレクトリを作成し、破壊的コマンドを検知するPythonスクリプトを配置してchmod +xで実行権限を付与します。 - Hookの紐付け
settings.jsonのhooks.PreToolUseに、作成したスクリプトを呼び出す設定を追加します。 - 設定の反映と動作テスト
Claude Codeセッションを再起動して設定を読み込ませます。必ず使い捨ての検証用ディレクトリを用意し、危険なコマンドが意図通りブロックされるか、機密ファイルの読み取りがOSレベルで弾かれるかをテストします。
実装によって得られたメリット
- 明確なポリシー分担の確立
「安全なコマンドは自動実行」「要確認の操作は人間が承認」「破壊的な操作は強制遮断」というルールを、それぞれpermissions.allow・permissions.ask・hooksの3つに綺麗に割り当てることができました。 - 単純なパターンマッチをすり抜ける危険操作の防止
permissions.denyによる単純な文字列一致では、引数の順序変更やサブシェル経由の実行等ですり抜けてしまう弱点があります。スクリプトを用いた構文解析を挟むことで、表記揺れや回避手口にも耐えうるガードレールを構築できました。 - プロジェクト横断での確実な機密情報保護
Bashサンドボックスを活用することで、cat .envのようなコマンドによる機密情報の漏洩を、開発ディレクトリ配下の全プロジェクトに対して一括で制限できるようになりました。 - 開発効率と安全性の両立
自動モードの快適さを活かしつつ、クリティカルな操作に対しては決定論的なブロックを担保することで、安心してAIエージェントに開発を任せられる環境が整いました。
残る限界・スコープ外としたこと
- 動的な環境変数展開やコマンド置換の検知
例えばCMD="reset --hard"; git $CMDのように、実行時に動的に組み立てられる変数は静的解析の段階では検知できません。これはシェルスクリプトの仕様上、避けられない限界といえます。 - gitやrm以外の削除コマンド
find -deleteや Pythonのshutil.rmtreeなど、ファイルを削除する手段は無数に存在します。これらをスクリプト側ですべて網羅するのは現実的ではないため、ファイルアクセスの権限やサンドボックス側の制限に委ねる設計としています。
おわりに
手作業でコードを書いていた時代は「自分が打つコマンドは自分が責任を持つ」で済みましたが、AIエージェントに自律的なコマンド実行を任せる現在においては、「何をAIに任せ、どこで人間が判断し、何をシステムとして確実に遮断するか」という権限境界の設計が欠かせません。
Claude Codeの確認プロンプトの多さに悩んでいる方や、自動モードを導入したいけれど安全性が心配という方の参考になれば幸いです。







