| name | description | allowed-tools | hooks | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
permission-hooks |
Diagnoses and fixes PermissionRequest hook issues when Bash triggers unexpected approval prompts. When called with arguments, treat the argument as the diagnostic target command — never execute it. Use when commands are blocked, user mentions "permission"/"hooks"/"承認", or adding auto-approval patterns. |
|
|
Claude Code の PermissionRequest フック(自動承認ロジック)を診断・修正する。
/permission-hooks <コマンド> のように引数付きで呼ばれた場合、その引数は 承認を求められたコマンド である。
- 引数のコマンドを Bash で実行してはならない。文字列として扱い診断のみ行う。
- まず以下を出力し、診断ワークフローのステップ 2 から開始する:
診断対象コマンド(非実行): <引数のコマンド全文>
- 第一アクション:
config/claude/settings.jsonを Read しpermissions.allowを確認する。
引数なしの場合は、ユーザーに状況を確認してからワークフローを開始する。
- allowed-tools: Read と unittest のみ。Edit は意図的に除外し、修正時にユーザー確認を求める。
- 修正時: ソースファイルの編集には Edit ツールを使用する。Bash でのファイル書き込み(
echo > file等)は禁止。
ソースは dotfiles リポジトリ内(Nix 管理):
| 用途 | ソースパス |
|---|---|
| 複合コマンド自動承認 | config/claude/hooks/approve-safe-commands.py |
| スキル固有 Bash 承認 | config/claude/hooks/approve-skill-bash.py(各 SKILL.md の hooks で呼出) |
| safe-commands テスト | config/claude/hooks/test_approve_safe_commands.py |
| skill-bash テスト | config/claude/hooks/test_approve_skill_bash.py |
| 許可/拒否リスト | config/claude/settings.json → permissions.allow / permissions.deny |
コマンド発行
→ permissions.deny にマッチ? → 拒否
→ permissions.allow にマッチ? → 承認(フック不要)
→ スキルがアクティブ & SKILL.md に PreToolUse hooks がある?
→ approve-skill-bash.py がスキルのパターンで判定 → 承認
→ PermissionRequest フック実行:
1. approve-safe-commands.py
→ allow を返す? → 承認
→ exit(0)? → ユーザーに承認確認を表示
最新の判定パスは approve-safe-commands.py を Read し、末尾の if 条件で確認すること。以下は主要な判定カテゴリ(検索キーは参考):
| カテゴリ | 概要 | 検索キー(参考) |
|---|---|---|
| サフィックス除去 | Claude Code 付加分を前処理で除去 | — |
| AI CLI コマンド検証 | codex/gemini/cursor-agent の SQ パーサー検証 | _is_safe_ai_cli |
| npm audit 読み取り専用 | fix を除外し読み取り専用操作のみ許可 | _SAFE_NPM_AUDIT |
| help/version 判定 | --help/--version で終わるコマンド |
_SAFE_HELP_VERSION |
| 構造化コミット等 | git commit heredoc / for-wc ループ | PATTERNS |
| 読み取り専用複合チェーン | RO コマンドの &&/|| チェーン | _is_safe_readonly_compound |
| git 読み取り専用パイプ | git show/diff/log のパイプライン | _is_safe_git_readonly_pipeline |
| gh api GET パイプ | gh api 読み取り専用リクエストのパイプ | _is_safe_gh_api_pipeline |
SKILL.md の allowed-tools に定義された Bash(...) パターンとマッチング。クォート外にシェルメタ文字を含むコマンドは拒否する。詳細は approve-skill-bash.py を Read して確認。
Claude Code がコマンドに自動付加するパターン:
2>&1— stderr リダイレクト2>&1 || echo "---EXIT: $?"— 終了コード取得
両フックの先頭でこれを除去してから判定する。
承認確認が出たコマンドの原因特定:
- コマンドを確認: 問題のコマンド全文を取得(引数で渡された場合は Bash 実行せずそのまま使用)
- permissions.allow 確認:
config/claude/settings.jsonのパターンとマッチするか確認 - サフィックスの影響確認: Claude Code 付加サフィックスで permissions.allow のマッチが壊れていないか
- フック1(safe-commands)確認:
approve-safe-commands.pyを Read し、末尾の if 条件でどの判定パスにも該当しないか特定 - フック2(skill)確認: SKILL.md にパターンがあるか、メタ文字で弾かれていないか
- 判定: 自動承認が安全に実現可能なら最小限の修正箇所を決定。プロセス置換
<(...)やクォート外のコマンド置換$(...)等、任意コマンド実行が可能な構文を含む場合は手動承認を推奨
- ソースファイルを編集:
config/claude/hooks/内のファイルを修正 - テスト追加: 修正対象のテストファイルに承認/拒否の両ケースを追加
- 回帰テスト確認: 既存のセキュリティテスト(攻撃パターンの拒否)が引き続きパスすることを確認
- テスト実行:
python3 -m unittest config/claude/hooks/test_approve_safe_commands -v
- ユーザーに rebuild 依頼: Nix 管理のため
sudo darwin-rebuild switch --flake ...が必要。詳細は nix-file-edit スキル参照
- ホワイトリスト方式: 安全と証明できるパターンのみ承認。不明なら拒否
- 正規表現はアンカー付き:
^と$で完全一致。部分一致は禁止 - メタ文字は信頼しない: クォート外のシェルメタ文字を含むコマンドは原則拒否
_RO_CMDSは副作用なしのコマンドのみ:cat/head/tailは Read deny 迂回防止のため除外- テストは攻撃ベクタを含む: 正常系だけでなくインジェクション攻撃のテストを必ず追加
- 自己無効化の禁止: フック自体の安全性を損なう変更(全許可パターンの追加、メタ文字チェックのバイパス等)は行わない
最もシンプルな修正を優先する:
- Pattern E(permissions.allow)を最優先: 単純な読み取り専用コマンド(パイプ・複合チェーン不要)は permissions.allow への追加で済む。既存の git サブコマンド(show, log, status 等)と同列に扱えるならここ。パイプラインでも使われるようになったら Pattern B/D に昇格する
- Pattern B/D(hook 側): パイプライン(
cmd | filter)や複合チェーン(cmd1 && cmd2)での使用が想定される場合、または引数パターンの細かい制御が必要な場合 - Pattern C(skill): スキル実行中のみ必要なコマンド
- Pattern A: Claude Code のサフィックス形式が変わった場合
2ファイルでサフィックス除去の正規表現が異なる点に注意:
approve-safe-commands.py: パイプ前・行継続前・末尾のいずれの位置でも除去approve-skill-bash.py: 末尾のみ除去
編集前にソース冒頭の re.sub を Read して現在の実装を確認すること。
専用の正規表現パターンを作成し、_RO_CMDS には追加しない。ソース末尾の if 条件に追加する。既存の判定関数・パターンに倣うこと(approve-safe-commands.py を Read して確認)。
SKILL.md の allowed-tools に Bash(...) パターンを追加し、hooks フロントマターに approve-skill-bash.py <SKILL.md-path> を登録。
PATTERNS リストに新しい re.compile(...) を追加。既存の PATTERNS を Read して書式・フラグの使い分け(re.DOTALL / re.ASCII)を確認すること。
副作用のない単純なコマンドは permissions.allow への追加が最もシンプル:
"Bash(npm ls)",
"Bash(npm ls *)"Bash(cmd)とBash(cmd *)のペアで追加する(Claude Code のサフィックス2>&1等に対応)- エントリはセクション内でアルファベット順にソートする(既存の空行区切りセクションを維持)
- サブコマンドで副作用があるもの(例:
npm audit fix)は*でマッチするため、hook 側で正規表現制御する(パターン B 参照)
| 問題 | 対処 |
|---|---|
| テストが import エラー | python3 -m unittest でプロジェクトルートから実行 |
| 修正後も承認確認が出る | rebuild していない。Nix 管理のためシンボリックリンク先は古いまま |
_RO_CMDS に追加したい |
副作用の有無を確認。引数次第で副作用があるコマンドは専用パターンで |
| 正規表現が複雑すぎる | 既存パターンを参考に。[ \t](水平空白のみ)と \s(改行含む)の使い分けに注意 |
プロセス置換 <(...) を含む |
任意コマンド実行が可能なため自動承認不可。手動承認を推奨 |