Compare commits

...

1 Commits

Author SHA1 Message Date
Vincent Koc
d93091dad7 Exec: restore approval-first host defaults 2026-04-25 11:28:35 -07:00
4 changed files with 14 additions and 12 deletions

View File

@@ -596,14 +596,16 @@ export function createExecTool(
const approvalDefaults = loadExecApprovals().defaults;
const configuredSecurity =
defaults?.security ?? approvalDefaults?.security ?? (host === "sandbox" ? "deny" : "full");
defaults?.security ??
approvalDefaults?.security ??
(host === "sandbox" ? "deny" : "allowlist");
const requestedSecurity = normalizeExecSecurity(params.security);
let security = minSecurity(configuredSecurity, requestedSecurity ?? configuredSecurity);
if (elevatedRequested && elevatedMode === "full") {
security = "full";
}
// Keep local exec defaults in sync with exec-approvals.json when tools.exec.* is unset.
const configuredAsk = defaults?.ask ?? approvalDefaults?.ask ?? "off";
const configuredAsk = defaults?.ask ?? approvalDefaults?.ask ?? "on-miss";
const requestedAsk = normalizeExecAsk(params.ask);
let ask = maxAsk(configuredAsk, requestedAsk ?? configuredAsk);
const bypassApprovals = elevatedRequested && elevatedMode === "full";

View File

@@ -432,12 +432,12 @@ describe("normalizeExecApprovals strips invalid security/ask enum values (#59006
},
} as unknown as ExecApprovalsFile;
const resolved = resolveExecApprovalsFromFile({ file });
// Invalid "none" in defaults is stripped, so fallback to DEFAULT_SECURITY ("full")
expect(resolved.defaults.security).toBe("full");
// Invalid "never" in defaults is stripped, so fallback to DEFAULT_ASK ("off")
expect(resolved.defaults.ask).toBe("off");
// Invalid "none" in defaults is stripped, so fallback to DEFAULT_SECURITY ("allowlist")
expect(resolved.defaults.security).toBe("allowlist");
// Invalid "never" in defaults is stripped, so fallback to DEFAULT_ASK ("on-miss")
expect(resolved.defaults.ask).toBe("on-miss");
// Wildcard agent "none" is stripped, so agent inherits resolved defaults
expect(resolved.agent.security).toBe("full");
expect(resolved.agent.security).toBe("allowlist");
// Wildcard agent ask="off" is valid and preserved
expect(resolved.agent.ask).toBe("off");
});

View File

@@ -463,8 +463,8 @@ describe("exec approvals policy helpers", () => {
});
expect(summary.askFallback).toEqual({
effective: "full",
source: "OpenClaw default (full)",
effective: "deny",
source: "OpenClaw default (deny)",
});
});

View File

@@ -168,9 +168,9 @@ export type ExecApprovalsResolved = {
// Keep CLI + gateway defaults in sync.
export const DEFAULT_EXEC_APPROVAL_TIMEOUT_MS = 1_800_000;
const DEFAULT_SECURITY: ExecSecurity = "full";
const DEFAULT_ASK: ExecAsk = "off";
export const DEFAULT_EXEC_APPROVAL_ASK_FALLBACK: ExecSecurity = "full";
const DEFAULT_SECURITY: ExecSecurity = "allowlist";
const DEFAULT_ASK: ExecAsk = "on-miss";
export const DEFAULT_EXEC_APPROVAL_ASK_FALLBACK: ExecSecurity = "deny";
const DEFAULT_AUTO_ALLOW_SKILLS = false;
const DEFAULT_SOCKET = "~/.openclaw/exec-approvals.sock";
const DEFAULT_FILE = "~/.openclaw/exec-approvals.json";