CLAUDE LABEN
2.1.278 — auto モードの分類器が Claude API・Enterprise・Bedrock / Vertex / Foundry でサーバー側の既定になりました。分類器の分は課金されず、/status に Auto mode server の行が増えていますTASKOUT — TaskOutput ツールが削除されました。taskOutputMaxChars と TASK_MAX_OUTPUT_LENGTH は無効になり、バックグラウンドの出力は Read で読む形に一本化されています10/07 — 管理構成キーの旧い綴りの受付は10月7日 正午 PT までです。残り17日で、締切を過ぎた設定は書き直すまでそのコネクタが使えなくなりますBUNPANIC — 更新で入った版が、起動しただけで落ちるという報告が出ています。同じ機械で前の版は動くとのことで、環境ではなく版の側が疑われていますNEW — Cowork と Claude Code のどちらに置くかを、承認の境界で決めた記録ですSONNET4.5 — 廃止表に並ぶ日付は「それより前には終わらない下限」です。Sonnet 4.5 は今も有効で、非推奨の告知は出ていません2.1.278 — auto モードの分類器が Claude API・Enterprise・Bedrock / Vertex / Foundry でサーバー側の既定になりました。分類器の分は課金されず、/status に Auto mode server の行が増えていますTASKOUT — TaskOutput ツールが削除されました。taskOutputMaxChars と TASK_MAX_OUTPUT_LENGTH は無効になり、バックグラウンドの出力は Read で読む形に一本化されています10/07 — 管理構成キーの旧い綴りの受付は10月7日 正午 PT までです。残り17日で、締切を過ぎた設定は書き直すまでそのコネクタが使えなくなりますBUNPANIC — 更新で入った版が、起動しただけで落ちるという報告が出ています。同じ機械で前の版は動くとのことで、環境ではなく版の側が疑われていますNEW — Cowork と Claude Code のどちらに置くかを、承認の境界で決めた記録ですSONNET4.5 — 廃止表に並ぶ日付は「それより前には終わらない下限」です。Sonnet 4.5 は今も有効で、非推奨の告知は出ていません
記事一覧/Claude Code
Claude Code/2026-06-12中級

Claude Code が破壊的なコマンドを打つ前に止める — PreToolUse フックの事前検査

長時間の自動実行中に rm -rf や force push が紛れ込む不安を、PreToolUse フックの事前検査で解消した記録です。settings.json の設定、検査スクリプト、exit code 2 でブロックされた後の Claude の挙動、誤検知の調整までを実例で示します。

Claude Code256Hooks4PreToolUse2permissions4安全運用

深夜、長めのリファクタリングを Claude Code に任せて別の作業をしていたときのことです。ふと実行ログを遡って、手が止まりました。ビルド成果物を消すための rm コマンドが、変数の展開結果しだいではプロジェクト直下を対象にし得る形で書かれていたのです。実害はありませんでした。それでも、「実行される前に機械的に検査する仕組み」を持っていないことが、急に心許なくなりました。

個人開発には、コマンドをレビューしてくれる同僚がいません。私自身、エージェントに任せる時間は今後も増えていく見込みだったので、このタイミングで PreToolUse フックによる事前検査を組み込みました。導入から数週間、実際に何度か「止まってくれた」場面があり、構成としても運用としても手応えを感じています。その過程で分かったことを、設定ファイルと検査スクリプトの実物とあわせて残しておきます。

許可ダイアログがあるのに、なぜ別の検査が要るのか

Claude Code には標準で許可確認の仕組みがあります。それでも検査の層をもう一枚足したのは、理由が2つあります。

1つ目は、自動承認と組み合わせる場面が現実に多いことです。長時間のタスクでは Bash の実行を許可リストに載せたり、確認を省略する設定で走らせたりします。便利さと引き換えに、「人間が読んでから実行する」という前提はそこで崩れます。

2つ目は、確認疲れです。何十回も続けて承認していると、ダイアログの中身を読まずに通すようになります。少なくとも私はそうなりました。人間の注意力は、残念ながら安全装置として当てになりません。読まなくなった人間の代わりに、毎回同じ集中力で読んでくれる検査役を置く。それが PreToolUse フックの位置づけです。

PreToolUse フックが介入できるタイミング

PreToolUse は、Claude Code がツールを実行する直前に呼ばれるフックです。フックに登録したコマンドは標準入力から JSON を受け取ります。Bash ツールの場合、tool_name と、実行されようとしているコマンド文字列を含む tool_input が入っています。

押さえておきたいのは終了コードの意味です。

  • exit 0 — 実行を許可します
  • exit 2 — 実行をブロックし、標準エラー出力の内容を Claude にフィードバックします
  • それ以外の非ゼロ — エラーとして扱われますが、ブロックにはなりません

この「2 だけが特別」という仕様は見落としやすく、私は最初 exit 1 で書いてしまい、何もブロックしない検査スクリプトをしばらく動かしていました。判定に引っかかったら必ず 2 を返す。ここを先に押さえておくと、無駄なデバッグが減ります。

settings.json への最小構成

プロジェクト単位で効かせる場合は .claude/settings.json に書きます。

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "python3 .claude/hooks/check_bash.py"
          }
        ]
      }
    ]
  }
}

matcher はツール名へのマッチです。ここを空にすると全ツールの実行前に呼ばれてしまうため、Bash に絞っています。ファイル編集系まで検査対象を広げると誤検知の調整が一気に難しくなるので、まずコマンド実行だけを見るのが現実的です。

設定をリポジトリにコミットしておけば、同じリポジトリを触る別マシンでも同じ検査が効きます。私はこの点を重視していて、まず1つのリポジトリで2週間ほど運用してから、~/.claude/settings.json に昇格させて全プロジェクト共通にしました。

