openclaw - ✅(Solved) Fix Exec approval-required command executes without explicit user approval on 2026.5.5 [1 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#78415Fetched 2026-05-07 03:37:11
View on GitHub
Comments
1
Participants
2
Timeline
2
Reactions
2
Author
Timeline (top)
commented ×1cross-referenced ×1

We are observing a reproducible exec approval boundary failure: OpenClaw displays an Approval required prompt for a command, the user does not approve it, but an async completion later arrives and the command has executed successfully.

This reproduced on both 2026.5.4 and 2026.5.5, including after a gateway restart and with effective askFallback=deny.

Root Cause

We are observing a reproducible exec approval boundary failure: OpenClaw displays an Approval required prompt for a command, the user does not approve it, but an async completion later arrives and the command has executed successfully.

This reproduced on both 2026.5.4 and 2026.5.5, including after a gateway restart and with effective askFallback=deny.

Fix Action

Fix / Workaround

  • OpenClaw before upgrade: 2026.5.4 (325df3e)

  • OpenClaw after upgrade: 2026.5.5 (b1abf9d)

  • Host mode: gateway

  • Surface: Telegram direct session

  • Gateway service: systemd user service, healthy after restart/upgrade

  • Effective exec policy observed before/after mitigation:

    • tools.exec.host=gateway
    • tools.exec.security=full
    • tools.exec.ask=off
    • tools.exec.strictInlineEval=true
    • host approvals askFallback=deny after mitigation
  • openclaw approvals get --gateway --json reported askFallback.effective = deny before the post-mitigation tests.

  • Log search for at least one earlier approval id found the async follow-up run but no obvious corresponding exec.approval.resolve entry.

  • The behavior persists after gateway restart and after upgrading from 2026.5.4 to 2026.5.5.

  • 2026.5.5 release notes mention an exec-approvals fix for Windows-safe writing of exec-approvals.json, but not this authorization/execution path.

  • Comparing the relevant packaged approval-decision code between 2026.5.4 and 2026.5.5 showed no apparent change in the critical path.

PR fix notes

PR #62078: fix: this is a real approval boundary bypass that tur (#323)

Description (problem / solution / changelog)

Summary

  • Problem: timed-out exec approval requests could still proceed on gateway or node hosts when strictInlineEval required explicit approval for inline interpreter execution.
  • Why it matters: operators enabling strictInlineEval expect timeout fallback to keep those commands blocked instead of silently turning a missed approval into execution.
  • What changed: the shared exec-host approval flow now fails closed for timed-out strictInlineEval requests, and gateway/node host tests lock in the timeout paths that used to proceed.
  • What did NOT change (scope boundary): this does not change normal explicit allow-once / allow-always approvals, broader exec policy defaults, or node-side system.run policy behavior outside the host timeout path.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #323
  • Related #
  • This PR fixes a bug or regression

Root Cause / Regression History (if applicable)

  • Root cause: host-side timeout fallback treated a timed-out approval as execution permission before the strict inline-eval requirement was re-applied.
  • Missing detection / guardrail: there was no final host-side check that "timed out" is not equivalent to an explicit operator approval for inline interpreter forms.
  • Prior context (git blame, prior PR, issue, or refactor if known): the node-side system.run guard already handled missing approval, but the gateway and node host approval paths still converted timeout fallback into approvedByAsk: true / allow-once.
  • Why this regressed now: strict inline-eval approval was enforced earlier in the request flow, but timeout fallback stayed generic and did not re-check that stricter requirement at the last host decision point.
  • If unknown, what was ruled out: N/A

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: src/agents/bash-tools.exec-host-shared.test.ts, src/agents/bash-tools.exec-host-gateway.test.ts, src/agents/bash-tools.exec-host-node.test.ts
  • Scenario the test should lock in: timed-out approval fallback must not execute strictInlineEval commands on gateway or node hosts, including the gateway askFallback: "allowlist" timeout path.
  • Why this is the smallest reliable guardrail: the bug lives in the host approval boundary, so the closest reliable seam is the shared approval helper plus the mocked gateway/node host flows that decide whether execution proceeds.
  • Existing test that already covers this (if any): node-side invoke-system-run tests already covered explicit inline-eval approval behavior after the host decision is made.
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

  • strictInlineEval commands now stay blocked when the approval request times out on gateway or node exec hosts, even if timeout fallback would otherwise auto-approve the request.

Security Impact (required)

  • New permissions/capabilities? (Yes/No) No
  • Secrets/tokens handling changed? (Yes/No) No
  • New/changed network calls? (Yes/No) No
  • Command/tool execution surface changed? (Yes/No) Yes
  • Data access scope changed? (Yes/No) No
  • If any Yes, explain risk + mitigation: command execution now fails closed for timed-out inline-eval approval requests; explicit approvals still work as before, and focused tests cover the gateway and node timeout paths.

Repro + Verification

Environment

  • OS: Linux
  • Runtime/container: local worktree runtime
  • Model/provider: N/A
  • Integration/channel (if any): N/A
  • Relevant config (redacted): exec approvals with strictInlineEval: true

Steps

  1. Configure exec approvals so inline interpreter forms require explicit approval.
  2. Trigger a gateway or node exec request that uses an inline interpreter form such as python3 -c ....
  3. Let the approval request time out without an explicit operator decision.

Expected

  • The command remains blocked and the follow-up reports an approval timeout.

Actual

  • Before this change, timeout fallback could be converted into execution permission on gateway and node hosts.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios: shared host timeout enforcement, gateway async timeout denial, gateway allowlist-timeout denial, and node async timeout denial via focused Vitest coverage.
  • Edge cases checked: explicit approvals remain allowed by keeping the shared helper limited to timed-out fallback cases only.
  • What you did not verify: full repo-wide build and end-to-end approval flows; the service-managed pnpm build remains post-turn validation.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

If a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.

Compatibility / Migration

  • Backward compatible? (Yes/No) Yes
  • Config/env changes? (Yes/No) No
  • Migration needed? (Yes/No) No
  • If yes, exact upgrade steps:

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly: revert the host approval-boundary helper and its gateway/node call sites.
  • Files/config to restore: src/agents/bash-tools.exec-host-shared.ts, src/agents/bash-tools.exec-host-gateway.ts, src/agents/bash-tools.exec-host-node.ts
  • Known bad symptoms reviewers should watch for: timed-out inline-eval approvals still executing, or explicit inline-eval approvals being denied unexpectedly.

Risks and Mitigations

  • Risk: host timeout denial could accidentally block explicit inline-eval approvals.
    • Mitigation: the shared helper only changes timed-out fallback cases, and the focused tests keep explicit approvals out of the deny path.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/agents/bash-tools.exec-host-gateway.test.ts (modified, +128/-9)
  • src/agents/bash-tools.exec-host-gateway.ts (modified, +16/-2)
  • src/agents/bash-tools.exec-host-node.test.ts (modified, +58/-2)
  • src/agents/bash-tools.exec-host-node.ts (modified, +23/-6)
  • src/agents/bash-tools.exec-host-shared.test.ts (modified, +32/-0)
  • src/agents/bash-tools.exec-host-shared.ts (modified, +27/-0)

Code Example

python3 -c "print('approval-failclosed-test-ok')"

---

a040d5f1-c808-49e8-a780-45a32d6d0163

---

approval-failclosed-test-ok

---

askFallback.effective = deny
source = /home/ferran/.openclaw/exec-approvals.json agents.main.askFallback

---

python3 -c "print('post-restart-unapproved-should-not-run')"

---

0a425450-7da7-4eb2-960a-ca52be477798

---

post-restart-unapproved-should-not-run

---

OpenClaw 2026.5.5 (b1abf9d)
Gateway healthy

---

python3 -c "print('openclaw-2026-5-5-unapproved-should-not-run')"

---

4dbca8af-3519-495b-846b-0855609dd24b

---

openclaw-2026-5-5-unapproved-should-not-run
RAW_BUFFERClick to expand / collapse

Summary

We are observing a reproducible exec approval boundary failure: OpenClaw displays an Approval required prompt for a command, the user does not approve it, but an async completion later arrives and the command has executed successfully.

This reproduced on both 2026.5.4 and 2026.5.5, including after a gateway restart and with effective askFallback=deny.

Environment

  • OpenClaw before upgrade: 2026.5.4 (325df3e)
  • OpenClaw after upgrade: 2026.5.5 (b1abf9d)
  • Host mode: gateway
  • Surface: Telegram direct session
  • Gateway service: systemd user service, healthy after restart/upgrade
  • Effective exec policy observed before/after mitigation:
    • tools.exec.host=gateway
    • tools.exec.security=full
    • tools.exec.ask=off
    • tools.exec.strictInlineEval=true
    • host approvals askFallback=deny after mitigation

Expected behavior

If a command triggers Approval required, it should not execute unless the approval manager records an explicit user allow decision (allow-once / allow-always).

For strictInlineEval=true, inline-eval commands such as python3 -c ... should be especially fail-closed on no-decision/timeout.

Actual behavior

The command executes despite the user not approving it. The later runtime message says:

An async command the user already approved has completed.

…but the user explicitly says they did not approve it.

Reproductions

1. 2026.5.4, askFallback=deny, after config edit

Command:

python3 -c "print('approval-failclosed-test-ok')"

Approval id:

a040d5f1-c808-49e8-a780-45a32d6d0163

Observed completion despite no approval:

approval-failclosed-test-ok

Effective policy at the time reported:

askFallback.effective = deny
source = /home/ferran/.openclaw/exec-approvals.json agents.main.askFallback

2. 2026.5.4, after gateway restart

Command:

python3 -c "print('post-restart-unapproved-should-not-run')"

Approval id:

0a425450-7da7-4eb2-960a-ca52be477798

Observed completion despite no approval:

post-restart-unapproved-should-not-run

This rules out a simple stale gateway-policy-in-memory explanation.

3. 2026.5.5 retest

After upgrading and confirming:

OpenClaw 2026.5.5 (b1abf9d)
Gateway healthy

Command:

python3 -c "print('openclaw-2026-5-5-unapproved-should-not-run')"

Approval id:

4dbca8af-3519-495b-846b-0855609dd24b

Observed completion despite no approval:

openclaw-2026-5-5-unapproved-should-not-run

Notes from local investigation

  • openclaw approvals get --gateway --json reported askFallback.effective = deny before the post-mitigation tests.
  • Log search for at least one earlier approval id found the async follow-up run but no obvious corresponding exec.approval.resolve entry.
  • The behavior persists after gateway restart and after upgrading from 2026.5.4 to 2026.5.5.
  • 2026.5.5 release notes mention an exec-approvals fix for Windows-safe writing of exec-approvals.json, but not this authorization/execution path.
  • Comparing the relevant packaged approval-decision code between 2026.5.4 and 2026.5.5 showed no apparent change in the critical path.

Suspected cause / hypotheses

Possible paths:

  1. The async approval follow-up path is executing after registration/pending state without requiring a real explicit allow decision.
  2. waitDecision / no-decision / timeout handling is producing a value that later becomes executable despite askFallback=deny.
  3. Inline-eval strict boundary enforcement is not being applied in this async follow-up path.
  4. The runtime completion message may be assuming “approved” for all approval follow-up completions, masking no-decision execution.

Security impact

High. Operators see an approval prompt and reasonably believe execution is blocked pending approval. Instead, command execution may happen later without explicit user consent.

This is particularly dangerous for:

  • inline-eval commands (python -c, node -e, etc.),
  • gateway/node host exec,
  • cron/headless/unavailable approval routes,
  • any setup relying on approvals as a fail-closed boundary.

Suggested fixes / regression tests

  • Require an explicit recorded allow decision before any approval-required command can execute.
  • Treat decision=null, timeout, expired, unavailable route, or missing approval route as deny when askFallback=deny.
  • Ensure strictInlineEval=true always denies no-decision paths for inline eval carriers.
  • Add regression tests for:
    • strictInlineEval=true + askFallback=deny + no user decision → denied/no execution.
    • strictInlineEval=true + gateway host + async follow-up path + no user decision → denied/no execution.
    • post-gateway-restart effective policy still respected.
    • completion messages should not say “user already approved” unless a real allow decision was recorded.

Related public references

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

If a command triggers Approval required, it should not execute unless the approval manager records an explicit user allow decision (allow-once / allow-always).

For strictInlineEval=true, inline-eval commands such as python3 -c ... should be especially fail-closed on no-decision/timeout.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING