Repository navigation
V2: subagent frontmatter skill allows ignored (global deny wins) #50149
Description
Description
Agent frontmatter permissions rules with action: "skill", effect: "allow" have no effect for subagents in V2. The child session appears to evaluate only the parent/global ruleset, so a global { "action": "skill", "resource": "*", "effect": "deny" } (the allowlist pattern from the permissions docs) hides and rejects skills that the subagent explicitly allows in its own frontmatter.
The docs describe the opposite behavior:
- /v2/docs/permissions — "Lower-priority configuration is loaded first, global rules are appended next, and agent rules are appended last" (last matching rule wins)
- /v2/docs/agents — "Global
permissionsapply before agent-specific rules, so later agent rules can refine them" - /v2/docs/skills — loading a skill "Checks the selected agent's
skillpermission"; "Place the same rules underagents.<id>.permissionsto apply them only to one agent"
Observed on v2.0.11: the skill is absent from the subagent's available-skills catalog (the catalog mirrors the primary's global-allow view — 37 skills — rather than anything derived from the subagent's own frontmatter), and the skill tool call fails with {"error":{"type":"permission.rejected","message":"Permission denied: "skill"}}.
Steps to reproduce
- Global config
~/.config/opencode/opencode.json:
{ "permissions": [
{ "action": "skill", "resource": "*", "effect": "deny" },
{ "action": "skill", "resource": "other-skill", "effect": "allow" }
] }-
Create
~/.config/opencode/skills/my-test-skill/SKILL.mdwith frontmattername: my-test-skilland a description (ID is path-derived, sonamematching the directory is irrelevant to the bug). -
Create
~/.config/opencode/agents/my-reviewer.md:
---
description: Loads a skill
mode: subagent
permissions:
- { action: skill, resource: my-test-skill, effect: allow }
---
Call the skill tool with id "my-test-skill" and report the exact result.- From the primary agent, launch
my-reviewerand let it run its instruction. - Observed:
my-test-skillmissing from the subagent's skill catalog; theskillcall returns{"error":{"type":"permission.rejected","message":"Permission denied: skill"}}. - Expected: the agent-level allow is the last matching rule, so the skill is advertised and loads without approval.
Proposed solution
Include the subagent's own permission rules in the child session's derived ruleset, appended after the global rules per the documented merge order. The V1 lineage of this bug is analyzed in #33223 (deriveSubagentSessionPermission reads input.subagent.permission only for task/todowrite checks and never includes it in the output) — worth checking whether the V2 derivation inherited the same shape. Related: #26758, #27497 (fixes #27201, #27654), #35238.
Plugin suggestion
While unfixed, a plugin-side workaround is currently impossible because the derived child-session permission set is never surfaced. Exposing a permission-derivation hook (e.g. an event/execute-style hook receiving the child session's effective permission set before the first tool call) would let deployments audit or patch derived rules, and would enable the "permission derivation receipt" test suggested in #33223's comments (fail when a subagent rule was silently dropped).
Plugins
@prevalentware/opencode-goal-plugin@^0.1.48 plus a local secret-masking plugin; neither touches permissions. The repro above requires no plugins.
OpenCode version
v2.0.11
Operating System
Ubuntu 24.04.5 LTS (x86_64)
Terminal
Reproduced headless via the agent API (no TUI involved).
Activity
feat(skills): implement Phases 1-2 — interim reviewer-skill allows (f…
martin-braun commentedon Sep 23, 2026
Confirmed, the V2 permissions do not work as documented. I had to revert my migration to the V1 format. However, the V2 permissions in opencode.json work.