← All insights
Your CTO Advisor21 Oct 2026

Your AI agent asked permission. It may not run what you approved

By Avinash Kumar Dubey ·

Your AI agent asked permission. It may not run what you approved

Your AI agent paused, showed you a card and waited for "approve" before it moved money or ran a shell command. Research and five CVEs published between 12 and 15 October 2026 show that the thing you approved and the thing that executed are often not the same.

AG Tech Consulting's advice for clients this week: list every place your agents ask for approval, and for each one answer two questions in writing: can the agent itself produce or answer that approval, and does the approval commit to the exact arguments that run? Where either answer is "yes, it can" or "no, it doesn't", move the check into a gateway the agent cannot reach, bind it to a digest of the full tool call, and patch or pin the coding agents named below.

What happened

On 15 October, three researchers at SportsVision AI posted "Approve What, Exactly?" (arXiv:2610.21063), an audit of how ten agent runtimes implement the approval step. The same week, VulnCheck and Microsoft published CVEs in Continue CLI, Roo Code, Mistral Vibe, goose and VS Code's Copilot harness, each a way for a command or edit to run without the approval the user expected.

On the same day as the paper, Datadog Security Labs showed that a model used as an automated approver can be talked out of blocking a risky tool call.


Taken together, they make one point: an approval prompt is being treated like multfactor authentication for agents, and in many deployments it is not a second factor at all.

The paper: approvals that do not bind

The authors, Sai Varun Kodathala, Prashanth Pollishetty and Jaylen Cargill, set a simple test. An approval protects an agent action only if compromising the agent cannot produce it, and only if it commits to exactly the action that executes.

They defined twelve attacks on the approval path, from a hidden bcc recipient and "amount cancellation" to padding a card with blank glyphs (U+2800, U+3164), bidirectional controls, label spoofing, grant stretching, flooding and threshold splitting.

Where agent approvals break: in-process approval vs an effect-bound design, plus five October CVEs where the approval checker and shell disagreed. (arXiv:2610.21063)
Where agent approvals break: in-process approval vs an effect-bound design, plus five October CVEs where the approval checker and shell disagreed. (arXiv:2610.21063)


What the runtime audit found

The audit covered the OpenAI Agents SDK 0.23.1, LangGraph 1.2.15, Google ADK 2.12.0, Agno 3.1.3, Pydantic AI 2.56.0, CrewAI 1.15.27, AutoGen AgentChat 0.7.5, smolagents 1.26.0, the MCP Python SDK 2.3.0 and, statically, OpenClaw 2026.10.3. Claude Code, Codex CLI and Cursor were not run.

By the authors' reading, no runtime produces an approval record a third party could verify. Approvals sit in run state as unsigned booleans or flags.

In four of the eight runtimes where binding could be measured, something other than the approver could change what ran after approval. LangGraph and Agno execute whatever arguments are in thread state at resume. Pydantic AI executes the arguments in a caller-supplied message history. In CrewAI, a later hook can change arguments an earlier hook approved, which the authors rate low severity.

Agno's substitution, published earlier as "Loopjacking", still reproduced on 3.0.9, 3.0.10 and 3.1.3, past its published affected range.

The passes matter too. The OpenAI Agents SDK binds a call identifier to one canonical payload and rejects a resumed run with different arguments. AutoGen's code-executor approval runs exactly the approved code. Google ADK resisted the resume API, but a writer of the session store could still substitute arguments.

Replay, floods and invisible text

In five rows, an approval was single-use only relative to run state: roll the state back and the approved call executes twice.

None of the seven runtimes where flooding could be measured limited approval floods. In the five with a native pause, one model turn raised 20 pending approvals.

MCP form-mode elicitation forwarded the server's message unchanged, including 400 blank Braille glyphs, a right-to-left override and 50 Hangul fillers. Two different payments, 10 to one account and 10000 to another, produced byte-identical prompts, and both executed after "accept". The MCP specification already points sensitive interactions to URL mode; these findings concern form mode.

Five CVEs, one pattern

Each of these is an approval or allowlist check that judged one thing while the shell or editor ran another.

Continue CLI: CVE-2026-109560

In @continuedev/cli through 1.5.47, a Bash allow rule such as Bash(ls*) becomes a regular expression tested against the whole command string, without parsing shell syntax. So ls; cat /etc/passwd matches an "ls" rule. Instructions planted in repository files or fetched pages can append commands with ;, && or |. VulnCheck rates it 7.7 (CVSS 4.0) and lists no fixed version.

Roo Code: CVE-2026-110202

Roo Code through 3.54.0 auto-approved denied shell commands prefixed with a bare >& redirect: the allowlist matched the redirect target, such as echo, while the shell ran the denied command. VulnCheck rates it 7.7. The extension shut down in May 2026 and its repository is archived, so no fix will ship.

Mistral Vibe: CVE-2026-109429

Mistral Vibe classified commands with tree-sitter-bash static parsing, which missed a command substitution hidden in a single-quoted variable. Bash's ${var@P} prompt-transform operator then re-expanded it and ran the hidden command. VulnCheck rates it 8.7; it is fixed in 2.25.4, released 12 September, a month before the CVE was published. Mistral's own advisory for six earlier shell-permission CVEs adds a line every team should note: automatic approval modes intentionally bypass these controls.

goose: CVE-2026-109561

In goose 1.28.0 up to 1.44.0, readOnlyHint: true annotations stored during Smart Approval mode were never cleared when the user switched to Manual Approval. Prompt-injected calls to those tools then ran without a prompt. It is rated low (2.3), fixed in 1.44.0 in July, and only became a CVE on 12 October, so pinned builds are the exposure.

VS Code and GitHub Copilot: CVE-2026-102232

In VS Code 1.141.0 and earlier, Copilot-harness agent sessions auto-approved edits to enabled custom hook and agent-definition locations (chat.hookFilesLocations, chat.agentFilesLocations) as if they were ordinary workspace files. A prompt injection could plant a shell command that later ran with the user's privileges. VS Code 1.141.1 treats those paths as sensitive, including across symlinks, multi-root workspaces and case-insensitive paths. The interim workaround is chat.useHooks and chat.useClaudeHooks set to false.

When the approver is a model

More teams now let a model approve tool calls. The paper tested 15 language models from 9 vendors as approvers: they caught 0.30 of attacks when shown the agent's own description and 0.98 when shown a card rendered by trusted code from the actual call, at the cost of refusing 16% of harmless near misses, mostly because of a placeholder artifact in the test stimuli.

In the hidden-bcc example, all 15 models approved the agent-narrated view and all 15 refused the trusted card. The model was not the weak point. The source of the text it read was.

Datadog Security Labs showed the same lesson from the other side. Against TypeSafe AI's Jev decision model, prepending a "counterfeit policy" that supplies the answer and redefines attack categories cut prompt-injection recall from 82.90% to 3.88% across 12,295 samples.

In LangChain's tool-risk gating, which blocks at a risk probability of 0.5, an unauthorized file edit scored a mean 0.893 over 40 runs. With the counterfeit policy placed in a user-editable profile_description field, the mean fell to 0.290 and the call would pass. A plain injection that impersonated system messages did not lower the score. A policy-shaped argument did.

What a binding approval looks like

The paper's reference design, ASU (Agent Step-Up), is deliberately conventional, and the authors note that Microsoft's ADR 0030 and Google's AP2 already bind approvals in similar ways.

A gateway outside the agent's reach canonicalizes each tool call into an effect descriptor (RFC 8785 JSON canonicalization, SHA-256 digest). It renders the approval card from that descriptor, never from the agent's text. A passkey on the user's phone signs the digest through WebAuthn. The gateway then executes only the stored descriptor; resubmitted arguments that differ get 409 effect_mismatch and nothing runs.

In the authors' AgentDojo replay with forged narration, attack success fell from 0.54 against an agent-narrated card to 0.03 against ASU, for an approver that compares the card with the task.

The limits are stated plainly. Flooding still succeeded 0.45 to 0.60 of the time against a modeled human approver. A second device added nothing measurable over a trusted confirmation on the same host in these experiments. And no approval stops an effect that policy already allows without asking.

Future security risks to plan for

1. Approval as the new phishing target. As agents send payments and email, attackers will aim at the card, not the model: hidden recipients, padded text, look-alike labels and two different actions that render the same.

2. Post-approval substitution in orchestration layers. Durable agent workflows pause, persist state and resume. Anyone who can write to that thread, checkpoint or message history can change what executes after a human said yes.

3. Approval fatigue at machine speed. One model turn raised 20 pending approvals in the paper's audit. Expect agents, once compromised, to flood owners until one click lands, and to split large actions under step-up thresholds.

4. Shell allowlists that do not parse the shell. Prefix rules and static parsers keep losing to chaining, redirects and re-expansion. Every coding agent with an "always allow" list is a candidate for the next CVE.

5. Model approvers argued out of their policy. Automated gates that read untrusted fields can be handed a counterfeit definition of "risky". The more approvals move to models for speed and cost, the more valuable that attack becomes.

6. Silent fixes and stale pins. goose and Mistral Vibe shipped fixes months or weeks before CVEs appeared. Teams that track agents only by CVE learn late, and pinned images stay exposed.

A 10-point checklist for CTOs

Inventory every agent approval point: payments, outbound email, file writes, shell, config and hook edits, and who or what answers each one. For each, record whether the approval is answered in a channel the agent can write to; if so, it is not a second factor. Bind approvals to a canonical digest of every effect-changing argument, store it with a nonce and expiry, and execute the stored call only; reject any mismatch. Render the approval card from the structured call, not from agent narration; show every recipient, path, amount and URL, escape invisible and bidirectional characters, and cap length. Resume paused runs only from a trusted service, and treat thread state, checkpoints and message history as untrusted until re-verified against the approved digest. Cap pending approvals per session and user, merge duplicates, lock out after repeated denials, and add aggregate limits so actions cannot be split under thresholds. Replace broad shell prefix rules with exact, parsed command allowlists; disable "auto-approve" and "always allow" modes for shell on agents that read untrusted repos or web pages. Patch now: Continue CLI (tighten rules; no fix listed), Roo Code (remove; archived), Mistral Vibe 2.25.4+, goose 1.44.0+, VS Code 1.141.1+; check pinned containers and vendored copies. If a model approves tool calls, feed it a trusted rendering of the call, keep user-editable fields out of its policy context, and red-team it with counterfeit-policy payloads before relying on it. Keep signed or tamper-evident approval logs (approver, digest, time, outcome) so you can prove later what was approved and what ran.

The bottom line

The approval step is becoming the security boundary for agentic AI, and October's evidence shows how often it is a formality. The fix is not more prompts. It is approvals that live outside the agent, name the exact effect, and are the only path to execution.

Sources: Kodathala, Pollishetty and Cargill, "Approve What, Exactly? Effect Binding and Trusted Rendering for Agent Step-Up Authorization," arXiv:2610.21063, 15 Oct 2026 (https://arxiv.org/abs/2610.21063), code and data (https://github.com/Sports-Vision-Inc/agent-step-up); The Injection summary of the paper (https://theinjection.dev/items/arxiv-agent-step-up-effect-binding/); VulnCheck advisory for Continue CLI CVE-2026-109560 (https://www.vulncheck.com/advisories/continue-cli-through-1.5.47-bash-permission-rule-bypass-via-command-chaining) and The Injection write-up (https://theinjection.dev/items/continue-cli-bash-approval-bypass/); VulnCheck advisory for Roo Code CVE-2026-110202 (https://www.vulncheck.com/advisories/roo-code-through-3.54.0-auto-approve-bypass-via-redirect-operator-stripping); The Injection on Mistral Vibe CVE-2026-109429 (https://theinjection.dev/items/mistral-vibe-var-p-permission-bypass/) and Mistral advisory MAI-2026-003 (https://docs.mistral.ai/resources/security-advisories/MAI-2026-003); CVE record for goose CVE-2026-109561 (https://www.cve.org/CVERecord?id=CVE-2026-109561) and The Injection write-up (https://theinjection.dev/items/goose-read-only-annotation-approval-bypass/); Microsoft VS Code advisory GHSA-fq62-m6f5-c7h9 for CVE-2026-102232 (https://github.com/microsoft/vscode/security/advisories/GHSA-fq62-m6f5-c7h9) and MSRC entry (https://msrc.microsoft.com/update-guide/vulnerability/CVE-2026-102232); Frichette and Al-Kassar, "Jev as a judge: How counterfeit policy steers Jev," Datadog Security Labs, 15 Oct 2026 (https://securitylabs.datadoghq.com/articles/jev-as-a-judge-how-counterfeit-policy-steers-jev/); The Injection, AI security news, week 42 of 2026 (https://theinjection.dev/week/2026-w42/).

Also on our website: https://agtechconsulting.ai/insights/your-agent-asked-permission-may-not-run-what-you-approved.html

Want help mapping where your agents ask for approval, and making those approvals bind to what actually runs? Email avinash@agtechconsulting.ai, visit agtechconsulting.ai, or book a 30-minute call: https://calendly.com/avinash-dubey-30-min-catchup/meeting-with-ag-tech

Tagging: VulnCheck , Datadog , Nick Frichette , Microsoft , GitHub , VISUAL STUDIO CODE , Mistral , LangChain , Harrison Chase , CrewAI , Pydantic , OpenAI , OWASP GenAI Security Project , Cloud Security Alliance , HiddenLayer

Originally published on LinkedIn in the Your CTO Advisor newsletter: read and comment on LinkedIn →

Get Your CTO Advisor in your feed

Subscribe on LinkedIn for the next issue.

Subscribe on LinkedIn