fix(permissions): the Permissions page hides wildcard exec rules - #1506
Conversation
- Resolve the Permissions default action through main, then *, then defaults - List wildcard allowlist entries as well as main Signed-off-by: Sebastien Tardif <SebTardif@ncf.ca>
|
🦞👀 Pull request received. I will update this pull request when review starts. ClawSweeper review completeClawSweeper finished reviewing this revision. The review result is being finalized. |
|
Codex review: needs maintainer review before merge. Reviewed September 27, 2026, 2:49 PM ET / 18:49 UTC (Revision 15). ClawSweeper reviewWhat this changesThe Windows tray Permissions page now shows main and wildcard execution rules with their scopes, removes rules from their original scope, and keeps inherited Deny effective when adding a rule could activate older grants. Merge readiness✅ Ready for maintainer review The current head addresses the earlier review findings and has current-head native UI and command-effect proof. The requested behavior is absent from current main, so this PR remains a useful landing candidate. Priority: P1 Review scores
Verification
How this fits togetherThe Permissions page reads the Windows node's stored execution-approval policy and lets users edit its rules. The execution path resolves that policy before deciding whether a requested command may run. flowchart LR
A[Stored exec policy] --> B[Permissions page]
B --> C[Scoped rule display]
B --> D[Add or remove rule]
D --> A
A --> E[Runtime policy resolver]
E --> F[Allow, prompt, or deny]
F --> G[Command execution]
Before mergeNone. Agent review detailsSecurityNone. Review metrics
Technical reviewBest possible solution: Land the scoped editor behavior with its persisted-file regressions and retain the verified rule that inherited Deny prevents command execution before the final side effect. Do we have a high-confidence way to reproduce the issue? Yes, from source: current main projects only main rules, while the runtime merges main and wildcard rules. The earlier Add transition also differs from the runtime's inherited policy cascade. Is this the best way to solve the issue? Yes. The patch repairs the existing editor projection and mutations without changing the runtime executor or stored-file schema. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning medium; reviewed against ed0c045cfe60. LabelsLabel changes: No label changes. Label justifications:
EvidenceWhat I checked:
Likely related people:
Rating scale
Overall follows the weaker of proof and patch quality. Workflow
HistoryReview history (14 earlier review cycles; latest 8 shown)
|
Preserve wildcard/main rule provenance through CAS removal and use the displayed policy cascade when adding a main rule. Cover cross-bucket duplicate IDs, ID-less argument variants, concurrent replacement, inherited policy, and fresh-store persistence. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4e7c9166-338e-44fb-828a-577c05de49b7
|
Global triage: HOLD_FOR_AUTHOR. Take confidence 35%; recommendation confidence 93%; effort medium; risk high. Reviewed exact head Owner: |
|
Hi @karkarl, Copilot here helping Scott close the native proof gap. Scott confirms this machine does not support BaseContainer (the strict probe selects For each result, please include the exact SHA, whether BaseContainer was actually selected, non-skipped MXC test counts, and the real WSL Gateway -> Windows node |
|
Maintainer product decision for this original PR, following Karen's exact-head review at |
Signed-off-by: Sebastien Tardif <SebTardif@ncf.ca>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9ba54a2d-477b-4b8e-994c-5fb3755d8b01
A wildcard row and a main row with the same pattern now show wildcard or main in the list and in the Remove name. Adding a rule while wildcard security is Deny and Ask is Off, and main security is unset, stores the new pattern without switching main to Allowlist. Inherited Deny/Always still enables only the main allowlist and keeps Ask Always. ./build.ps1 exit 0. Shared tests: 4107 passed, 32 skipped. Tray tests: 3133 passed, 0 failed. Signed-off-by: Sebastien Tardif <SebTardif@ncf.ca>
|
I saw and preserved the concurrent author update |
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9ba54a2d-477b-4b8e-994c-5fb3755d8b01
|
Current head is now This preserves Seb's concurrent Validation
Current-head visible UI proof is being captured separately now. @clawsweeper re-review |
|
🦞👀 Re-review progress:
|
Current-head visible UI proofValidated
This is current-head native WinUI evidence of the changed state. The real-store regression additionally proves both entries remain present while resolved main policy stays @clawsweeper re-review |
|
🦞👀 Re-review progress:
|
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9ba54a2d-477b-4b8e-994c-5fb3755d8b01
|
Current head Current-head native UI proofIn an isolated profile representing the post-Add state under wildcard
The real-store theory covers both inherited Validation
@clawsweeper re-review |
|
🦞👀 Re-review progress:
|
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9ba54a2d-477b-4b8e-994c-5fb3755d8b01
|
Current head Final command-I/O proofRan the exact head in an isolated MCP-only profile with:
This proves both commands are rejected before command execution while inherited Deny remains authoritative. The native Permissions UI shows both rows as Validation
@clawsweeper re-review |
|
🦞👀 Re-review progress:
|
|
Validation count correction for the preceding proof comment: the exact full Tray result is 3,141 passed, 0 failed. All other reported results are unchanged. |
|
@clawsweeper re-review |
|
🦞👀 Re-review progress:
|
|
@clawsweeper re-review |
|
🦞👀 Re-review progress:
|
What Problem This Solves
The Permissions page could hide wildcard exec-approval rules and could activate previously dormant main or wildcard grants when a user added a rule under inherited
Deny/OfforDeny/OnMiss.User Impact
The page now:
this agent/all agentsscope labels;inactivewhile Deny remains effective;Allowlist/OnMissfallback as the runtime executor when no security value is stored.Why This Change Was Made
system.runresolvesagents["main"], thenagents["*"], then defaults, and merges both allowlists. The previous page projected only main rules and its Add transition could change main to Allowlist in a way that activated older merged entries.The repair preserves the existing storage schema and execution engine. It changes only the editor projection and mutation policy, with source-aware removal and fail-closed Add behavior.
Change Type
Scope
winnodeproofRequired proof pools
windows-winui-interactive: PASS on current head. The native Permissions page showedDefault action: Deny, scopedall agents/this agentrows, distinct accessible Remove names, andinactivestatus for both stored rules.windows-wsl-mxc: PASS on current head. Strict non-skipping Gateway-to-node MXC validation completed 17/17.Validation
Current head:
40cc5e61be4c945e63784a72639eebaa50bcad24./build.ps1: PASS.dotnet test ./tests/OpenClaw.Shared.Tests/OpenClaw.Shared.Tests.csproj --no-restore: 4,107 passed, 32 skipped, 0 failed.dotnet test ./tests/OpenClaw.Tray.Tests/OpenClaw.Tray.Tests.csproj --no-restore: 3,141 passed, 0 failed../scripts/validate-mxc-e2e.ps1 -NoBuildwithout-AllowSkip: 17/17 passed.Deny/OffandDeny/OnMiss, plus the runtimeAllowlist/OnMissfallback.Real behavior proof
Native UI
An isolated current-head profile represented the post-Add state under wildcard
security=Deny,ask=OnMisswith an older wildcard rule and a newly stored main rule.The native Permissions page showed:
Default action: Deny;**/other.exe (all agents)with statusinactive;**/git.exe (this agent)with statusinactive;The page was opened through local MCP
app.navigate, proving the built current-head app and actual WinUI projection.Final command I/O
A separate isolated MCP-only profile contained:
security=Deny,ask=OnMiss, older**/cmd.exerule;**/powershell.exerule.Two real
winnode system.runcalls attempted separate marker writes:exec-approvals-v2: SecurityDeny (security=deny), exit 1;exec-approvals-v2: SecurityDeny (security=deny), exit 1.Neither marker file was created. This proves both commands were rejected before command execution while inherited Deny remained authoritative.
Persisted authorization semantics
Deny/OfforDeny/OnMisswith any older dormant rule stores the new pattern but leaves main security/ask unset, so resolved policy remains Deny and every row is shown inactive.Deny/Alwaysretains the existing safe behavior: main becomes Allowlist/Always, so every match still requires a prompt.Allowlist/OnMissrather than incorrectly showing inactive Deny.Security Impact
Compatibility and Migration
exec-approvals.jsonfiles remain compatible.Review Conversations