Skip to content

Instantly share code, notes, and snippets.

@silenvx
Created February 23, 2026 03:47
Show Gist options
  • Select an option

  • Save silenvx/e580d66ba58b186f19452f26d5d35f84 to your computer and use it in GitHub Desktop.

Select an option

Save silenvx/e580d66ba58b186f19452f26d5d35f84 to your computer and use it in GitHub Desktop.
permission-hooks SKILL.md: 承認ダイアログの自動修正スキル — https://zenn.dev/ux_xu/articles/4f57169b0dd820
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.
Bash(python3 -m unittest *)
Read
PreToolUse
matcher hooks
Bash
type command
command
$HOME/.claude/hooks/approve-skill-bash.py $HOME/.claude/skills/permission-hooks/SKILL.md

Permission Hooks 整備

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.jsonpermissions.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 の判定パス

最新の判定パスは 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

approve-skill-bash.py の判定パス(SKILL.md PreToolUse hooks 経由)

SKILL.md の allowed-tools に定義された Bash(...) パターンとマッチング。クォート外にシェルメタ文字を含むコマンドは拒否する。詳細は approve-skill-bash.py を Read して確認。

Claude Code のサフィックス

Claude Code がコマンドに自動付加するパターン:

  • 2>&1 — stderr リダイレクト
  • 2>&1 || echo "---EXIT: $?" — 終了コード取得

両フックの先頭でこれを除去してから判定する。

診断ワークフロー

承認確認が出たコマンドの原因特定:

  1. コマンドを確認: 問題のコマンド全文を取得(引数で渡された場合は Bash 実行せずそのまま使用)
  2. permissions.allow 確認: config/claude/settings.json のパターンとマッチするか確認
  3. サフィックスの影響確認: Claude Code 付加サフィックスで permissions.allow のマッチが壊れていないか
  4. フック1(safe-commands)確認: approve-safe-commands.py を Read し、末尾の if 条件でどの判定パスにも該当しないか特定
  5. フック2(skill)確認: SKILL.md にパターンがあるか、メタ文字で弾かれていないか
  6. 判定: 自動承認が安全に実現可能なら最小限の修正箇所を決定。プロセス置換 <(...) やクォート外のコマンド置換 $(...) 等、任意コマンド実行が可能な構文を含む場合は手動承認を推奨

修正ワークフロー

  1. ソースファイルを編集: config/claude/hooks/ 内のファイルを修正
  2. テスト追加: 修正対象のテストファイルに承認/拒否の両ケースを追加
  3. 回帰テスト確認: 既存のセキュリティテスト(攻撃パターンの拒否)が引き続きパスすることを確認
  4. テスト実行:
    python3 -m unittest config/claude/hooks/test_approve_safe_commands -v
  5. ユーザーに rebuild 依頼: Nix 管理のため sudo darwin-rebuild switch --flake ... が必要。詳細は nix-file-edit スキル参照

セキュリティ原則

  • ホワイトリスト方式: 安全と証明できるパターンのみ承認。不明なら拒否
  • 正規表現はアンカー付き: ^$ で完全一致。部分一致は禁止
  • メタ文字は信頼しない: クォート外のシェルメタ文字を含むコマンドは原則拒否
  • _RO_CMDS は副作用なしのコマンドのみ: cat/head/tail は Read deny 迂回防止のため除外
  • テストは攻撃ベクタを含む: 正常系だけでなくインジェクション攻撃のテストを必ず追加
  • 自己無効化の禁止: フック自体の安全性を損なう変更(全許可パターンの追加、メタ文字チェックのバイパス等)は行わない

修正パターン集

パターン選択基準

最もシンプルな修正を優先する:

  1. Pattern E(permissions.allow)を最優先: 単純な読み取り専用コマンド(パイプ・複合チェーン不要)は permissions.allow への追加で済む。既存の git サブコマンド(show, log, status 等)と同列に扱えるならここ。パイプラインでも使われるようになったら Pattern B/D に昇格する
  2. Pattern B/D(hook 側): パイプライン(cmd | filter)や複合チェーン(cmd1 && cmd2)での使用が想定される場合、または引数パターンの細かい制御が必要な場合
  3. Pattern C(skill): スキル実行中のみ必要なコマンド
  4. Pattern A: Claude Code のサフィックス形式が変わった場合

パターン A: 新しいサフィックス形式への対応

2ファイルでサフィックス除去の正規表現が異なる点に注意:

  • approve-safe-commands.py: パイプ前・行継続前・末尾のいずれの位置でも除去
  • approve-skill-bash.py: 末尾のみ除去

編集前にソース冒頭の re.sub を Read して現在の実装を確認すること。

パターン B: 新しい安全コマンドの追加(safe-commands 側)

専用の正規表現パターンを作成し、_RO_CMDS には追加しない。ソース末尾の if 条件に追加する。既存の判定関数・パターンに倣うこと(approve-safe-commands.py を Read して確認)。

パターン C: 新しいスキルコマンドの自動承認

SKILL.md の allowed-toolsBash(...) パターンを追加し、hooks フロントマターに approve-skill-bash.py <SKILL.md-path> を登録。

パターン D: 新しい読み取り専用複合パターンの追加(safe-commands 側)

PATTERNS リストに新しい re.compile(...) を追加。既存の PATTERNS を Read して書式・フラグの使い分け(re.DOTALL / re.ASCII)を確認すること。

パターン E: permissions.allow への追加

副作用のない単純なコマンドは 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(改行含む)の使い分けに注意
プロセス置換 <(...) を含む 任意コマンド実行が可能なため自動承認不可。手動承認を推奨
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment