yoi/tickets/permission-extension-point.md

3.4 KiB
Raw Blame History

パーミッション: パターンベースのツール実行制御

背景

現状の Scope はディレクトリ単位の書き込み制約で、静的な境界線。 実際のエージェント運用では、ツール単位・引数パターン単位の動的な権限制御が必要になる。

OpenCode はパターンベースのルールtool × pattern → allow/deny/askを持ち、 *.env への書き込み拒否や rm -rf の実行拒否を宣言的に設定できる。

方針

PreToolCall Hook として実装する。マニフェストにルールを宣言し、 insomnia 層の Hook 実装がツール呼び出し時に評価する。

[[permission]]
tool = "bash"
pattern = "rm *"
action = "deny"

[[permission]]
tool = "file_write"
pattern = "*.env"
action = "deny"

[[permission]]
tool = "*"
pattern = "*"
action = "allow"

評価順序OpenCode に倣う):

  1. 最初にマッチした deny → 拒否
  2. すべてマッチする allow → 許可
  3. それ以外 → ask(ユーザー確認)

設計ポイント

  • 設計原則3: 新しい trait は作らない。PreToolCall Hook として実装
  • 設計原則2: マニフェストに宣言した以上、insomnia 層が解決する
  • ask アクションは Pod Protocol の拡張が必要Method に PermissionReply を追加)
  • Scope との関係: Scope は書き込みの物理的境界、Permission はツール実行のポリシー。補完関係
  • ルール評価はパターンマッチのみ。コンテキスト依存の判断はしない(シンプルに保つ)

段階的実装

  1. 拡張ポイントの記録(今): docs/pod.md の拡張ポイント表に追加
  2. deny/allow の実装(ツール実装時): PreToolCall Hook でパターン評価
  3. ask の実装Protocol 拡張時): Method/Event に Permission 関連メッセージを追加

受け皿になる外部仕様

Agent Skills allowed-tools

tickets/agent-skills.md で ingest した SKILL.md の frontmatter には agent-skills 仕様の experimental field である allowed-tools (例: ["Read", "Bash"]) が含まれる場合がある。crates/memory/src/skill.rs::parse_skill_md 時点では tracing::warn! で受け流しているだけで、実効化していない。

本チケットの Permission 層が固まった時点で、Skill 由来 Workflow を実行中のみ当該 skill の allowed-tools リストに含まれるツールしか走れない形で反映する。スコープは「Workflow 実行中」相当 (Workflow の system message が context に乗っているターン) に限定する想定。skill 単位で local な permission 集合を持つので、グローバルな [[permission]] ルールとは独立に評価する。

実装上の足がかり:

  • WorkflowRecord の出所は WorkflowSource::Skill { dir } で識別済み (crates/memory/src/workflow.rs)。dir は manifest [skills] directories に書かれた skill ルートそのもの
  • 受け皿実装時に SkillFrontmatter::allowed_tools の保持先を WorkflowRecord に伸ばすか、別の SkillRecord registry を持つかは本チケット内で決める
  • 現状の tracing::warn! は受け皿実装と同時に消す

依存チケット

  • remove-hook-module.md — 完了。PreToolCall は Pod 層の hook::Hook<PreToolCall> として利用可能