From ccad66768ba713f586c74d1d1b6d9abbd4b0098a Mon Sep 17 00:00:00 2001 From: uninhibite-scholar Date: Thu, 12 Mar 2026 10:35:18 +0800 Subject: [PATCH 1/3] fix: respect tools.exec.ask=off in webchat/control-ui Previously, tools.exec.ask=off was only respected if exec-approvals.json had ask=off, but the user's openclaw.json setting was ignored. This fix ensures that tools.exec.ask=off takes precedence and disables prompts in webchat/control-ui as expected. Fixes #42574 --- src/agents/bash-tools.exec-host-shared.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/agents/bash-tools.exec-host-shared.ts b/src/agents/bash-tools.exec-host-shared.ts index c24e0a2f1fa..26a9f6b1de8 100644 --- a/src/agents/bash-tools.exec-host-shared.ts +++ b/src/agents/bash-tools.exec-host-shared.ts @@ -133,9 +133,15 @@ export function resolveExecHostApprovalContext(params: { ask: params.ask, }); const hostSecurity = minSecurity(params.security, approvals.agent.security); - // An explicit ask=off policy in exec-approvals.json must be able to suppress - // prompts even when tool/runtime defaults are stricter (for example on-miss). - const hostAsk = approvals.agent.ask === "off" ? "off" : maxAsk(params.ask, approvals.agent.ask); + // An explicit ask=off policy (either from exec-approvals.json or tools.exec.ask) + // must be able to suppress prompts even when other defaults are stricter. + // tools.exec.ask=off takes precedence to allow users to disable prompts entirely. + const hostAsk = + params.ask === "off" + ? "off" + : approvals.agent.ask === "off" + ? "off" + : maxAsk(params.ask, approvals.agent.ask); const askFallback = approvals.agent.askFallback; if (hostSecurity === "deny") { throw new Error(`exec denied: host=${params.host} security=deny`); From 188c5e37e146eb1b112663318c603b5b6226d010 Mon Sep 17 00:00:00 2001 From: uninhibite-scholar Date: Thu, 12 Mar 2026 16:16:28 +0800 Subject: [PATCH 2/3] refactor: simplify nested ternary per Greptile review Co-authored-by: Greptile --- src/agents/bash-tools.exec-host-shared.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/agents/bash-tools.exec-host-shared.ts b/src/agents/bash-tools.exec-host-shared.ts index 26a9f6b1de8..b74d5f9312a 100644 --- a/src/agents/bash-tools.exec-host-shared.ts +++ b/src/agents/bash-tools.exec-host-shared.ts @@ -137,11 +137,9 @@ export function resolveExecHostApprovalContext(params: { // must be able to suppress prompts even when other defaults are stricter. // tools.exec.ask=off takes precedence to allow users to disable prompts entirely. const hostAsk = - params.ask === "off" + params.ask === "off" || approvals.agent.ask === "off" ? "off" - : approvals.agent.ask === "off" - ? "off" - : maxAsk(params.ask, approvals.agent.ask); + : maxAsk(params.ask, approvals.agent.ask); const askFallback = approvals.agent.askFallback; if (hostSecurity === "deny") { throw new Error(`exec denied: host=${params.host} security=deny`); From e3f61edcf9e9ea5688b579756988665ecfdb41d0 Mon Sep 17 00:00:00 2001 From: uninhibite-scholar Date: Tue, 17 Mar 2026 09:07:26 +0800 Subject: [PATCH 3/3] docs: add design decision comment for tools.exec.ask=off precedence Explicitly documents the security trade-off: user-level tools.exec.ask=off takes precedence over exec-approvals.json policies. This is intentional to allow users to disable prompts in trusted environments. Addresses Greptile review on PR #43600. --- src/agents/bash-tools.exec-host-shared.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/agents/bash-tools.exec-host-shared.ts b/src/agents/bash-tools.exec-host-shared.ts index b74d5f9312a..30625f10000 100644 --- a/src/agents/bash-tools.exec-host-shared.ts +++ b/src/agents/bash-tools.exec-host-shared.ts @@ -133,9 +133,11 @@ export function resolveExecHostApprovalContext(params: { ask: params.ask, }); const hostSecurity = minSecurity(params.security, approvals.agent.security); - // An explicit ask=off policy (either from exec-approvals.json or tools.exec.ask) - // must be able to suppress prompts even when other defaults are stricter. - // tools.exec.ask=off takes precedence to allow users to disable prompts entirely. + // DESIGN DECISION: User-level tools.exec.ask=off takes precedence over exec-approvals.json policies. + // This allows users to disable exec prompts entirely in trusted environments (e.g., webchat/control-ui). + // SECURITY TRADE-OFF: A user setting tools.exec.ask=off in openclaw.json can bypass an admin-configured + // ask: "always" policy in exec-approvals.json. This is intentional: user opt-out wins over admin defaults. + // Admins requiring mandatory approvals should enforce this at the deployment level, not via exec-approvals.json. const hostAsk = params.ask === "off" || approvals.agent.ask === "off" ? "off"