Skip to content

A subject agent's runtime built-in peer messaging can exfiltrate session-private content to unrelated local sessions #998

Description

@Poytr1

What happened (caught live, cross-verified)

During a real-model webchat Werewolf trial, the doctor player — a local Claude Code subject over ACP — answered its private needsReply delegations through the runtime's built-in SendMessage tool instead of mcp__agentconnect__sendMessage (the #800 name collision). The built-in call did not fail silently: it delivered, to an unrelated local Claude session on the same machine, which received first ROLE-ACK: player-4 and then I protect player-4. — a game-private night action. The receiving session verified the sender as a claude CLI process whose --mcp-config pointed at the trial daemon's MCP socket, i.e. unambiguously the game's doctor subject.

The trial artifacts show the matching daemon-side signature: built-in SendMessage tool calls in the child's turns, a final output that only NARRATES the send ("Sent my Night 1 protection choice (self) to the referee."), and #984's inferred reply delivering that narration — the wake arrived, but the content had already left the game.

Why this is its own issue, beyond #800

#800 frames the collision as a LOST report (and the inferred-reply fix now recovers the lost-report symptom — in the same trial it salvaged a prose kill statement and a role ack). This finding is the other half: the built-in channel is not a black hole, it is a working delivery channel to whatever local session it can address. Any AgentConnect child session handling confidential content (delegated task details, private game state, per-tenant material) can leak it to arbitrary co-located sessions through one mis-picked tool — a boundary the product has no model of and no audit trail for.

Mitigation path

claude-agent-acp forwards sessionMeta.claudeCode.options.disallowedTools (verified against the adapter dist), so the daemon could suppress the built-in messaging tools for AgentConnect-managed sessions at session/new. Inferred reply (#984) treats the lost-report symptom; only tool suppression prevents the misdelivery itself. Needs a runtime-gated seam through AcpHost's _meta channel and confidence that Claude Code's own subagent machinery tolerates it.

Refs #800 (the collision), #984 (inferred reply — symptom-level recovery), #941 (the measuring harness).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions