diff --git a/src/commands/doctor-security.test.ts b/src/commands/doctor-security.test.ts index 085b5fdf170..8418761f0eb 100644 --- a/src/commands/doctor-security.test.ts +++ b/src/commands/doctor-security.test.ts @@ -66,6 +66,49 @@ describe("noteSecurityWarnings gateway exposure", () => { await run(); } + async function expectAgentExecHostPolicyWarning(agentKey: "*" | "runner") { + await withExecApprovalsFile( + { + version: 1, + defaults: + agentKey === "*" + ? { + security: "full", + ask: "off", + } + : undefined, + agents: { + [agentKey]: { + security: "allowlist", + ask: "always", + }, + }, + }, + async () => { + await noteSecurityWarnings({ + agents: { + list: [ + { + id: "runner", + tools: { + exec: { + security: "full", + ask: "off", + }, + }, + }, + ], + }, + } as OpenClawConfig); + }, + ); + + const message = lastMessage(); + expect(message).toContain("agents.list.runner.tools.exec is broader than the host exec policy"); + expect(message).toContain(`agents.${agentKey}.security="allowlist"`); + expect(message).toContain(`agents.${agentKey}.ask="always"`); + } + it("warns when exposed without auth", async () => { const cfg = { gateway: { bind: "lan" } } as OpenClawConfig; await noteSecurityWarnings(cfg); @@ -197,43 +240,7 @@ describe("noteSecurityWarnings gateway exposure", () => { }); it("attributes broader host policy warnings to wildcard agent entries", async () => { - await withExecApprovalsFile( - { - version: 1, - defaults: { - security: "full", - ask: "off", - }, - agents: { - "*": { - security: "allowlist", - ask: "always", - }, - }, - }, - async () => { - await noteSecurityWarnings({ - agents: { - list: [ - { - id: "runner", - tools: { - exec: { - security: "full", - ask: "off", - }, - }, - }, - ], - }, - } as OpenClawConfig); - }, - ); - - const message = lastMessage(); - expect(message).toContain("agents.list.runner.tools.exec is broader than the host exec policy"); - expect(message).toContain('agents.*.security="allowlist"'); - expect(message).toContain('agents.*.ask="always"'); + await expectAgentExecHostPolicyWarning("*"); }); it("does not invent a deny host policy when exec-approvals defaults.security is unset", async () => { @@ -282,39 +289,7 @@ describe("noteSecurityWarnings gateway exposure", () => { }); it("warns when a per-agent exec policy is broader than the matching host agent policy", async () => { - await withExecApprovalsFile( - { - version: 1, - agents: { - runner: { - security: "allowlist", - ask: "always", - }, - }, - }, - async () => { - await noteSecurityWarnings({ - agents: { - list: [ - { - id: "runner", - tools: { - exec: { - security: "full", - ask: "off", - }, - }, - }, - ], - }, - } as OpenClawConfig); - }, - ); - - const message = lastMessage(); - expect(message).toContain("agents.list.runner.tools.exec is broader than the host exec policy"); - expect(message).toContain('agents.runner.security="allowlist"'); - expect(message).toContain('agents.runner.ask="always"'); + await expectAgentExecHostPolicyWarning("runner"); }); it("warns when an agent inherits broader global tools.exec policy than the matching host agent policy", async () => {