Fragments of verbose memory

冗長な記憶の断片 - Web技術のメモをほぼ毎日更新

Feb 12, 2026 - 日記

エージェント時代の"sudoers"を作る:Claude Code Damage Controlの設計を読む

claude-code-damage-control-pretooluse-hooks cover image

AIエージェントに権限を渡す前に、何を守るべきか。

Claude Code のようなAIコーディングアシスタントは、ファイルの編集やシェルコマンドの実行を自律的に行います。便利な反面、rm -rf /のような破壊的な操作や、機密ファイルへの意図しないアクセスが現実のリスクになっています。

Claude Code Damage Control は、こうした事故を防ぐための「強制ガードレール」です。PreToolUseフック(ツール実行前に割り込める仕組み)を使い、危険なコマンドやパス操作を検知して、実行前にブロックまたは確認ダイアログへ誘導します。

感覚としては、エージェント時代のsudoers(sudoの許可ルール定義)を作る、に近いです。

Claude Code Damage Controlとは

Claude Code Damage Controlは、Claude Code向けのオープンソース(MIT)セキュリティ拡張です。PreToolUseフックという仕組みを使い、AIエージェントがツールを実行する直前に介入します。

主な機能

  • 危険コマンドのブロック: rm -rfchmod 777、WHERE句なしのDELETEなど
  • パス保護: SSH鍵、AWS認証情報、システムファイルへのアクセス制御
  • 確認ダイアログ: リスクはあるが正当な操作(特定IDへのDELETE等)は確認後に許可
  • YAML設定: ポリシーをコードとして管理可能

仕組み

Claude Codeは、ツール実行前にPreToolUseフック を呼び出します。Damage Controlはこのフックで以下を実行します:

  1. ツール名と入力パラメータをJSON形式で受け取る
  2. patterns.yamlに定義されたルールと照合
  3. 終了コード(exit code)で判定を返す(0=許可、2=ブロック、JSON出力=確認)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
┌─────────────────────────────────────────────────────────────────────┐
│                   Claude Code Tool Call                              │
└─────────────────────────────────────────────────────────────────────┘
          ┌─────────────────────┼─────────────────────┐
          ▼                     ▼                     ▼
    ┌───────────┐         ┌───────────┐         ┌───────────┐
    │   Bash    │         │   Edit    │         │   Write   │
    │   Tool    │         │   Tool    │         │   Tool    │
    └─────┬─────┘         └─────┬─────┘         └─────┬─────┘
          │                     │                     │
          ▼                     ▼                     ▼
┌─────────────────┐   ┌─────────────────┐   ┌─────────────────┐
│ bash-tool-      │   │ edit-tool-      │   │ write-tool-     │
│ damage-control  │   │ damage-control  │   │ damage-control  │
└────────┬────────┘   └────────┬────────┘   └────────┬────────┘
         │                     │                     │
         ▼                     ▼                     ▼
   exit 0 = allow        exit 0 = allow        exit 0 = allow
   exit 2 = BLOCK        exit 2 = BLOCK        exit 2 = BLOCK
   JSON   = ASK

パス保護の3段階設計

Damage Controlは、パスごとに異なる保護レベルを設定できます。すべてpatterns.yamlで管理します。

1. zeroAccessPaths(完全アクセス禁止)

読み取りも書き込みも一切禁止。秘密鍵や認証情報など、触れてはいけないファイルを指定します。

1
2
3
4
zeroAccessPaths:
  - ~/.ssh/
  - ~/.aws/
  - ~/.gnupg/

適用ツール: Bash、Edit、Write

2. readOnlyPaths(読み取り専用)

読み取りは許可、変更・削除は禁止。システム設定ファイルなどに使います。

1
2
3
4
readOnlyPaths:
  - /etc/
  - ~/.bashrc
  - ~/.zshrc

適用ツール: Bash、Edit、Write

3. noDeletePaths(削除のみ禁止)

読み取り・書き込み・編集は許可、削除だけ禁止。重要なプロジェクトファイルを守ります。

1
2
3
noDeletePaths:
  - .claude/hooks/
  - .claude/commands/

適用ツール: Bashのみ

保護マトリクス

操作zeroAccessPathsreadOnlyPathsnoDeletePaths
Read (cat)✅ ブロック❌ 許可❌ 許可
Write (>)✅ ブロック✅ ブロック❌ 許可
Edit (sed -i)✅ ブロック✅ ブロック❌ 許可
Delete (rm)✅ ブロック✅ ブロック✅ ブロック

危険コマンドパターンの定義

Bashツール向けには、正規表現で危険なコマンドパターンを定義できます。

ブロックパターン

1
2
3
4
5
6
7
bashToolPatterns:
  # 完全ブロック
  - pattern: '\brm\s+-[rRf]'
    reason: rm with recursive or force flags

  - pattern: '\bDELETE\s+FROM\s+\w+\s*;'
    reason: DELETE without WHERE clause

確認パターン(Ask)

ask: trueを付けると、ブロックではなく確認ダイアログを表示します。

1
2
3
4
5
bashToolPatterns:
  # 確認を求める
  - pattern: '\bDELETE\s+FROM\s+\w+\s+WHERE\b.*\bid\s*='
    reason: SQL DELETE with specific ID
    ask: true

動作例:

1
2
3
4
5
# ブロックされる(WHERE句なし
DELETE FROM users;

# 確認ダイアログが表示される(WHERE句あり
DELETE FROM users WHERE id = 1;

実際の導入手順

前提条件

  • Claude Codeがインストール済み
  • Python実行環境(uv 推奨。Pythonツールチェーンをまとめて扱うCLI)またはBun/TypeScript環境

手動インストール(Python/UV版)

以下の手順で、プロジェクトローカルにDamage Controlを導入します。

1. UVのインストール

このコマンドはスクリプトをダウンロードして実行します。気になる場合は、URLを開いて中身を確認してから実行してください。

1
curl -LsSf https://astral.sh/uv/install.sh | sh

2. リポジトリをクローン

1
2
git clone https://github.com/disler/claude-code-damage-control.git
cd claude-code-damage-control

3. フックファイルをプロジェクトにコピー

プロジェクトディレクトリで以下を実行します。

