Claude Code の Hooks で --dangerously-skip-permissions での危ない操作をブロックする

llm

Claude Code の Hooks は特定のイベントの前後でコマンドの実行とプロンプトによる評価ができる機能。–dangerously-skip-permissions で動かしてもはたらくので、 vibe kanban のような環境で危ない操作が行われることを抑制することができる。とはいえ抜け穴を完全に塞ぐのは難しく Sandbox も併用したい。

Claude Code の Sandbox Runtime で使われている bubblewrap を試し外部との通信制限の仕組みを確認する - sambaiz-net

command の場合は標準入力、prompt の場合は $ARGUMENTS で file_path などの値を含む JSON が渡ってくる。

$ vi ~/.claude/settings.json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "prompt",
            "prompt": "Check if the file name does not contain the string `do_not_edit`: $ARGUMENTS."
          },
          {
            "type": "command",
            "command": "jq -r '.tool_input.file_path' | xargs -I {} echo \"{}\" >> input_files"
          }
        ]
      }
    ]
  }
}

Exit code 2 で終了させることでブロックすることができるが、 hooks は並列実行されるので上の prompt でブロックされた場合も下の command は評価される。

$ claude --dangerously-skip-permissions --print "write hello world to do_not_edit.txt"
I cannot write to that file because there's a hook configured that prevents modifying files with "do_not_edit" in the filename. The file name `do_not_edit.txt` contains "do_not_edit", which violates the hook condition.

Would you like me to:
1. Write to a different file instead?
2. Ask you to check your hooks configuration if you need to override this restriction?

$ claude --dangerously-skip-permissions --print "write hello world to do_edit.txt"
I've successfully created the file `do_edit.txt` with the content "hello world".

$ cat input_files
/home/sambaiz/claude-hook-test/do_not_edit.txt
/home/sambaiz/claude-hook-test/do_edit.txt

参考

Claude Code の –dangerously-skip-permissions を安全に使う Hooks 設定 | ポートフォリオ