AI Agent Governance Does Not Survive The Approval Prompt
Most AI agent governance is a dialog box. The agent proposes a shell command, the developer reads it or does not, and clicks. Whatever survives that click, repeated all day, is the real policy. Two vendors shipped changes in the last fortnight that move the boundary off that click, from opposite ends: one removes most of the prompts, the other makes the remaining ones impossible to switch off from below.
GitHub made enterprise managed permissions for Copilot agent operations generally available on 9 September. An administrator on Copilot Business or Enterprise can now declare centrally that an agent operation is blocked, needs a human, or runs unattended. Three categories are covered: shell commands, file reads and edits, and network domains. The sentence worth the money is the one about what cannot undo it — user settings, workspace settings, auto-approval, and approvals a developer already granted.
What the reference says that the announcement did not
Policy lives in a file named managed-settings.json, and the model is three-tier. A deny rule is unconditional and beats everything else. An allow rule runs without a prompt. An ask rule demands a fresh human decision every time, and the reference is explicit that bypass mode, auto-approval settings, approval hooks and shortcuts, and previously persisted approvals cannot satisfy it. Setting permissions.disableBypassPermissionsMode to disable switches off the VS Code global auto-approve setting, chat.tools.global.autoApprove, suppresses the bypass options on the CLI, and blocks the Allow all control in the Copilot app.
Operations are selectors, not prose: Shell(command) with a trailing star for prefix matching, Read(path) and Edit(path) over globs anchored at // for the filesystem root, / for the workspace root, ~/ for home and ./ for the current directory, and Domain(host), where a bare host means HTTPS and a leading star-dot covers subdomains.
Two things the changelog left out are worth the trip to the docs.
The first is coverage. The permissions.deny, permissions.ask and permissions.allow keys apply in VS Code only inside Agent Host sessions, and the Copilot cloud agent supports none of the three — nor the telemetry, remoteControl, deniedMcpServers or sandbox keys. The agent that runs with nobody watching is the one this permission model does not reach. JetBrains IDEs get less again: model, enabledPlugins, the marketplace keys, and allowedMcpServers. A separate changelog the day before put enterprise-managed sandbox policy for JetBrains into public preview, covering filesystem and network access, proxy settings, developer-tool access and macOS Keychain access, with managed restrictions overriding user settings — a second surface for the same question.
The second is precedence, and it is the one that will generate tickets. Once any managed source defines permission rules, or an allow list exists at any level, an operation matching nothing falls through to ask rather than to the normal flow. A four-line allow list does not authorise four things and leave the rest alone. It converts every unlisted operation in the organisation into a prompt. Two smaller edges: deny rules cannot block first-party Copilot servers, the built-in GitHub MCP server among them, and where several sources define MCP policy the allowlist is intersected while the denylist is unioned.
The same conclusion, reached from the other side
LM Studio published the internals of Auto Review in Bionic on 27 August. The design does not harden the prompt; it removes most of them. A deterministic Shell Judge parses the command into an abstract syntax tree — mvdan/sh for sh, bash and zsh, PowerShell's own parser for PowerShell — extracts a ShellCapability describing what the command could do in the worst case, and matches that against a ruleset. The posture is refusal by default: an AST structure it does not recognise is rejected rather than guessed at, environment variable assignments are rejected outright, and variable expansion is tracked only to a limit of 1,000 alternatives. Their rule for cat permits reading readable files or standard input, which is what rejects /etc/passwd. That machinery approves roughly 82% of commands with no prompt at all. Only the remainder reaches an LLM reviewer, which grades risk and whether the user actually authorised the action, without being told the passing threshold.
Note what the 82% buys. It is not throughput. It is the count of prompts a developer never sees, and therefore the reason the prompts that remain still get read.
Why teams keep walking into it
The prompt is the cheapest control to build and the easiest to demo, and it passes review on paper: a human approved every action, and there is a log. What the log does not show is the drift. The person being asked is the person whose work is blocked by the asking, so the approval surface gets tuned in the only direction that is available to them.
Stated so it can be wrong: any agent permission surface a developer can edit will drift permissive under daily use, and the useful controls are the ones defined somewhere they cannot reach. What would falsify it is a team running agent sessions at volume for a quarter on local settings alone, showing a refusal rate at the prompt that is neither trivial nor falling. If that team exists, the boundary belongs where it already is.
This is the same shape as the pilot-to-production gap in why enterprise AI doesn't ship and POC to production AI: the control that works in a pilot is the one nobody has had to click a few hundred times yet. Deciding which operations are allowed, denied and asked — before the agent is in front of the whole engineering org — is part of the scoping work in AI agent development, not a setting to tune afterwards.
The cheapest way out
Write the allow list first, and make it long. Pull the commands your agents actually ran this week out of your own session logs and put them in permissions.allow as prefix selectors, because of the precedence rule above: the shorter that list, the more prompts you have created. Put the irreversible operations in permissions.deny, and the small set where a human decision is genuinely worth the interruption in permissions.ask, then set permissions.disableBypassPermissionsMode to disable so that set cannot be traded away locally.
Then measure one number: prompts per developer per day. Above roughly ten, the policy is training people to click rather than to read, and the fix is a longer allow list, not a firmer prompt. And write down separately how the cloud agent is bounded, because the keys it accepts do not include these.
Related reading
- AI Engineering
PatchTST-FM-r2 Beats r1 on Average and Loses on 24 of 97 GIFT-Eval Configurations
By Petru Popa · Read - AI Engineering
GHES 3.22 Points Copilot CLI At A Private LLM, One Per Instance
By Petru Popa · Read - AI Engineering
Ai2 Audited 16 LLM Benchmarks. Nearly Half the Safety Questions Score Reasoning.
By Petru Popa · Read
Turn this into a plan for your team.
One week, fixed fee: a working session with your team, a prioritized use-case backlog, and an ROI model for the opportunities worth chasing.