メインコンテンツへスキップ
KatoKyo works

Claude Code Skill の allowed-tools は結局なんのためにあるのか

| 読了 4 分 | 技術

Skill frontmatter に allowed-tools: [Bash(codex exec:*)] と書いたのに、codex exec 実行時に承認ダイアログが出てくる。書いた通りに動いていないのか、自分の理解が間違っているのか。しばらく触っているうちに、質問のかたちで自分に問い直した方が整理しやすいと気付いた。以下は Q&A メモである。


Q1. allowed-tools に書いたら、承認ダイアログが出なくなるはずではないのか

自分もそう思っていた。手元では出る。該当 Skill は codex-skill-split で作った codex-ask。冷静に眺めると、「読み取られていない」「仕様を誤解している」「パターンマッチが想定より厳密」の 3 通りが考えられる。


Q2. では、まず「読み取られているか」はどう確認できるか

結論から言うと、直接は確認できない。Skill 起動時に SKILL.md 本文は会話コンテキストに展開されているように見えるが、frontmatter の allowed-tools が権限判定にどう使われたかを可視化する UI もログもない。これが最初のつまずきだった。

手元で ~/.claude/settings.jsonpermissions.allowBash(codex exec:*) を追加すると、承認ダイアログは確かに出なくなる。ただしそれは「settings.json が効いた」だけで、Skill の allowed-tools が効いたかどうかの切り分けにはなっていない。


Q3. settings.json と Skill の allowed-tools は、同じものを 2 箇所に書いているだけなのか

書いたときはそのつもりだった。しかし手元の観察を重ねると、同じではないかもしれない、という疑いが出てきた。

settings.json を空に戻して Skill 側だけで承認が抜けるかを試したいのだが、そのための「Claude Code のセッション状態を完全にクリーンにして再現する手順」が定まらない。結局ここは切り分けが途中で止まった。Skill の allowed-tools 単独で効くのかどうかは、今のところ分からない。

推測の域だが、関係としては次のどれかだと予想している。

  • 仕様 A: settings.json が最終判断、Skill の allowed-tools は自己申告として扱われる(ユーザーの許可 ⊃ Skill の申告)
  • 仕様 B: 両方が OR で評価され、どちらかに該当すれば allow
  • 仕様 C: 別々のレイヤで評価され、特定の条件でだけ Skill 側が効く

仕様 A を暫定的に採用して運用しているが、根拠は弱い。


Q4. なぜ仕様 A に寄せたのか

セキュリティモデルの自然さ、という一点である。Skill は書き換え可能な外部資産で、~/.claude/skills/ に置かれるだけで参照される。もし Skill 側の申告だけで権限が広がるなら、他人が共有した Skill をダウンロードした瞬間に好きなツールを allow できてしまう。サプライチェーン耐性の観点で穴が大きい。

逆に「Skill は自分が何を使いたいかを宣言する場、ユーザーの settings.json が最後のゲート」という設計なら、外部 Skill を導入したときの被害が限定される。このモデルの方が素直である。もし仕様どおりなら合理的、という留保付きで納得している。


Q5. Bash(codex exec:*)Bash(codex exec review:*) は同じものとしてマッチしないのか

ここがもう一つ腑に落ちなかった箇所。Bash(codex exec:*) を allow しておけば、codex exec review ... も包含されるように読める。が、手元では具体的なサブコマンドまで書いたパターン、つまり Bash(codex exec review:*) の方が安定して効く。

完全な反証はできていないが、「ワイルドカード付きの広いパターンは、実コマンドラインに対してやや限定的にしかマッチしない場合がある」という感触を得た。

この観察は副産物として codex-skill-split で Skill を 2 本に分けた判断を後押しする。責務で分離した結果、

  • codex-ask には Bash(codex exec:*) を許可
  • codex-review には Bash(codex exec review:*) を許可

と、Skill ごとに必要最小限のパターンだけ allow できる構造になった。最小権限原則に自然と寄る形で、もし Skill の申告機構に抜け穴があっても被害範囲が狭い。設計の副作用としては悪くない。


Q6. 結局、Skill の allowed-tools は何のために書くのか

現時点で置いている答えはこうだ。

Skill 側の「このツールを使いたい」という自己申告。ユーザーの settings.json と揃って初めて、承認ダイアログがスキップされる。

ただし繰り返すが、これは観察と推測の混合物である。公式仕様で追認していない。


未整理のまま残ったもの

  • settings.json を空にして Skill 側単独でどこまで効くかの厳密実験。セッションクリーン化の手順が詰められていない。次にやるときの最低限のプロトコルは以下:
Case 1: settings.json=空,  Skill allowed-tools=あり
Case 2: settings.json=あり, Skill allowed-tools=なし
Case 3: settings.json=あり, Skill allowed-tools=あり
各 Case で `codex exec` / `codex exec review` の承認ダイアログ有無を 3 回ずつ記録
  • allowed-toolspermissions.allow の正確な優先順位の公式仕様確認。
  • Bash ツール以外(Write / Edit など)でも allowed-tools が同じセマンティクスを持つかどうか。

Claude Code のバージョンで変わる領域なので、この Q&A は現時点のスナップショットに過ぎない。後から同じ疑問を踏んだ誰かが、せめて「ここまでは観察されている」と読めるよう、手元の整理だけ残しておく。