diff --git a/src/agents/agent-tools.create-openclaw-coding-tools.test.ts b/src/agents/agent-tools.create-openclaw-coding-tools.test.ts index b028566adda1..66fdbd0dacd7 100644 --- a/src/agents/agent-tools.create-openclaw-coding-tools.test.ts +++ b/src/agents/agent-tools.create-openclaw-coding-tools.test.ts @@ -552,6 +552,18 @@ describe("createOpenClawCodingTools", () => { expect(inheritedToolAllowlistRef).not.toContain("exec"); }); + it("does not snapshot additive alsoAllow policies for spawn inheritance", () => { + const inheritedToolAllowlistRef: string[] = []; + + createOpenClawCodingTools({ + config: { tools: { alsoAllow: ["read"], deny: ["exec"] } }, + inheritedToolAllowlistRef, + }); + + expect(inheritedToolAllowlistRef).toEqual([]); + expect(latestCreateOpenClawToolsOptions().inheritedToolDenylist).toContain("exec"); + }); + it("preserves runtime-allowed message through restrictive profiles", () => { const tools = createOpenClawCodingTools({ config: { tools: { profile: "minimal" } }, diff --git a/src/agents/tool-policy.test.ts b/src/agents/tool-policy.test.ts index 71fa385bdbf4..de57d48de087 100644 --- a/src/agents/tool-policy.test.ts +++ b/src/agents/tool-policy.test.ts @@ -12,6 +12,7 @@ import { collectExplicitAllowlist, DEFAULT_PLUGIN_TOOLS_ALLOWLIST_ENTRY, expandToolGroups, + hasRestrictiveAllowPolicy, normalizeToolName, resolveToolProfilePolicy, TOOL_GROUPS, @@ -79,6 +80,19 @@ describe("tool-policy", () => { "*", ]); }); + + it("does not treat additive allow-all policies as restrictive", () => { + expect(hasRestrictiveAllowPolicy(pickSandboxToolPolicy({ alsoAllow: ["optional-demo"] }))).toBe( + false, + ); + expect( + hasRestrictiveAllowPolicy(pickSandboxToolPolicy({ allow: [], alsoAllow: ["optional-demo"] })), + ).toBe(false); + }); + + it("still treats explicit bounded allowlists as restrictive", () => { + expect(hasRestrictiveAllowPolicy(pickSandboxToolPolicy({ allow: ["read"] }))).toBe(true); + }); }); describe("sandbox tool policy", () => { diff --git a/src/agents/tool-policy.ts b/src/agents/tool-policy.ts index f5fc03dfe672..65573684b8d5 100644 --- a/src/agents/tool-policy.ts +++ b/src/agents/tool-policy.ts @@ -55,16 +55,17 @@ const SHIPPED_PLUGIN_POLICY_FAMILY_CORE_TOOLS = new Map { - const normalized = normalizeToolName(entry); - return ( - Boolean(normalized) && - normalized !== "*" && - normalized !== DEFAULT_PLUGIN_TOOLS_ALLOWLIST_ENTRY - ); - }) + if (!Array.isArray(policy?.allow)) { + return false; + } + const normalizedAllow = policy.allow.map((entry) => normalizeToolName(entry)); + // A wildcard remains allow-all when additive entries are present. Treating + // those extras as restrictive would unnecessarily cap delegated sessions. + if (normalizedAllow.includes("*")) { + return false; + } + return normalizedAllow.some( + (entry) => Boolean(entry) && entry !== DEFAULT_PLUGIN_TOOLS_ALLOWLIST_ENTRY, ); }