Merge e3f61edcf9e9ea5688b579756988665ecfdb41d0 into 598f1826d8b2bc969aace2c6459824737667218c

This commit is contained in:
uninhibite-scholar 2026-03-20 21:26:10 -07:00 committed by GitHub
commit aaab3f284f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -180,9 +180,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);
// 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"
: maxAsk(params.ask, approvals.agent.ask);
const askFallback = approvals.agent.askFallback;
if (hostSecurity === "deny") {
throw new Error(`exec denied: host=${params.host} security=deny`);