Skip to content

fix(agents): restore exec host=node routing and per-call override from auto#60788

Merged
obviyus merged 2 commits into
openclaw:mainfrom
openperf:fix/issue-60772-exec-node-routing
Apr 4, 2026
Merged

fix(agents): restore exec host=node routing and per-call override from auto#60788
obviyus merged 2 commits into
openclaw:mainfrom
openperf:fix/issue-60772-exec-node-routing

Conversation

@openperf

@openperf openperf commented Apr 4, 2026

Copy link
Copy Markdown
Member

Summary

  • Problem: Since 2026.4.2, exec host=node no longer routes commands to paired nodes — every command executes on the gateway instead. All four configuration paths are broken: global tools.exec.host: "node" silently runs on gateway; tools.exec.host: "auto" with per-call host=node throws "exec host not allowed"; subagent host=node also throws; and disabling elevated does not help. This leaves zero remaining paths to execute commands on paired nodes from agents ([Bug]: exec host=node regression in 2026.4.2 — agent exec always routes to gateway #60772, same root cause as stale [Bug]: Agent exec ignores node binding — always routes to gateway despite correct config #20669).

  • Root Cause: Two regressions in resolveExecTarget() and isRequestedExecTargetAllowed() in src/agents/bash-tools.exec-runtime.ts:

    1. Elevated override (line 238–245): elevatedRequested unconditionally returns effectiveHost: "gateway", ignoring configuredTarget: "node". When a channel has elevated defaults enabled (defaultLevel: "on"), the elevated mode resolves to "ask"elevatedRequested = true → gateway forced, even though the user explicitly configured host=node.
    2. Strict equality gate (line 224–228): isRequestedExecTargetAllowed uses requestedTarget === configuredTarget. When configuredTarget is "auto", any per-call override to a concrete host (node, gateway, sandbox) is rejected. The comment says "auto is a routing strategy, not a wildcard allowlist", but this contradicts the documented behavior where auto should allow runtime host selection.
  • Fix:

    1. Elevated: When configuredTarget === "node", preserve effectiveHost: "node" instead of forcing gateway. The node's own approval/security layer handles elevated semantics on the remote host. All other configured targets (auto, sandbox, gateway) still redirect elevated to gateway as before.
    2. Auto override: Allow isRequestedExecTargetAllowed to return true when configuredTarget === "auto", enabling per-call overrides to any concrete host. Non-auto concrete targets still require exact match to prevent silent host-hopping.
  • What changed:

    • src/agents/bash-tools.exec-runtime.ts: Fixed isRequestedExecTargetAllowed to allow per-call overrides under auto; fixed resolveExecTarget elevated path to honour node binding.
    • src/agents/bash-tools.exec-runtime.test.ts: Updated 2 existing tests and added 5 new tests covering auto→node override, auto→gateway override, auto→sandbox override, cross-host rejection for concrete targets, elevated+node routing, and elevated+node without per-call override.
  • What did NOT change (scope boundary): Node transport layer (bash-tools.exec-host-node.ts), approval policy resolution (exec-approvals.ts), sandbox isolation checks in bash-tools.exec.ts, and the elevated gate logic in createExecTool.execute are all untouched. The fix is strictly limited to target selection in resolveExecTarget.

Reproduction

  1. Pair a Windows node (connected, system.run capability advertised).
  2. Set tools.exec.host: "node" and tools.exec.node: "<node-id>" in config.
  3. Run exec hostname from an agent session.
  4. Before fix: Returns gateway hostname (Linux). After fix: Returns node hostname (Windows).
  5. Alternatively, set tools.exec.host: "auto" and run exec host=node: hostname.
  6. Before fix: Throws "exec host not allowed". After fix: Routes to node correctly.

Risk / Mitigation

  • Risk: Allowing per-call overrides under auto could let a sandboxed session escape to gateway/node.
  • Mitigation: Sandbox isolation is enforced independently in bash-tools.exec.ts (line 1338: target.selectedTarget === "sandbox" && !sandbox check) and by the approval layer (line 1322: host === "sandbox" ? "deny" : "full"). The new tests explicitly verify that cross-host overrides between concrete targets (e.g. nodegateway) are still rejected. The elevated fix only applies to configuredTarget === "node", which is an explicit admin choice — no implicit escalation path is opened.

Change Type (select all)

  • Bug fix

Scope (select all touched areas)

  • Gateway
  • Agent Tools
  • Exec Runtime

Linked Issue/PR

Fixes #60772

@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: S labels Apr 4, 2026
@greptile-apps

greptile-apps Bot commented Apr 4, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Restores two broken routing paths in resolveExecTarget: per-call host= overrides under configuredTarget=auto (previously thrown as "exec host not allowed"), and configuredTarget=node with elevated execution (previously silently redirected to gateway). Both fixes are narrowly scoped to target selection in bash-tools.exec-runtime.ts with good test coverage for the new paths.

Confidence Score: 5/5

Safe to merge; all findings are P2 style/documentation suggestions that do not affect runtime correctness.

Both logic fixes are correct and well-tested. The only open items are a missing test for the elevated+node+mismatched-requestedTarget silent-discard path (P2) and an inaccuracy in the PR's cited sandbox-escape mitigations — the real guard is the approval/ask flow, not lines 1338/1322 (P2 documentation concern, no code change needed).

No files require special attention.

Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/agents/bash-tools.exec-runtime.ts
Line: 249-261

Comment:
**Elevated path ignores per-call `requestedTarget` override silently**

When `elevatedRequested=true` the function returns immediately based solely on `configuredTarget`, completely discarding `requestedTarget`. That means a caller passing `{ configuredTarget: "node", requestedTarget: "gateway", elevatedRequested: true }` gets back `effectiveHost: "node"` with no error and no log entry — the gateway request is silently dropped.

The test suite only exercises `requestedTarget: "node"` under the elevated+node path. Adding a case for a mismatched `requestedTarget` (e.g. `node`/`gateway`) would make the silent-discard behaviour explicit and prevent confusion if the elevated override logic is revisited later.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/agents/bash-tools.exec-runtime.ts
Line: 228-234

Comment:
**PR's cited sandbox-isolation mitigations don't fully apply to the `auto`→gateway override path**

The PR description cites two protections against sandbox escape via a per-call `host=gateway` override from an `auto` session:

- `bash-tools.exec.ts` line 1338 (`target.selectedTarget === "sandbox" && !sandbox`): this only fires when *sandbox is requested but unavailable*; it never fires when `selectedTarget === "gateway"`, so it does not prevent the escape.
- `bash-tools.exec.ts` line 1322 (`host === "sandbox" ? "deny" : "full"`): when the resolved host is `"gateway"`, the default `security` is `"full"`*less* restrictive than the sandbox `"deny"` default, meaning the command allow-list gets wider, not narrower.

The actual safety net for this path is the `ask`/approval flow, which is unchanged. This is a documentation/rationale accuracy issue, not a code bug — the behaviour change itself is intentional and the approval layer does still apply. Future security reviewers relying on the cited lines as the isolation guarantee will be misled.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "fix(agents): resolve exec host=node rout..." | Re-trigger Greptile

Comment thread src/agents/bash-tools.exec-runtime.ts
Comment thread src/agents/bash-tools.exec-runtime.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6fd0b63f22

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/agents/bash-tools.exec-runtime.ts
@openperf
openperf force-pushed the fix/issue-60772-exec-node-routing branch from 6fd0b63 to 32afe6d Compare April 4, 2026 10:04

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 32afe6ddc0

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/agents/bash-tools.exec-runtime.ts

@obviyus obviyus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed latest changes; landing now.

@obviyus
obviyus force-pushed the fix/issue-60772-exec-node-routing branch from 7b480da to f2815d0 Compare April 4, 2026 16:29
@obviyus
obviyus merged commit 7750902 into openclaw:main Apr 4, 2026
7 checks passed
@obviyus

obviyus commented Apr 4, 2026

Copy link
Copy Markdown
Contributor

Landed on main.

Thanks @openperf.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: exec host=node regression in 2026.4.2 — agent exec always routes to gateway

2 participants