はじめに — 承認プロンプトは本当に必要か

Claude Codeを日常的に使っていると、承認プロンプトの多さに悩まされることがあります。ファイルの読み書き、コマンドの実行、外部APIの呼び出し——あらゆる操作で「許可しますか?」と問われ、そのたびに手を止めて「Yes」を押す作業が発生します。

この承認プロンプトは、本当にセキュリティに貢献しているのでしょうか

1セッションで50回以上の承認プロンプトが表示される環境では、多くの場合、内容を確認せずに反射的に「Yes」を押す習慣がついてしまいます。これはセキュリティの世界でアラート疲れ(Alert Fatigue)と呼ばれる現象です。NIST(米国国立標準技術研究所)のサイバーセキュリティフレームワークでも、過剰なアラートが防御態勢を弱体化させるリスクが指摘されており、適切なアラート設計が推奨されています。過剰な承認はむしろセキュリティを低下させるという逆説的な結果を招くのです。

本記事では、承認プロンプトをゼロにしながらセキュリティを維持するdeny-firstアーキテクチャの設計方法を解説します。この設計思想は、NISTが提唱するゼロトラスト・アーキテクチャ(SP 800-207)の「暗黙の信頼を排除し、明示的なポリシーで制御する」という原則と軌を一にしています。セキュリティリスクの評価についてはAIコーディングツールの「承認ゼロ運用」を支えるセキュリティ設計を、障害発生時のバックアップ体制についてはCloudflareサービスの障害復旧完全ガイドをあわせてご覧ください。

deny-firstアーキテクチャとは何か

Claude Codeの権限モデルは、deny → ask → allowの評価順序で設計されています。denyルールに該当する操作はAIの判断に関係なく100%ブロックされ、いかなるallowルールやHooksでも覆すことができません。

この設計を活用し、「危険な操作をdenyで絶対的にブロックし、それ以外をallowで自動承認する」のがdeny-firstアーキテクチャです。

従来の承認モデルとの比較を整理します。

従来モデル(人間が毎回判断) では、すべての操作に対して人間が「安全か危険か」を判断します。この判断は確率的であり、疲労や慣れによって精度が低下します。1日に数百回の判断を求められれば、いずれ見落としが発生します。

deny-firstモデル(ルールが自動判断) では、危険な操作は機械的にブロックされ、安全な操作は機械的に承認されます。この判断は決定論的であり、100万回実行しても同じ結果を返します。人間の疲労や見落としの影響を受けません。

三段階の安全境界を設計する

deny-firstアーキテクチャは、3つの安全境界で構成されます。

第1層 — 絶対禁止(denyルール)

「何があっても実行してはならない操作」 を定義します。deny ルールはAIの判断に依存せず、パターンマッチで100%ブロックする決定論的制御です。

設定すべきdenyルールは、大きく5つのカテゴリに分類できます。

破壊的コマンドの防止として、rm -rfrm -fr など、ファイルシステムを不可逆に破壊するコマンドをブロックします。Claude Code自体にも破壊的操作に対する内部的な安全制約がありますが、これはLLMの判断に依存する確率的な防御です。denyルールによる決定論的なブロックを追加することで、二重の防御になります。

機密ファイルの保護として、.envファイルや認証情報ファイルへのアクセスをブロックします。Claude Codeの承認設定を最適化するで解説した権限モデルの知識が、ここで直接役立ちます。

データ流出経路の遮断として、curlwgetなど、外部にデータを送信できるコマンドをブロックします。正規のWebアクセスはClaude CodeのWebFetchツールを使うことで、セキュリティフィルタを経由した安全なアクセスに限定できます。

危険なGit操作の防止として、git push --force(リモート履歴の不可逆な破壊)やgit reset --hard(未コミット変更の消失)をブロックします。

シェルバイパスの遮断として、PowerShellやcmdなど、ファイルシステム制限を迂回できるシェルへのアクセスをブロックします。

以下は、これらのカテゴリを網羅した設定例です:

{
  "permissions": {
    "deny": [
      "Bash(rm -rf *)",
      "Bash(rm -fr *)",
      "Bash(curl *)",
      "Bash(wget *)",
      "Bash(powershell*)",
      "Bash(cmd *)",
      "Bash(git push --force*)",
      "Bash(git push -f *)",
      "Bash(git reset --hard*)",
      "Read(.env*)",
      "Edit(.env*)",
      "Write(.env*)"
    ]
  }
}

ワイルドカード * を使うことで、引数のバリエーションを網羅的にブロックできます。denyルールのパターンマッチ仕様の詳細はConfigure permissions公式ドキュメントで確認できます。

第2層 — 自動承認(allowルール)

denyに該当しないすべての操作を自動承認します。Claude Codeのallowルールは、ツール名を指定子なしで記述するとブランケット許可として機能します。たとえば "Bash" と記述すれば、deny ルールに該当しないすべてのBashコマンドが自動承認されます。

{
  "permissions": {
    "allow": [
      "Bash",
      "Read",
      "Edit",
      "Write",
      "Glob",
      "Grep",
      "WebFetch",
      "WebSearch",
      "Agent",
      "mcp__*"
    ]
  }
}

ファイルの読み書き、Gitの通常操作、ビルド・デプロイコマンド、Web検索、MCPツールなど、日常的な開発操作のすべてをallowに含めることで、承認プロンプトの発生をゼロにします。mcp__* のようなワイルドカード指定で、MCPサーバー経由のツールを一括許可することも可能です。

第3層 — 監査ログ(Hooks)

承認プロンプトをゼロにしても、何が実行されたかの記録は残すべきです。Claude CodeのHooks機構を使い、PostToolUseイベントで全操作をJSONL形式のログファイルに自動記録します。

