fix(agents): preserve spawned tools with alsoAllow (#114530)

This commit is contained in:
josemanuel-jaen-sqaas
2026-07-28 02:47:32 +02:00
committed by GitHub
parent 10966ed344
commit 5c50d2ff70
3 changed files with 37 additions and 10 deletions
@@ -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" } },
+14
View File
@@ -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", () => {
+11 -10
View File
@@ -55,16 +55,17 @@ const SHIPPED_PLUGIN_POLICY_FAMILY_CORE_TOOLS = new Map<string, readonly string[
/** Returns true when an allow policy is narrower than all/default plugin tools. */
export function hasRestrictiveAllowPolicy(policy?: { allow?: string[] }): boolean {
return (
Array.isArray(policy?.allow) &&
policy.allow.some((entry) => {
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,
);
}