3.3 KiB
パーミッション: パターンベースのツール実行制御
背景
現状の 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 に倣う):
- 最初にマッチした
deny→ 拒否 - すべてマッチする
allow→ 許可 - それ以外 →
ask(ユーザー確認)
設計ポイント
- 設計原則3: 新しい trait は作らない。
PreToolCallHook として実装 - 設計原則2: マニフェストに宣言した以上、insomnia 層が解決する
askアクションは Pod Protocol の拡張が必要(Method にPermissionReplyを追加)Scopeとの関係: Scope は書き込みの物理的境界、Permission はツール実行のポリシー。補完関係- ルール評価はパターンマッチのみ。コンテキスト依存の判断はしない(シンプルに保つ)
段階的実装
- 拡張ポイントの記録(今): docs/pod.md の拡張ポイント表に追加
- deny/allow の実装(ツール実装時): PreToolCall Hook でパターン評価
- 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::WorkspaceSkill { dir }/UserSkill { dir }で識別済み (crates/memory/src/workflow.rs)- 受け皿実装時に
SkillFrontmatter::allowed_toolsの保持先をWorkflowRecordに伸ばすか、別の SkillRecord registry を持つかは本チケット内で決める - 現状の
tracing::warn!は受け皿実装と同時に消す
依存チケット
remove-hook-module.md— 完了。PreToolCall は Pod 層のhook::Hook<PreToolCall>として利用可能