以下はHooksの設定例です:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "*",
        "command": "echo '{ \"ts\": \"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'\", \"tool\": \"'$CLAUDE_TOOL_NAME'\", \"input\": \"'$CLAUDE_TOOL_INPUT'\" }' >> ~/logs/claude-audit.jsonl"
      }
    ]
  }
}

これにより、以下のようなJSONL形式の監査ログが自動的に蓄積されます:

{"ts":"2026-03-31T06:30:00Z","tool":"Bash","input":"npm run build"}
{"ts":"2026-03-31T06:30:05Z","tool":"Write","input":"/src/index.ts"}
{"ts":"2026-03-31T06:30:10Z","tool":"Bash","input":"npm run deploy"}

Hooksは「LLMの判断に依存しない決定論的制御」(サンドボックスと同様の確実性を持つ仕組み)を実現する機構であり、設定されたイベントに対して100%確実に発火します。問題が発生した場合、監査ログから操作の時系列を正確に再構築できます。

Hooksの詳細についてはAnthropic公式のHooksドキュメントを参照してください。また、Hooksを使ってAIスタッフごとに実行権限を動的に制御する方法をAIスタッフに鍵を持たせる — Claude Codeのhook機構で実現するAI間権限管理で詳しく解説しています。

設定ファイルの4層階層を活用する

Claude Codeの設定ファイルは、Enterprise(最高優先度)→ Project → User → CLI引数(最低優先度)の階層で構成されています。設定の適用優先度についての最新仕様はClaude Code Settings公式ドキュメントで確認できます。

deny/allowルールが複数の層に存在する場合、配列は**マージ(結合+重複排除)**されます。そして重要な原則として、あるレベルでdenyされたツールは、いかなる下位レベルでもallowできません

この階層構造を活用した実践的な設定例を示します:

Enterprise Settings(組織全体のセキュリティポリシー):

{
  "permissions": {
    "deny": ["Bash(rm -rf *)", "Bash(curl *)", "Bash(wget *)"]
  }
}

Project Settings(.claude/settings.json):

{
  "permissions": {
    "deny": ["Bash(git push --force*)", "Read(.env*)"],
    "allow": ["Bash", "Read", "Edit", "Write"]
  }
}

User Settings(~/.claude/settings.json):

{
  "permissions": {
    "allow": ["WebFetch", "WebSearch", "Agent", "mcp__*"]
  }
}

Enterprise Settingsで組織全体の破壊的コマンドを禁止し、Project Settingsでプロジェクト固有のdeny/allowを定義し、User Settingsで個人の作業スタイルに応じたツール許可を追加する——この多層構成が実現できます。

段階的に導入する — 移行パス

いきなり全操作を承認ゼロにするのは不安がある場合、段階的な移行パスを推奨します。

Phase 1: 観察期間(1〜2週間) まずHooksのみを設定し、現在の承認パターンを監査ログで可視化します。どの操作に何回承認が発生しているかを把握することが目的です。

Phase 2: 安全な操作からallowに追加 ReadGlobGrep などの読み取り専用操作をallowに追加します。これらはファイルシステムを変更しないため、リスクが最小です。

Phase 3: denyルールを確定してからBash/Write/Editをallow 第1層で解説した5カテゴリのdenyルールを設定し、その上でBashWriteEdit をallowに追加します。denyルールが正しく機能していることをテスト(意図的に rm -rf を試行してブロックされることを確認)してからallowを有効にします。

Phase 4: 承認ゼロ達成・監査ログで継続監視 全ツールをallowに追加し、承認プロンプトがゼロになったことを確認します。以降は監査ログの定期レビューで異常を検知します。

バックアップ体制との組み合わせ

deny-firstアーキテクチャは「危険な操作をブロックする」予防的制御ですが、denyの境界外で問題が発生する可能性は残ります。このリスクをカバーするのがバックアップ体制です。

Cloudflareの各サービスには、問題発生時に迅速に復旧できる仕組みが備わっています。Workers Versions & Deploymentsでは100バージョンの保持とワンコマンドロールバックが可能です。D1のTime Travel機能では30日間のPoint-in-Time Recoveryをサポートしており、任意の時点のデータに復元できます。Pagesは全デプロイ履歴からの即時ロールバックをサポートしています。

「denyで予防し、allowで自動化し、Hooksで記録し、バックアップで復旧する」——この4つの組み合わせが、承認ゼロ運用の完全な安全アーキテクチャです。技術的な復旧手順の詳細はCloudflareサービスの障害復旧完全ガイドで解説しています。

「スマート承認ゼロ」の設計原則

最後に、承認ゼロ運用を設計する際の原則をまとめます。

denyは狭く、深く設定することが重要です。ブロックすべき操作を正確に特定し、それ以外は積極的にallowします。denyが広すぎると作業効率が落ち、狭すぎるとセキュリティに穴が開きます。破壊的コマンド、機密ファイル、データ流出経路、危険なGit操作、シェルバイパス——この5カテゴリを網羅すれば、実用上の安全性は十分に確保できます。

allowはブランケットで設定することで、個別の操作を1つずつ許可する煩雑さを排除します。「ツール名のみ指定(specifierなし)」のallowルールが、その実現手段です。

監査ログは必ず残すことで、承認プロンプトなしでも「何が起きたか」を事後検証できる状態を維持します。ログの存在自体が、問題の早期発見と迅速な復旧を可能にします。

バックアップは承認ゼロの前提条件です。「問題が起きても元に戻せる」という保証があるからこそ、予防的制御(deny)の境界外のリスクを受容できます。バックアップなしの承認ゼロ運用は推奨しません。

承認プロンプトは、セキュリティのための儀式ではなく、リスク管理の手段の一つにすぎません。deny-firstアーキテクチャは、その手段をより確実で効率的なものに置き換える設計パターンです。

関連リソース