github / github/copilot-cli

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

Open
#1,607 1 comment 0 reactions 0 assignees View on GitHub
area:authentication area:non-interactive area:permissions area:sessions
Dominant language
Shell
Stars
11.2k
Forks
1.9k
Avg merge
14h 16m
Merged PRs (30d)
6

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

```bash
# 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

```bash
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:
- Custom tools registered via `session/new` are silently ignored (#1574)
- Tool IDs in permission requests don't match the IDs the CLI expects in responses (#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:

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 (#989)

Permissions declared at session creation are a security boundary. Mid-session negotiation is a footgun.

## Related

- #1574 — Custom tools silently ignored in ACP
- #989 — Tool ID mismatch in ACP permission requests
- #1606 — `--headless` removed without deprecation (the protocol that had these primitives)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.