You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In a Code Mode session, plugin tools invoked through the execute dispatcher do not surface the configured ask permission. A mutation tool declared with options.permission mapped to an ask rule executes silently, with no permission prompt in the client.
Global opencode.jsonc has rules such as { "action": "systemd_user_start", "resource": "*", "effect": "ask" }.
A server plugin exposes a tool with options: { permission: "systemd_user_start" } via context.tool.transform((e) => e.add(...)).
In a Code Mode session, invoke that tool through the dispatcher, e.g. an execute block calling tools["systemd_user_start"]({ unit: "wivrn.service" }).
Observe: the unit starts/stops successfully, and the client never shows an ask prompt (no permission.asked event; compare with early-session direct tool calls, which did produce asking id=per_... log lines).
Expected Behavior
The docs for the execute action state each nested tool still enforces its own permission. An ask rule should prompt the user (or be rejected when no interactive channel is available).
Actual Behavior
The ask rule is bypassed: mutation tools execute silently through the execute dispatcher. In our session systemd_user_start/stop for wivrn.service ran with no confirmation. Risk: any ask-class plugin tool is unenforced in Code Mode.
Additional Context
Reproducible consistently via execute.
Direct (non-dispatcher) tool calls in the same environment do prompt, so the bypass appears specific to the Code Mode dispatcher path.
No saved "allow always" approval exists for these actions; config rules are intact ask.
Update: this is broader than the Code Mode dispatcher path. Local server plugin tools bypass the permissions engine entirely — not just the ask prompt, but deny rules too.
Additional evidence (native tool path, not execute)
With a local server plugin exposing tools that declare options.permission/codemode: false, and global permissions in opencode.jsonc:
systemd_user_start with rule { action: "systemd_user_start", resource: "*", effect: "ask" } → executes silently, no permission.asked event (client polling GET /api/session/<id>/permission returns 404 the whole time).
Same tool with the rule changed to effect: "deny" → still executes successfully.
A read-only plugin tool with its rule changed to effect: "deny" → also still executes (confirms the engine is not being consulted at all for plugin tools).
Control: a built-in tool (writing a file outside the workspace, edit + external_directory = ask) → prompts correctly in the same client/session.
Conclusion
Plugin-registered tools are invoked without permission evaluation regardless of execute vs native listing, and regardless of codemode. ask, deny, and allow rules have no effect on them. Built-in tools are unaffected. This makes permission enforcement for plugin tools unreliable end-to-end.
Thanks for the report and for checking that both ask and deny rules are bypassed on direct plugin calls too. This is the same problem as #50652, where we're tracking plugin-tool permission enforcement; please subscribe there or add your deny-rule findings, which are useful extra details.
Activity
github-actions commentedon Sep 4, 2026
This issue might be a duplicate of or closely related to existing issues. Please check:
permission.askplugin hook is defined but not triggered #7006:permission.askplugin hook is defined but never triggered — shares the same root area (plugin tool permissions not being enforced), thoughpermission.askplugin hook is defined but not triggered #7006 covers the hook not firing at all while this issue focuses specifically on theexecutedispatcher path in Code Mode silently bypassingaskrules.CyberNekokoya commentedon Sep 4, 2026
Update: this is broader than the Code Mode dispatcher path. Local server plugin tools bypass the permissions engine entirely — not just the
askprompt, butdenyrules too.Additional evidence (native tool path, not
execute)With a local server plugin exposing tools that declare
options.permission/codemode: false, and global permissions inopencode.jsonc:systemd_user_startwith rule{ action: "systemd_user_start", resource: "*", effect: "ask" }→ executes silently, nopermission.askedevent (client pollingGET /api/session/<id>/permissionreturns 404 the whole time).effect: "deny"→ still executes successfully.effect: "deny"→ also still executes (confirms the engine is not being consulted at all for plugin tools).edit+external_directory=ask) → prompts correctly in the same client/session.Conclusion
Plugin-registered tools are invoked without permission evaluation regardless of
executevs native listing, and regardless ofcodemode.ask,deny, andallowrules have no effect on them. Built-in tools are unaffected. This makes permission enforcement for plugin tools unreliable end-to-end.neriousy commentedon Oct 20, 2026
Thanks for the report and for checking that both ask and deny rules are bypassed on direct plugin calls too. This is the same problem as #50652, where we're tracking plugin-tool permission enforcement; please subscribe there or add your deny-rule findings, which are useful extra details.