-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
Summary
The --headless protocol allowed clients to declare tool permissions at session creation via CLI flags: --yolo, --allowed-tools, --allow-all-tools. These flags established a security boundary before the agent executed its first action. The agent could not escalate beyond what the client authorized at spawn time.
The ACP protocol (--acp) has no equivalent mechanism. There is no way to declare tool permissions at session creation. The session/new and initialize RPC methods accept no permission parameters. This is a security regression.
What --headless provided
# Client declares exactly which tools the agent may use — before it runs
copilot --headless --stdio --allowed-tools "read_file,write_file,run_shell"
# Or: trust everything (explicit opt-in to full access)
copilot --headless --stdio --yoloThe permission model was:
- Client spawns CLI with explicit tool constraints
- Agent runs within those constraints
- Agent cannot escalate — the boundary was set before the first prompt
What ACP provides
copilot --acpNo --allowed-tools. No --yolo. No --allow-all-tools. The session/new RPC method accepts model, previousSessionId, and systemPrompt — no permission fields.
Tool permission handling in ACP is broken in multiple ways:
- Custom tools registered via
session/neware silently ignored (Title: ACP agent ignores custom JSON‑RPC methods and only exposes internal tool list #1574) - Tool IDs in permission requests don't match the IDs the CLI expects in responses (copilot --acp responses return incorrect tool IDs when requesting permissions #989)
- There is no documented mechanism for a client to restrict which built-in tools the agent may invoke
Why this matters
Every ACP client must now implement its own permission enforcement — or ship without one. The old model pushed this responsibility to the CLI, where it could be enforced consistently across all clients. The new model distributes it to every adopter, and if any one of them gets it wrong (or skips it), the agent runs unconstrained.
This is especially concerning for:
- VS Code extensions that embed Copilot in a sidebar where users don't expect file writes or shell execution without consent
- CI/CD integrations where an unconstrained agent could modify build artifacts, credentials, or deployment configs
- Third-party applications building on the SDK/ACP where developers may not understand the trust model
Expected behavior
ACP should support session-level permission declaration equivalent to what --headless provided. At minimum:
session/newshould accept anallowedToolsparameter that restricts the agent's tool access for the entire session- A
permissionModefield (equivalent to--yolo/ default / restricted) that the CLI enforces server-side - Tool permission requests should use consistent IDs that clients can match and respond to (copilot --acp responses return incorrect tool IDs when requesting permissions #989)
Permissions declared at session creation are a security boundary. Mid-session negotiation is a footgun.
Related
- Title: ACP agent ignores custom JSON‑RPC methods and only exposes internal tool list #1574 — Custom tools silently ignored in ACP
- copilot --acp responses return incorrect tool IDs when requesting permissions #989 — Tool ID mismatch in ACP permission requests
- Breaking change: --headless --stdio removed without deprecation, breaks copilot-sdk and all downstream integrations #1606 —
--headlessremoved without deprecation (the protocol that had these primitives)