fix(mcp): require owner for Claude permission replies#98256
Conversation
|
Codex review: needs maintainer review before merge. Reviewed June 30, 2026, 4:34 PM ET / 20:34 UTC. Summary PR surface: Source +37, Tests +145, Docs 0. Total +182 across 16 files. Reproducibility: yes. from source inspection: current main resolves a pending Claude permission from any matching yes/no short-id session message before checking role or owner metadata. I did not run a failing current-main live repro, but the PR's Docker artifact proves the after-fix owner and non-owner paths on the PR head. Review metrics: 2 noteworthy metrics.
Stored data model Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Merge this owner-gated approval fix after maintainers explicitly accept the fail-closed missing-metadata behavior and the exact head remains green with the Docker MCP-channel proof. Do we have a high-confidence way to reproduce the issue? Yes, from source inspection: current main resolves a pending Claude permission from any matching yes/no short-id session message before checking role or owner metadata. I did not run a failing current-main live repro, but the PR's Docker artifact proves the after-fix owner and non-owner paths on the PR head. Is this the best way to solve the issue? Yes for the code shape: carrying the authenticated owner bit and gating at the MCP bridge is narrower than adding a required permission-request protocol field and also blocks same-session non-owner replies. The unresolved question is maintainer acceptance of the fail-closed compatibility behavior. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 9f07b21e6231. Label changesLabel justifications:
Evidence reviewedPR surface: Source +37, Tests +145, Docs 0. Total +182 across 16 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
|
Behavioral proof is now available on the current PR head. Real setup: the targeted workflow packed the candidate, installed it into the functional Docker image, launched a real Gateway, connected the real stdio MCP server, and exercised the permission flow through authenticated Gateway clients. No provider credentials or private channel identifiers were used. Observed sequence:
Redacted artifact output: {
"ok": true,
"nonOwnerReplyForwarded": true,
"nonOwnerPermissionBlocked": true,
"ownerPermissionAllowed": true
}The The durable scenario is checked in under Compatibility decision for maintainer review: missing trusted ownership metadata intentionally fails closed for permission decisions while preserving the reply as an ordinary message. This prevents an unauthenticated ownership claim from becoming an approval; transports that want text approvals must carry the ownership decision established at authenticated ingress. Additional fresh validation:
|
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
* fix(mcp): require owner for Claude permission replies * fix(mcp): prove owner-gated permission replies
* fix(mcp): require owner for Claude permission replies * fix(mcp): prove owner-gated permission replies
* fix(mcp): require owner for Claude permission replies * fix(mcp): prove owner-gated permission replies
* fix(mcp): require owner for Claude permission replies * fix(mcp): prove owner-gated permission replies
Summary
What Problem This Solves
Claude channel permission replies were matched only by the short pending request ID. A non-owner channel participant could therefore resolve a privileged Claude Code permission prompt by sending a matching
yes <id>orno <id>message.Changes
Why This Change Was Made
senderIsOwnerdecision from channel and Gateway ingress through user-turn transcript persistence andsession.messagebroadcasts.notifications/claude/channel/permission.User Impact
Command owners retain the existing text-reply approval flow. Non-owners, assistant messages, and messages without authenticated ownership metadata can no longer approve or deny Claude Code permission requests.
Validation
Evidence
nonOwnerReplyForwarded: true,nonOwnerPermissionBlocked: true,ownerPermissionAllowed: true.node scripts/run-vitest.mjs src/mcp/channel-bridge.test.ts src/mcp/channel-server.test.ts src/gateway/server-session-events.test.ts src/sessions/user-turn-transcript.test.ts src/auto-reply/reply/get-reply-run.media-only.test.ts src/gateway/server-methods/chat.directive-tags.test.ts— 8 files, 408 tests passed across 3 shards.node scripts/run-vitest.mjs test/scripts/docker-e2e-observability.test.ts test/scripts/test-projects.test.ts— 2 files, 188 tests passed.node_modules/.bin/oxfmt --check --threads=1 <changed files>— passed.node scripts/check-docs-mdx.mjs docs/cli/mcp.md— passed.git diff --check upstream/main...HEAD— passed.Notes