From 2a6229161d5aa4440f7a95baf16c4a6eda5ed034 Mon Sep 17 00:00:00 2001 From: Dotta Date: Sun, 8 Nov 2026 21:12:04 -0600 Subject: [PATCH] fix(authz): do not link fast response denials to connection settings Address review: the Connections page shows fast response controls only while the experiment is on, so a denied fast response route now gets the general board instruction instead of a link to a page that may lack them. Co-Authored-By: Claude Opus 5.5 --- server/src/__tests__/board-access-denial.test.ts | 5 +++++ server/src/routes/authz.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/server/src/__tests__/board-access-denial.test.ts b/server/src/__tests__/board-access-denial.test.ts index 8b8759af6ac..582cc11e6c4 100644 --- a/server/src/__tests__/board-access-denial.test.ts +++ b/server/src/__tests__/board-access-denial.test.ts @@ -57,6 +57,11 @@ describe("board-only denial", () => { expect(res.body.remediation).not.toContain("](/"); }); + it("does not link connection settings for fast responses, whose controls an experiment can hide", async () => { + const res = await request(createApp(agentActor)).put(`/api/companies/${COMPANY_ID}/fast-response`).expect(403); + expect(res.body.remediation).not.toContain("/company/settings/connections"); + }); + it("applies through the org-access guard", async () => { const res = await request(createApp(agentActor, assertBoardOrgAccess)).delete(`/api/companies/${COMPANY_ID}`).expect(403); expect(res.body.code).toBe(BOARD_ACCESS_REQUIRED_CODE); diff --git a/server/src/routes/authz.ts b/server/src/routes/authz.ts index b0a64ec9a54..10d2400fd55 100644 --- a/server/src/routes/authz.ts +++ b/server/src/routes/authz.ts @@ -48,7 +48,7 @@ const AGENT_PROFILE_TABS: Record = { const BOARD_CONTROL_PAGES: Array<[RegExp, (match: RegExpExecArray) => [string, string]]> = [ [/^\/(?:companies\/[^/]+\/)?secrets?(?:[-/]|$)/, () => ["company secrets", "//company/settings/secrets"]], [/^\/companies\/[^/]+\/(?:budgets|budget-incidents|costs)(?:\/|$)/, () => ["budgets", "//activity/budgets"]], - [/^\/companies\/[^/]+\/(?:prompt-injection-prevention|decision-model|fast-response)(?:\/|$)/, () => ["connection settings", "//company/settings/connections"]], + [/^\/companies\/[^/]+\/(?:prompt-injection-prevention|decision-model)(?:\/|$)/, () => ["connection settings", "//company/settings/connections"]], [/^\/companies\/[^/]+\/(?:members|invites|join-requests)(?:\/|$)/, () => ["company members", "//company/settings/members"]], [/^\/companies\/[^/]+\/(?:tools\/)?gateways(?:\/|$)|^\/tool-gateway\//, () => ["tool gateways", "//apps/gateways"]], [/^\/approvals\/([^/]+)/, match => ["the approval", `//approvals/${match[1]}`]],