Skip to content

fix(cli): harden plan mode permissions and propagate restrictions to sub-agents#8417

Merged
kirillk merged 8 commits into
mainfrom
utopian-starflower
Apr 6, 2026
Merged

fix(cli): harden plan mode permissions and propagate restrictions to sub-agents#8417
kirillk merged 8 commits into
mainfrom
utopian-starflower

Conversation

@kirillk

@kirillk kirillk commented Apr 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes two related security/correctness issues with plan mode permissions and sub-agent isolation.

This PR also incorporates the guidance and changes from PR #8360, which identified that apply_patch and write tool permissions were not properly restricted in plan mode.


Problems Found

1. Plan mode could silently hard-block the model with no recourse

Plan mode had edit: { "*": "deny" } — any attempt to edit a file outside .kilo/plans/ would throw a hard error that the model couldn't recover from. This caused confusing failures when a sub-agent or the plan agent itself tried to do something reasonable (e.g. update a config file the user approved).

2. Sub-agents did not inherit the calling agent's restrictions

When the plan agent spawned a sub-agent (e.g. general or explore) via the task tool, the child session was created with only todowrite/todoread deny rules. The sub-agent's own agent definition was used for everything else — which has fully permissive edit and standard bash permissions. This meant a sub-agent could freely write any file, bypassing plan mode entirely.

3. Plan mode had unrestricted bash access

The plan agent inherited defaults bash rules, which allow write operations (touch, mkdir, cp, mv) without restriction. Plan mode is supposed to be read-and-plan-only, so these should require approval or be blocked.

4. MCP tools were unavailable in plan mode

Plan mode had no MCP rules, so all MCP tool calls were denied. The ask agent (PR #7929) already solved this pattern with per-call approval — plan mode should benefit from the same.

5. Specific MCP tool restrictions were dropped when propagating to sub-agents

The inheritance filter in task.ts only preserved server-wide wildcard rules like github_*. Narrower rules targeting individual tools (e.g. github_create_issue: deny) were silently dropped, so sub-agents fell back to their own permissive * rule for those tools.


Changes

packages/opencode/src/agent/agent.ts

Behaviour Before After
Edit outside plan files ❌ Hard denied — model gets an error it cannot recover from ⚠️ Asks user for approval — user stays in control
Edit plan files (.kilo/plans/*.md) ✅ Allowed ✅ Allowed (unchanged)
Bash write commands (touch, cp, mv, …) ⚠️ Asks (inherited from defaults) ❌ Denied — plan mode uses read-only bash
Bash unknown commands ⚠️ Asks (inherited from defaults) ❌ Denied — plan mode uses read-only bash
Bash read-only commands (cat, grep, git log, …) ✅ Allowed ✅ Allowed (unchanged)
MCP tools ❌ Denied (no rules) ⚠️ Asks per call — matches ask agent behaviour

packages/opencode/src/tool/task.ts

When any agent spawns a sub-agent via the task tool, the child session now inherits the calling agent's edit, bash, and MCP permission rules. Because permission evaluation uses findLast, the inherited rules are appended last and take precedence over the sub-agent's own defaults.

Scenario Before After
plangeneral sub-agent edit any file ✅ Allowed (sub-agent used its own permissive defaults) ⚠️ Asks — inherits plan's edit: "*": "ask"
plangeneral sub-agent edit plan file ✅ Allowed ✅ Allowed — inherits plan's explicit allow rule
plangeneral sub-agent bash write commands ⚠️ Asks ❌ Denied — inherits plan's readOnlyBash
orchestrator → sub-agent bash ⚠️ Asks (sub-agent default) ❌ Denied — inherits orchestrator's bash: "deny"
code → sub-agent edit ✅ Allowed ✅ Allowed — inherits code's permissive rules (no change)
Sub-agent with server-wide MCP wildcard (github_*: deny) ❌ Denied (inherited correctly) ❌ Denied (unchanged)
Sub-agent with specific MCP tool rule (github_create_issue: deny) ✅ Allowed (rule was silently dropped — bug) ❌ Denied — specific MCP tool rules are now preserved

Related

Comment thread packages/opencode/src/tool/task.ts Outdated
Comment thread packages/opencode/src/tool/task.ts
@kilo-code-bot

kilo-code-bot Bot commented Apr 6, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (1 files)
  • packages/kilo-vscode/src/KiloProvider.ts

Reviewed by gpt-5.4-2026-03-05 · 197,147 tokens

Comment thread packages/opencode/src/tool/task.ts Outdated
@kirillk kirillk marked this pull request as draft April 6, 2026 15:10
kirillk added 3 commits April 6, 2026 11:26
…ion status text

When plan mode delegates to a subagent the child session can block on a
permission or question before the UI starts tracking it, leaving the parent
stuck on 'Delegating work' with no visible prompt.

- Auto-adopt child sessions in KiloProvider.handleEvent as soon as the task
  tool part reveals metadata.sessionId — eliminates the race where the child
  emits a prompt before the webview renderer calls syncSession
- Add fetchAndSendPendingQuestions mirroring the existing permission recovery;
  call both after handleSyncSession so missed prompts are recovered for child
  sessions
- Extend questionCtx with trackedSessionIds + sessionDirectories needed for
  the recovery path
- Improve statusText: when delegating and the session family has pending
  permissions/questions, show 'Subagent waiting for permission' or
  'Subagent waiting for response' instead of generic 'Delegating work'
- Add i18n keys for the two new status strings across all 19 locales
@kirillk kirillk marked this pull request as ready for review April 6, 2026 16:16
Comment thread packages/kilo-vscode/src/KiloProvider.ts
@kirillk kirillk merged commit 3aa5327 into main Apr 6, 2026
17 checks passed
@kirillk kirillk deleted the utopian-starflower branch April 6, 2026 17:18
jliounis pushed a commit to jliounis/kilocode that referenced this pull request May 18, 2026
fix(cli): harden plan mode permissions and propagate restrictions to sub-agents
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants