Skip to content

Commit 3baf42a

Browse files
committed
Node host: document Windows shell wrapper approvals
1 parent d6edcca commit 3baf42a

5 files changed

Lines changed: 8 additions & 7 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ Docs: https://docs.openclaw.ai
187187

188188
### Fixes
189189

190+
- Node host/exec: require approval for Windows PowerShell and pwsh shell-wrapper runs in allowlist mode, matching the existing cmd.exe wrapper behavior. (#67655) Thanks @plgonzalezrx8.
190191
- Cron/agents: recognize same-target `edit`↔`write` recovery in `isSameToolMutationAction`, so a successful `write` to a path clears an earlier failed `edit` on the same path. Stops cron from reporting fatal failures when an agent self-heals across `edit` and `write`, while preserving same-tool fingerprint matching, blocking different-target writes, and excluding tools (including `apply_patch`) whose real call args do not produce a stable `path` fingerprint segment. Fixes #79024. Thanks @RenzoMXD.
191192
- Gateway/Tailscale: add opt-in `gateway.tailscale.preserveFunnel` so when `tailscale.mode = "serve"` and an externally configured Tailscale Funnel route already covers the gateway port, OpenClaw skips re-applying `tailscale serve` on startup and skips the `resetOnExit` teardown for that run, keeping operator-managed Funnel exposure alive across gateway restarts. Fixes #57241. Thanks @RenzoMXD.
192193
- Agents/compaction: keep the recent tail after manual `/compact` when Pi returns an empty or no-op compaction summary, preventing blank checkpoints from replacing the live context.

docs/nodes/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ Notes:
374374
- `system.run` supports `--cwd`, `--env KEY=VAL`, `--command-timeout`, and `--needs-screen-recording`.
375375
- For shell wrappers (`bash|sh|zsh ... -c/-lc`), request-scoped `--env` values are reduced to an explicit allowlist (`TERM`, `LANG`, `LC_*`, `COLORTERM`, `NO_COLOR`, `FORCE_COLOR`).
376376
- For allow-always decisions in allowlist mode, known dispatch wrappers (`env`, `nice`, `nohup`, `stdbuf`, `timeout`) persist inner executable paths instead of wrapper paths. If unwrapping is not safe, no allowlist entry is persisted automatically.
377-
- On Windows node hosts in allowlist mode, shell-wrapper runs via `cmd.exe /c` require approval (allowlist entry alone does not auto-allow the wrapper form).
377+
- On Windows node hosts in allowlist mode, shell-wrapper runs via `cmd.exe /c` or `powershell`/`pwsh -Command` require approval (allowlist entry alone does not auto-allow the wrapper form).
378378
- `system.notify` supports `--priority <passive|active|timeSensitive>` and `--delivery <system|overlay|auto>`.
379379
- Node hosts ignore `PATH` overrides and strip dangerous startup/shell keys (`DYLD_*`, `LD_*`, `NODE_OPTIONS`, `PYTHON*`, `PERL*`, `RUBYOPT`, `SHELLOPTS`, `PS4`). If you need extra PATH entries, configure the node host service environment (or install tools in standard locations) instead of passing `PATH` via `--env`.
380380
- On macOS node mode, `system.run` is gated by exec approvals in the macOS app (Settings → Exec approvals).

docs/nodes/troubleshooting.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ run as an approval mismatch instead of trusting the edited payload.
9393
- `LOCATION_BACKGROUND_UNAVAILABLE` → app is backgrounded but only While Using permission exists.
9494
- `SYSTEM_RUN_DENIED: approval required` → exec request needs explicit approval.
9595
- `SYSTEM_RUN_DENIED: allowlist miss` → command blocked by allowlist mode.
96-
On Windows node hosts, shell-wrapper forms like `cmd.exe /c ...` are treated as allowlist misses in
97-
allowlist mode unless approved via ask flow.
96+
On Windows node hosts, shell-wrapper forms like `cmd.exe /c ...` or `powershell`/`pwsh -Command ...`
97+
are treated as allowlist misses in allowlist mode unless approved via ask flow.
9898

9999
## Fast recovery loop
100100

src/node-host/exec-policy.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,13 @@ describe("formatSystemRunAllowlistMissMessage", () => {
6464
).toContain("shell wrappers like sh/bash/zsh -c require approval");
6565
});
6666

67-
it("adds Windows shell-wrapper guidance when blocked by cmd.exe policy", () => {
67+
it("adds Windows shell-wrapper guidance when blocked by Windows wrapper policy", () => {
6868
expect(
6969
formatSystemRunAllowlistMissMessage({
7070
shellWrapperBlocked: true,
7171
windowsShellWrapperBlocked: true,
7272
}),
73-
).toContain("Windows shell wrappers like cmd.exe /c require approval");
73+
).toContain("Windows shell wrappers like cmd.exe /c or powershell/pwsh -Command");
7474
});
7575
});
7676

@@ -155,7 +155,7 @@ describe("evaluateSystemRunPolicy", () => {
155155
);
156156
expect(denied.shellWrapperBlocked).toBe(true);
157157
expect(denied.windowsShellWrapperBlocked).toBe(true);
158-
expect(denied.errorMessage).toContain("powershell -Command");
158+
expect(denied.errorMessage).toContain("powershell/pwsh -Command");
159159
});
160160

161161
it("does not block Windows cmd.exe invocations without inline shell-wrapper transport", () => {

src/node-host/exec-policy.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export function formatSystemRunAllowlistMissMessage(params?: {
3535
if (params?.windowsShellWrapperBlocked) {
3636
return (
3737
"SYSTEM_RUN_DENIED: allowlist miss " +
38-
"(Windows shell wrappers like cmd.exe /c or powershell -Command require approval; " +
38+
"(Windows shell wrappers like cmd.exe /c or powershell/pwsh -Command require approval; " +
3939
"approve once/always or run with --ask on-miss|always)"
4040
);
4141
}

0 commit comments

Comments
 (0)