microsoft / microsoft/vscode

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

Open
#328,879 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
193k
Forks
42.4k
PR merge metrics
PR metrics pending

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:

```text
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:

- Managed approval enforcement: `src/vs/platform/agentHost/node/copilot/copilotAgentSession.ts`, `_handlePermissionRequest`
- Original commit: https://github.com/microsoft/vscode/commit/13124ea3d3ed29b3bbd79e4145526e0c395f9931
- PR: https://github.com/microsoft/vscode/pull/327383 — **Agent Host: Require confirmation for managed permission asks**

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:

- Commit: https://github.com/microsoft/vscode/commit/89d417cf1f39163e7b23779312467dd04a298aee
- PR: https://github.com/microsoft/vscode/pull/327187 — **Adopt SDK managed settings notifications**

Related reconciliation work currently under review:

- PR: https://github.com/microsoft/vscode/pull/328729 — **Fix managed Copilot permission synchronization**
- Relevant commits include `7b293480de8`, `037316fa8b3`, and `1bfbf2cdbd3`.

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

- `github/copilot-agent-runtime` commit `b8469c632e9654aebaabe70c5396866084db4a35`
- PR #14218 — **Runtime: managed-settings fail-open on fetch failure + forceRemoteSettingsRefresh setting**
- Reportedly shipped in runtime `1.0.78-1` / `1.0.78-2`.

The affected session was running Copilot runtime `1.0.77`.

Relevant VS Code dependency update:

- Commit: https://github.com/microsoft/vscode/commit/add330dbd5704e5e27a4aa1bba7f41549ca7e671
- PR: https://github.com/microsoft/vscode/pull/328392
- Updated VS Code to `@github/copilot` 1.0.77 and `@github/copilot-sdk` 1.0.9-preview.1.

### 2. Permission-mode synchronization can wait indefinitely

VS Code serializes permission-mode changes and awaits:

```ts
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: https://github.com/microsoft/vscode/commit/e6549ec3e40aee3e1877dd8b8c4d632574cb71be
- PR: https://github.com/microsoft/vscode/pull/325547 — **AH: 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.

Contributor guide

Open the contributing guide

Research direction

Start in src/vs/platform/agentHost/node/copilot/copilotAgentSession.ts, reading _handlePermissionRequest, _subscribeToPermissionConfigChanges, _syncPermissionModeAfterConfigChange, and syncPermissionMode. Compare the existing behavior with PR 328729 and the referenced runtime correction, then trace the unresolved setAllowAll path. Done means existing sessions recover after policy resolution, Allow All cannot block later turns indefinitely, and the listed regression scenarios are covered.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript, vscode
Domain
devtools, security
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.