検査スクリプトの実装

検査の本体は Python で書きました。「消えたら取り返しがつかない操作」だけを止める、控えめな拒否リストです。

#!/usr/bin/env python3
# .claude/hooks/check_bash.py
import json
import re
import sys
 
BLOCK_PATTERNS = [
    (r"rm\s+-[a-zA-Z]*r[a-zA-Z]*f?\s+(/|~|\$HOME)(\s|$)",
     "ルートやホームディレクトリへの再帰削除は許可していません"),
    (r"git\s+push\s+(?!.*--force-with-lease).*--force",
     "force push は --force-with-lease を使ってください"),
    (r"chmod\s+(-R\s+)?777",
     "chmod 777 は許可していません。必要な権限を個別に指定してください"),
    (r"curl\s+[^|;]*\|\s*(ba|z)?sh",
     "ダウンロードしたスクリプトの直接実行は許可していません"),
    (r">\s*/dev/sd[a-z]",
     "ブロックデバイスへの直接書き込みは許可していません"),
]
 
def main() -> int:
    data = json.load(sys.stdin)
    if data.get("tool_name") != "Bash":
        return 0
    command = data.get("tool_input", {}).get("command", "")
    for pattern, reason in BLOCK_PATTERNS:
        if re.search(pattern, command):
            print(f"blocked by check_bash.py: {reason}", file=sys.stderr)
            return 2
    return 0
 
if __name__ == "__main__":
    sys.exit(main())

許可リスト方式(許可したコマンド以外を全部止める)も検討しましたが、最初の1週間で捨てました。エージェントが使うコマンドの幅は想像より広く、許可リストが育つまでの間、ほとんど何も実行できなくなるからです。拒否リストで「致命傷だけ防ぐ」線から始めて、ヒヤリとした実例が出るたびにパターンを足す。個人開発の規模では、この育て方が一番長く続きます。

ブロックされた後、Claude はどう動くか

導入して最初に面白かったのは、ブロックされたときの Claude の振る舞いです。exit 2 で返した標準エラーの文面は、そのまま Claude へのフィードバックになります。

実際にあった例では、git push --force を止めたとき、Claude は文面にある「--force-with-lease を使ってください」を読み取り、自分でコマンドを書き換えて再実行してきました。つまり、うまく書いたエラーメッセージは、禁止ではなく誘導として機能します。

この挙動が分かってからは、メッセージを「何がだめか」ではなく「代わりにどうするか」が伝わる形に直しました。blocked とだけ返すと、Claude は原因を推測して別の回避策を探し始めることがあり、かえって挙動が読みにくくなります。

数週間の運用で調整した点

実際に回してみて、手を入れたのは次の3箇所でした。

  • 一時ディレクトリの誤検知: テストが使う $TMPDIR 配下の再帰削除まで止めていました。パターンを見直し、対象を /~$HOME の直指定に絞って解消しています。
  • ブロックログの記録: 何を止めたかを ~/.claude/hooks.log に追記するようにしました。週に一度見返すと、パターンを足す判断にも削る判断にも、このログがそのまま根拠になります。
  • 検査の軽さの維持: このスクリプトはツール実行のたびに走るので、起動の重い処理を入れると体感がはっきり悪くなります。外部コマンドの呼び出しやネットワークアクセスは入れない、が私の結論です。

permissions の deny ルールとの住み分け

Claude Code には設定ベースの deny ルールもあり、最近のアップデートで glob によるパターン指定にも対応しました。「設定で書けるなら、スクリプトは不要では」と考えて両方試しましたが、いまは役割分担に落ち着いています。

  • 静的に決まる禁止事項(特定ディレクトリへの書き込み禁止、特定コマンドの使用禁止)→ permissions の deny ルール
  • 文脈を見て判断したい事項(引数の組み合わせ、リダイレクト先、代替案をメッセージで誘導したいもの)→ PreToolUse フック

deny ルールは宣言的で高速、フックは表現力で勝ります。どちらかに寄せるより、単純な禁止を deny 側へ逃がしてフックの検査パターンを最小限に保つ構成が、メンテナンスの負担としては一番軽くなりました。

最初の一歩は1ファイルから

この仕組みは、check_bash.py を1ファイル置いて settings.json に数行足すだけで動き始めます。まずは拒否パターンを2つか3つに絞って1週間運用し、ブロックログを眺めてから育てる順番がおすすめです。誤検知に悩まされる前に、「止まってくれた」という最初の体験が得られるはずです。

シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥2,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

Claude Code2026-08-27
リポジトリに置いた allow を信じるか、環境側の信頼登録に寄せるか
使い捨ての実行環境で Claude Code を非対話で走らせると、リポジトリ内の permissions.allow が信頼待ちのまま落ちます。何が落ちて何が残るのかを 2.1.246 で確かめ、許可設定の置き場所を決め、起動前に検出するプリフライトを用意します。
Claude Code2026-08-21
Claude Code の read deny が許可フォルダの内側まで届いていなかった話
秘密ファイルとソースが同じツリーに同居する個人開発環境で、permissions.deny の Read ルールが実際にどのファイルまで届いているかを数え直した記録です。棚卸し用のスクリプトつき。
Claude Code2026-08-07
権限モードを変えても止まらない書き込み — サブエージェント用 PreToolUse ゲートを150通りで測る
ワークフローのサブエージェントによるファイル編集は、セッションの権限モードに関わらず自動承認されます。残る境界である agent_id / agent_type ベースの PreToolUse フックを150通りのペイロードで測り、素通りしていた54件の内訳と、フェイルクローズへ寄せた実装を共有します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます