fix(node): trust gateway session attribution only - #1072
Conversation
|
Codex review: needs maintainer review before merge. Reviewed August 7, 2026, 9:38 PM ET / August 8, 2026, 01:38 UTC. ClawSweeper reviewWhat this changesThe PR accepts session attribution only from Gateway invocation envelopes, ignores nested command session data, and adds transport and approval regression coverage. Merge readinessThis PR remains necessary: current main still falls back to caller-controlled nested session data. The patch cleanly narrows that trust boundary, but merge should wait for direct current-head Gateway attribution proof. Priority: P1 Review scores
Verification
How this fits togetherThe Windows node decodes Gateway invocation envelopes, passes attribution into exec approval planning, and executes node capabilities. This PR protects the envelope-to-command boundary so caller arguments cannot select an approval session. flowchart LR
Gateway[Gateway invocation envelope] --> Decode[Windows node decoding]
Decode --> Trust[Trusted session attribution]
Decode --> Args[Caller command arguments]
Trust --> Approval[Approval and run planning]
Args --> Capability[Capability execution]
Approval --> Capability
Capability --> Response[Gateway response]
Before merge
Agent review detailsSecurityNone. Review metrics
Merge-risk optionsMaintainer options:
Technical reviewBest possible solution: Keep a single transport-owned attribution source, then attach a redacted exact-head Gateway trace proving envelope precedence and nested-value rejection before merge. Do we have a high-confidence way to reproduce the issue? Yes. Send either supported Gateway envelope with conflicting envelope and nested session keys; current source and focused tests establish the expected trusted value. Is this the best way to solve the issue? Yes. Reading attribution only at the decoded Gateway envelope is the narrowest maintainable ownership boundary, provided both supported envelope shapes remain contractually trusted. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 603886a81d34. LabelsLabel changes:
Label justifications:
EvidenceWhat I checked:
Likely related people:
Rank-up movesOptional improvements that raise the rating; they are not merge blockers.
Rating scale
Overall follows the weaker of proof and patch quality. Workflow
HistoryReview history (23 earlier review cycles; latest 8 shown)
|
|
Adversarial maintainer review found blocking protocol regressions, so this draft should not be marked ready yet:
Please accept both string/object unknown-method errors case-insensitively, preserve trusted request-envelope attribution, and dispatch/respond to cancellation without waiting on negotiation. Current merge confidence is 35%. |
4a137f6 to
44e8c78
Compare
|
Exact-head native Windows CI is terminal green at The current authoring environment has no Windows/Parallels/MXC runtime lane, so the real Gateway trace remains an explicit residual compatibility risk in the PR body. I am marking the PR ready for human review, not representing that unavailable proof as completed. |
Remove the unsupported protocol feature publication and treat top-level Gateway envelope attribution as optional on each invocation. Preserve older Gateway compatibility by leaving unattributed calls unset while rejecting nested forgery attempts. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
8738d67 to
b5a37b8
Compare
|
Maintainer acceptance for exact head |
What Problem This Solves
The Windows node must accept session attribution only from the Gateway-stamped top-level
node.invoke.request.payload.sessionKey. Caller-controlled nested command data such asargs.sessionKeyorparams.sessionKeymust never be able to forge that attribution.Why This Change Was Made
Current Gateway runtime code sends
sessionKeyas an optional sibling ofparamsJSON. Stable older Gateways omit it, and there is no supported feature-announcement request for this field.This change therefore applies the contract per invocation:
sessionKeydata from command arguments.NodeInvokeRequest.SessionKeyremains transport-owned through[JsonIgnore]plus an internal setter. Approval validation andsystem.run.prepareconsume only that trusted value.This branch was replayed onto main at
603886a81d3495c173802af864a5c71c3c880cae, preserving #1076's correlated nodehello-okresponse guard and immediate pre-credential handshake authorization.User Impact
New Gateways can provide trusted session attribution. Older Gateways remain compatible by omission: their invocations execute without attribution instead of trusting nested caller data.
Validation
Exact head:
b5a37b8427cecf5725544af450de210fe3246142.git diff --check origin/main..HEAD: passed.$env:OPENCLAW_REPO_ROOT = (Get-Location).Path; .\build.ps1: passed.dotnet test .\tests\OpenClaw.Shared.Tests\OpenClaw.Shared.Tests.csproj --no-restore: 3,631 passed, 32 skipped.dotnet test .\tests\OpenClaw.Tray.Tests\OpenClaw.Tray.Tests.csproj: 2,241 passed.dotnet test .\tests\OpenClaw.WinNode.Cli.Tests\OpenClaw.WinNode.Cli.Tests.csproj: 126 passed..\scripts\validate-mxc-e2e.ps1without-AllowSkip: 15 passed, 0 skipped.python .\.agents\skills\autoreview\scripts\autoreview --mode branch --base origin/main --engine codex --model gpt-5.6-sol --thinking high: clean, no actionable findings, correctness confidence 0.92.Real behavior proof
Strict Gateway-to-Windows-node MXC proof completed successfully on the current head:
The proof included real Gateway
node.invokepaths for bound executable execution, sandboxedsystem.run, and denied writes to the isolated tray data directory.An isolated current-head tray instance was launched in MCP-only mode with a session-scoped data directory. No real tray settings, Gateway credentials, or identities were read or modified.
The isolated process was stopped and its generated token/data directory was deleted after proof collection.
The user's paired Gateway was not used because the strict disposable Gateway E2E proved the same real gateway-mediated invocation path without risking mutation of the user's saved profile or connection.