From a7a08b665037f9863cb0b7b9371d2b72e80c0704 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 14 Feb 2026 13:14:17 +0100 Subject: [PATCH] test(gateway): cover tools allow/deny precedence --- src/gateway/tools-invoke-http.test.ts | 62 +++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/gateway/tools-invoke-http.test.ts b/src/gateway/tools-invoke-http.test.ts index d373c274100..eeeac85819d 100644 --- a/src/gateway/tools-invoke-http.test.ts +++ b/src/gateway/tools-invoke-http.test.ts @@ -279,6 +279,68 @@ describe("POST /tools/invoke", () => { expect(res.status).toBe(404); }); + it("allows gateway tool via HTTP when explicitly enabled in gateway.tools.allow", async () => { + testState.agentsConfig = { + list: [{ id: "main", tools: { allow: ["gateway"] } }], + // oxlint-disable-next-line typescript/no-explicit-any + } as any; + const { writeConfigFile } = await import("../config/config.js"); + await writeConfigFile({ + gateway: { tools: { allow: ["gateway"] } }, + // oxlint-disable-next-line typescript/no-explicit-any + } as any); + + const token = resolveGatewayToken(); + + try { + const res = await invokeTool({ + port: sharedPort, + tool: "gateway", + headers: { authorization: `Bearer ${token}` }, + sessionKey: "main", + }); + + // Ensure we didn't hit the HTTP deny list (404). Invalid args should map to 400. + expect(res.status).toBe(400); + const body = await res.json(); + expect(body.ok).toBe(false); + expect(body.error?.type).toBe("tool_error"); + } finally { + await writeConfigFile({ + // oxlint-disable-next-line typescript/no-explicit-any + } as any); + } + }); + + it("treats gateway.tools.deny as higher priority than gateway.tools.allow", async () => { + testState.agentsConfig = { + list: [{ id: "main", tools: { allow: ["gateway"] } }], + // oxlint-disable-next-line typescript/no-explicit-any + } as any; + const { writeConfigFile } = await import("../config/config.js"); + await writeConfigFile({ + gateway: { tools: { allow: ["gateway"], deny: ["gateway"] } }, + // oxlint-disable-next-line typescript/no-explicit-any + } as any); + + const token = resolveGatewayToken(); + + try { + const res = await invokeTool({ + port: sharedPort, + tool: "gateway", + headers: { authorization: `Bearer ${token}` }, + sessionKey: "main", + }); + + expect(res.status).toBe(404); + } finally { + await writeConfigFile({ + // oxlint-disable-next-line typescript/no-explicit-any + } as any); + } + }); + it("uses the configured main session key when sessionKey is missing or main", async () => { testState.agentsConfig = { list: [