Skip to content

Agent Host: stale managed permission state forces approval for every tool and hangs Allow All #328879

Description

Summary

A Copilot Agent Host session can become stuck in a stale enterprise-managed permission state even when no enterprise or device policy is configured.

Once this happens:

  • Every tool requires explicit approval, including reads inside the workspace.
  • Each approval is treated as a one-time approval.
  • Selecting Allow All updates the VS Code-side session configuration, but the Copilot runtime does not complete the corresponding permission-mode update.
  • Subsequent turns can hang while waiting behind that unresolved permission-mode operation.

Slack context: https://vscodeteam.slack.com/archives/C0AKR94N3CK/p1785801351886179

The debug logs used for this investigation are intentionally not attached because they contain sensitive session data.

Observed sequence

The runtime's managed-settings initialization briefly entered a fail-closed state while account policy was unresolved:

  1. Policy could not initially be determined, so bypass-permissions mode was disabled.
  2. Milliseconds later, device and server policy resolution completed and reported that no managed policy existed.
  3. Despite that successful resolution, subsequent permission requests in the existing session were still emitted with managedApprovalRequired: true.

This affected shell commands, writes, and workspace reads. Eight consecutive requests in the captured failure period carried the managed marker and required individual approval.

The protocol trace also showed that selecting Allow All successfully dispatched and echoed:

session/configChanged { autoApprove: "autoApprove" }

However, the runtime did not emit the corresponding session.permissions_changed event or complete the permission-mode transition. Later turn-start synchronization was then blocked behind the unresolved update.

Root cause

There appear to be two linked problems.

1. Managed-policy state is not reconciled for the existing session

The Copilot runtime initially fails closed while policy is unresolved. When policy resolution subsequently reports that no managed policy exists, the already-running session retains the restrictive state and continues tagging requests as managed.

VS Code correctly treats managedApprovalRequired as authoritative and deliberately disables every auto-approval route for such requests. The incorrect input therefore produces the user-visible approval storm.

Relevant VS Code implementation:

This enforcement is appropriate when a real managed policy exists; the defect is the stale/incorrect managed state supplied to it.

Related managed-settings notification adoption:

Related reconciliation work currently under review:

The upstream runtime also has a relevant managed-settings correction:

The affected session was running Copilot runtime 1.0.77.

Relevant VS Code dependency update:

2. Permission-mode synchronization can wait indefinitely

VS Code serializes permission-mode changes and awaits:

this._wrapper.session.rpc.permissions.setAllowAll({ mode })

There is no timeout or cancellation around that call. If the runtime does not settle the RPC—such as when it still believes managed policy prohibits bypass—the permission-mode sequencer remains occupied. Every later turn calls syncPermissionMode('turn-start') and queues behind the unresolved operation, making the session appear hung.

Relevant implementation:

  • src/vs/platform/agentHost/node/copilot/copilotAgentSession.ts
  • _subscribeToPermissionConfigChanges
  • _syncPermissionModeAfterConfigChange
  • syncPermissionMode
  • Original commit: e6549ec
  • PR: AH: adopt sdk llm-judged tools #325547AH: adopt sdk llm-judged tools

Expected behavior

  • Once managed-settings resolution determines that no managed policy exists, existing sessions should be reconciled immediately and should stop producing managedApprovalRequired requests.
  • Reads inside the workspace should follow normal session permission behavior.
  • Selecting Allow All should either complete successfully or surface a clear failure.
  • A missing SDK response must not permanently occupy the permission-mode sequencer or block future turns.

Suggested fixes

  1. Ensure the runtime and/or Agent Host reconciles already-running sessions after managed-policy resolution changes from the initial fail-closed state to no policy.
  2. Verify that the runtime update containing the managed-settings correction is included and that it fixes restored/existing sessions, not only newly created sessions.
  3. Add timeout/cancellation or another bounded failure path around rpc.permissions.setAllowAll.
  4. On permission-mode synchronization failure, clear/unblock the sequencer and surface an actionable error instead of leaving later turns waiting indefinitely.
  5. Add regression coverage for:
    • Initial policy unresolved → no managed policy resolved.
    • Workspace read after that transition.
    • Selecting Allow All while a stale managed restriction exists.
    • An SDK setAllowAll request that never resolves.

Authorship context

Git history identifies the areas and commits above, but this issue is about the interaction between managed-policy initialization, correct security enforcement, and unbounded synchronization—not individual fault.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions