Skip to content

[Security] ACP protocol lacks session-level tool permission primitives that --headless provided #1607

Closed

Description

@darthmolen

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 --yolo

The permission model was:

  1. Client spawns CLI with explicit tool constraints
  2. Agent runs within those constraints
  3. Agent cannot escalate — the boundary was set before the first prompt

What ACP provides

copilot --acp

No --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:

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:

  1. session/new should accept an allowedTools parameter that restricts the agent's tool access for the entire session
  2. A permissionMode field (equivalent to --yolo / default / restricted) that the CLI enforces server-side
  3. 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

Activity

  1. added
    area:non-interactiveNon-interactive mode (-p), CI/CD, ACP protocol, and headless automation
    on Apr 6, 2026
  2. added
    area:permissionsTool approval, security boundaries, sandbox mode, and directory restrictions
    area:authenticationLogin, OAuth, device auth, token management, and keychain integration
    area:sessionsSession management, resume, history, session picker, and session state
    on Apr 6, 2026
  3. stefandevo commented on May 4, 2026

    @stefandevo

    We really need that permission support in ACP - this agent is one of the few that does not support a permission dropdown in Zed for example and asks permissions for everything

  4. patniko commented on Oct 26, 2026

    @patniko
    Collaborator

    Thanks for raising this. ACP mode enforces spawn-time permission boundaries: start copilot --acp with the same flags you would use elsewhere (--allow-tool/--deny-tool, --allow-all-tools or --yolo, and --available-tools/--excluded-tools) and they apply to the sessions on that connection, with tool exclusions that an ACP client can't lift. Clients can additionally toggle allow-all per session through the allow_all session config option, and the tool-filtering flags have applied correctly in ACP mode since Copilot CLI v1.0.60. If a launch flag isn't honored in ACP mode on the latest version, please reopen with a repro.

    Triaged as part of a Copilot SDK backlog review, with help from GitHub Copilot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:authenticationLogin, OAuth, device auth, token management, and keychain integrationarea:non-interactiveNon-interactive mode (-p), CI/CD, ACP protocol, and headless automationarea:permissionsTool approval, security boundaries, sandbox mode, and directory restrictionsarea:sessionsSession management, resume, history, session picker, and session state

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions