feat: replace legacy exec approvals with V2 - #1051
Conversation
|
Codex review: found issues before merge. Reviewed July 28, 2026, 2:03 AM ET / 06:03 UTC. ClawSweeper reviewWhat this changesThis PR replaces Windows command-text approval rules with a V2 executable-identity approval system, makes low-level Merge readinessKeep this PR open for maintainer review. The V2 authorization design and real MXC/MCP proof are substantial, but the branch intentionally breaks existing raw string-form Priority: P1 Review scores
Verification
How this fits togetherGateway, MCP, CLI, and plugin callers send flowchart LR
A[Gateway, MCP, CLI, plugins] --> B[Windows node request]
B --> C[Canonical argv validation]
C --> D[V2 approval policy]
D --> E[Native approval dialog]
D --> F[Approved execution payload]
F --> G[Local or MXC runner]
G --> H[Command result]
Decision needed
Why: The security model makes automatic V1 rule conversion unsafe, but rejecting a documented existing request shape and discarding prior policy semantics changes real user upgrades. The supplied discussion records the author’s rationale but not an approving maintainer decision. Before merge
Findings
Agent review detailsSecurityNeeds attention: The V2 path appears designed to fail closed and the reported remote-policy weakening fix is focused, but retiring persisted V1 policy enforcement changes a security boundary and needs explicit upgrade acceptance. Review metrics
Merge-risk optionsMaintainer options:
Technical reviewBest possible solution: Keep the V2 executable-identity coordinator and MXC argv path, but either preserve the supported raw string-call boundary with a narrow canonicalization shim and visible V1 reapproval notice, or obtain explicit maintainer approval for a versioned breaking change with migration guidance and release communication. Do we have a high-confidence way to reproduce the issue? Not applicable: this PR proposes a new default authorization architecture rather than fixing a reported current-main failure. The PR does provide high-signal live evidence for the changed MXC and MCP execution paths. Is this the best way to solve the issue? No, not yet. The V2 coordinator is a coherent security direction, but the default cutover is not the best merge-ready solution until maintainers decide whether existing low-level callers and stored V1 policy intent require a compatibility boundary or an explicitly accepted breaking-release path. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against fe43b157b561. LabelsLabel justifications:
EvidenceSecurity concerns:
What 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 (3 earlier review cycles)
|
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
@clawsweeper re-review |
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
f7e2ae0 to
c444067
Compare
|
I am holding this below the repository's 90% merge-confidence bar after independent Opus and Codex reviews of the current head
The first two may be deliberate product decisions, but they need explicit release handling. The third is a concrete authorization-policy gap that should be fixed before merge. |
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
@shanselman Thanks for the review. The concrete remote-policy weakening gap is fixed on the updated head:
Explicit product/release decision for the other two items:
Current validation: build green; Shared 3,249 passed / 32 skipped; Tray 1,954; CLI 126; SetupEngine 697; Tray Integration 19; MXC E2E 2/2 with true contained Access denied proof. Opus and Sol found no remaining actionable issues at 95% / 96% confidence. Please reconsider the merge-confidence gate on the updated head. |
|
@clawsweeper re-review |
|
🦞👀 Command router queued. I will update this comment with the next step. |
Summary
system.runandsystem.run.preparecanonical argv-only, matching the upstream gateway contract.cmd.exe /d /s /c.Architecture ownership
SystemCapability,ExecApprovalPolicy, andExecApprovalPromptServicesplit approval text matching, prompting, and shell execution across parallel paths.ExecApprovalsCoordinatorowns authorization;ExecApprovalsStoreowns policy persistence/CAS;ExecApprovalV2UiPromptHandlerandExecApprovalDialogown presentation; runners receive only the approved execution payload.Behavior changes
commandasstring[]argv. The normal gatewayexec host=nodepath already wraps Windows command strings as["cmd.exe","/d","/s","/c",command].node.invoke, plugin, andwinnodecallers migrate from{"command":"echo hello","shell":"cmd"}to{"command":["cmd.exe","/d","/s","/c","echo hello"],"rawCommand":"echo hello"}. String requests returncommand-array-required.security=allowlist,ask=on-miss,askFallback=deny, and an empty allowlist. Only truly missing trustworthy state gets this default; invalid or unreadable active/legacy paths fail closed tosecurity=deny.envis rejected until environment values can be identity-bound and displayed safely.system.execApprovals.setmay preserve/remove existing grants and preserve/tighten effective policy, but cannot add/change grants or weakensecurity,ask,askFallback, orautoAllowSkills.%APPDATA%\OpenClawTray\exec-approvals.json;OPENCLAW_STATE_DIRoverrides it.Upgrade contract
Windows V1
exec-policy.jsoncommand-text globs are intentionally retired without migration.Mechanical conversion and V1 runtime fallback were rejected because V1 authorized shell command text while V2 binds resolved executable identity and canonical argv. Conversion could widen narrow text rules into broad command-host grants, while dual evaluators would preserve parallel authorization paths.
Validation
.\build.ps1dotnet test .\tests\OpenClaw.Shared.Tests\OpenClaw.Shared.Tests.csproj --no-restoredotnet test .\tests\OpenClaw.Tray.Tests\OpenClaw.Tray.Tests.csproj --no-restoredotnet test .\tests\OpenClaw.WinNode.Cli.Tests\OpenClaw.WinNode.Cli.Tests.csproj --no-restoredotnet test .\tests\OpenClaw.SetupEngine.Tests\OpenClaw.SetupEngine.Tests.csproj --no-restoredotnet test .\tests\OpenClaw.Tray.IntegrationTests\OpenClaw.Tray.IntegrationTests.csproj --no-restore.\scripts\validate-mxc-e2e.ps1Real behavior proof
Gateway to Windows node to MXC
Canonical argv:
Observed:
The companion execution proof returned the expected marker with exit code 0 through the same contained path.
Local MCP
winnode --list-toolsadvertised:Canonical invocation returned:
{ "stdout": "OPENCLAW_LOCAL_MCP_CANONICAL_ARGV_OK", "stderr": "", "exitCode": 0, "timedOut": false, "success": true }Runtime logs confirmed
path=v2,decision=Allow,contained=True, andcontainment=mxc.Upgrade characterization
Automated upgrade tests cover:
Adversarial review
Claude Opus 4.8 and GPT-5.6 Sol independently reviewed the complete diff through three rounds with cross-model challenge and re-review after fixes.