From 10b0ceed3c718aa33b881ed4c12e46505ce68f90 Mon Sep 17 00:00:00 2001 From: Theodore Li Date: Mon, 1 Jun 2026 18:56:50 -0700 Subject: [PATCH] fix(mothership): scope mothership block tool permissions to the executing user --- .../lib/copilot/request/lifecycle/run.test.ts | 33 +++++++++++++++++++ apps/sim/lib/copilot/request/lifecycle/run.ts | 3 ++ 2 files changed, 36 insertions(+) diff --git a/apps/sim/lib/copilot/request/lifecycle/run.test.ts b/apps/sim/lib/copilot/request/lifecycle/run.test.ts index 31b9c4dad58..12008960528 100644 --- a/apps/sim/lib/copilot/request/lifecycle/run.test.ts +++ b/apps/sim/lib/copilot/request/lifecycle/run.test.ts @@ -222,4 +222,37 @@ describe('runCopilotLifecycle', () => { }) ) }) + + it('propagates payload userPermission into the generated execution context', async () => { + let capturedExecContext: ExecutionContext | undefined + mockGetEffectiveDecryptedEnv.mockResolvedValueOnce({}) + mockRunStreamLoop.mockImplementationOnce( + async ( + _fetchUrl: string, + _fetchOptions: RequestInit, + _context: StreamingContext, + execContext: ExecutionContext + ): Promise => { + capturedExecContext = execContext + } + ) + + await runCopilotLifecycle( + { message: 'hello', messageId: 'stream-1', userPermission: 'write' }, + { + userId: 'user-1', + workspaceId: 'ws-1', + chatId: 'chat-1', + } + ) + + expect(capturedExecContext).toEqual( + expect.objectContaining({ + userId: 'user-1', + workspaceId: 'ws-1', + chatId: 'chat-1', + userPermission: 'write', + }) + ) + }) }) diff --git a/apps/sim/lib/copilot/request/lifecycle/run.ts b/apps/sim/lib/copilot/request/lifecycle/run.ts index e06341f43ef..ff7f63e9ef4 100644 --- a/apps/sim/lib/copilot/request/lifecycle/run.ts +++ b/apps/sim/lib/copilot/request/lifecycle/run.ts @@ -472,6 +472,8 @@ async function buildExecutionContext( const userTimezone = typeof requestPayload?.userTimezone === 'string' ? requestPayload.userTimezone : undefined const requestMode = typeof requestPayload?.mode === 'string' ? requestPayload.mode : undefined + const userPermission = + typeof requestPayload?.userPermission === 'string' ? requestPayload.userPermission : undefined let execContext: ExecutionContext if (workflowId) { @@ -490,6 +492,7 @@ async function buildExecutionContext( if (userTimezone) execContext.userTimezone = userTimezone execContext.copilotToolExecution = true if (requestMode) execContext.requestMode = requestMode + if (userPermission) execContext.userPermission = userPermission execContext.messageId = typeof requestPayload?.messageId === 'string' ? requestPayload.messageId : undefined execContext.executionId = executionId