1
2
3
4
cd /path/to/your/project
mkdir -p .claude/hooks/damage-control
cp /path/to/claude-code-damage-control/.claude/skills/damage-control/hooks/damage-control-python/*.py .claude/hooks/damage-control/
cp /path/to/claude-code-damage-control/.claude/skills/damage-control/patterns.yaml .claude/hooks/damage-control/

4. settings.local.jsonを作成

.claude/settings.local.jsonに以下を記述します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [{
          "type": "command",
          "command": "uv run \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/damage-control/bash-tool-damage-control.py",
          "timeout": 5
        }]
      },
      {
        "matcher": "Edit",
        "hooks": [{
          "type": "command",
          "command": "uv run \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/damage-control/edit-tool-damage-control.py",
          "timeout": 5
        }]
      },
      {
        "matcher": "Write",
        "hooks": [{
          "type": "command",
          "command": "uv run \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/damage-control/write-tool-damage-control.py",
          "timeout": 5
        }]
      }
    ]
  }
}

5. Claude Codeを再起動

設定を反映させるため、Claude Codeを再起動します。

6. 動作確認

Claude Codeで以下のように指示してみます。

1
delete all files in /tmp/test recursively

正しく設定されていれば、rm -rfがブロックされ、エラーメッセージが表示されます。

スキルベースのインストール(推奨)

Damage Controlには、インタラクティブなインストールワークフローを提供するClaude Code Skill が同梱されています。

スキルをインストール後、Claude Codeで以下のように指示するだけです。

1
install the damage control system

スキルが以下を対話的に案内します:

  • インストール場所の選択(グローバル/プロジェクト/個人)
  • ランタイムの選択(Python/UV または TypeScript/Bun)
  • 既存設定の扱い

設定のカスタマイズ

patterns.yamlの編集

プロジェクト固有のルールを追加できます。

1
2
3
4
5
6
7
8
9
bashToolPatterns:
  # プロジェクト固有のブロック
  - pattern: '\bnpm\s+publish'
    reason: Prevent accidental npm publish

zeroAccessPaths:
  # プロジェクトの機密ファイル
  - .env
  - config/secrets.yml

グローバル vs プロジェクトフック

場所スコープ用途
~/.claude/settings.json全プロジェクトベースライン保護
.claude/settings.json単一プロジェクトプロジェクト固有ルール

重要: グローバルとプロジェクトのフックは並列実行されます。どちらか一方がブロックすれば、コマンドは実行されません。

テスト方法

インタラクティブテスター

実際のフックを動かさずに、パターンマッチングをテストできます。

1
2
cd .claude/skills/damage-control/hooks/damage-control-python
uv run test-damage-control.py -i

実行例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
============================================================
  Damage Control Interactive Tester
============================================================

Select tool to test:
  [1] Bash  - Test shell commands
  [2] Edit  - Test file paths for edit operations
  [3] Write - Test file paths for write operations
  [q] Quit

Tool [1/2/3/q]> 1

Command> rm -rf /tmp/test

BLOCKED - 2 pattern(s) matched:
   - rm with recursive or force flags
   - rm with recursive or force flags

Tool [1/2/3/q]> 2

Path> ~/.ssh/id_rsa

BLOCKED - 1 pattern(s) matched:
   - zero-access path: ~/.ssh/

CLIテスト

個別のコマンドを直接テストできます。

1
2
3
4
5
# rm -rfがブロックされることを確認
uv run test-damage-control.py bash Bash "rm -rf /tmp" --expect-blocked

# 安全なコマンドが許可されることを確認
uv run test-damage-control.py bash Bash "ls -la" --expect-allowed

実運用での設計パターン

1. ポリシーをYAMLで管理

patterns.yamlをGit管理下に置き、チームで共有します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# チーム共通のベースライン
zeroAccessPaths:
  - ~/.ssh/
  - ~/.aws/
  - .env

# プロジェクト固有
readOnlyPaths:
  - terraform/prod/
  - k8s/production/

2. ブロックと確認の線引き

  • 完全ブロック: 絶対に実行してはいけない操作(rm -rf /、WHERE句なしDELETE)
  • 確認ダイアログ: リスクはあるが正当な場合もある操作(特定IDへのDELETE、本番DBへの接続)
1
2
3
4
5
6
7
8
9
bashToolPatterns:
  # ブロック
  - pattern: '\bDELETE\s+FROM\s+\w+\s*;'
    reason: DELETE without WHERE clause

  # 確認
  - pattern: '\bDELETE\s+FROM\s+\w+\s+WHERE\b.*\bid\s*='
    reason: SQL DELETE with specific ID
    ask: true

3. 多層防御との組み合わせ

Damage Controlは「最後の砦」ではなく、多層防御の一部として位置づけます。

  • Gitフック: コミット前のチェック(pre-commit)
  • 権限分離: 本番環境へのアクセスは別アカウント
  • サンドボックス: Docker/VM内でAIエージェントを実行
  • Damage Control: 上記をすり抜けた操作をブロック

まとめ

Claude Code Damage Controlは、AIエージェントに権限を渡す際の「強制ガードレール」です。

  • PreToolUseフックで実行前に介入
  • 3段階のパス保護(完全禁止/読み取り専用/削除禁止)
  • 正規表現パターンで危険コマンドをブロック
  • 確認ダイアログでリスクと利便性のバランスを取る

エージェント時代の"sudoers"として、YAMLでポリシーを定義し、チームで共有できる設計になっています。

AIエージェントを安全に運用するための第一歩として、導入を検討してみてください。

参考リンク