Skip to content

Commit 27f902e

Browse files
fix(mcp): scope operation provenance to MCP delegations
1 parent 560f539 commit 27f902e

2 files changed

Lines changed: 43 additions & 6 deletions

File tree

apps/sim/lib/internal/principals/executor.test.ts

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,16 +81,47 @@ describe('createExecutorPrincipalFromExecutionContext', () => {
8181
)
8282
})
8383

84-
it('binds MCP policy provenance from the trusted execution context', async () => {
84+
it.each(['sim:mcp-servers', 'sim:managed-mcp-credentials'])(
85+
'binds MCP policy provenance from the trusted execution context for %s',
86+
async (audience) => {
87+
const principal = await createExecutorPrincipalFromExecutionContext({
88+
context: executionContext({
89+
mcpBlockId: 'saved-block',
90+
executorDelegationOrigin: { subjectUserId: 'user-origin', workflowId: 'workflow-origin' },
91+
}),
92+
audience,
93+
resourceScope: { mcpServerId: 'server-1' },
94+
})
95+
expect(principal.resourceScope).toEqual({
96+
mcpBlockId: 'saved-block',
97+
mcpServerId: 'server-1',
98+
})
99+
}
100+
)
101+
102+
it('keeps credential lookup unscoped when its block has MCP provenance metadata', async () => {
85103
const principal = await createExecutorPrincipalFromExecutionContext({
86104
context: executionContext({
87-
mcpBlockId: 'saved-block',
105+
mcpBlockId: 'credential-block',
88106
executorDelegationOrigin: { subjectUserId: 'user-origin', workflowId: 'workflow-origin' },
89107
}),
90-
audience: 'sim:mcp-servers',
91-
resourceScope: { mcpServerId: 'server-1' },
108+
audience: 'sim:credential-groups',
109+
})
110+
expect(principal.resourceScope).toBeUndefined()
111+
expect(principal.subjectUserId).toBe('user-origin')
112+
expect(principal.delegationContext?.workflowId).toBe('workflow-origin')
113+
})
114+
115+
it('preserves another operation’s resource scope without adding MCP policy metadata', async () => {
116+
const principal = await createExecutorPrincipalFromExecutionContext({
117+
context: executionContext({
118+
mcpBlockId: 'agent-block',
119+
executorDelegationOrigin: { subjectUserId: 'user-origin', workflowId: 'workflow-origin' },
120+
}),
121+
audience: 'sim:tables',
122+
resourceScope: { tableId: 'table-1' },
92123
})
93-
expect(principal.resourceScope).toEqual({ mcpBlockId: 'saved-block', mcpServerId: 'server-1' })
124+
expect(principal.resourceScope).toEqual({ tableId: 'table-1' })
94125
})
95126

96127
it('uses an explicit trusted execution deadline as the delegation expiry', async () => {

apps/sim/lib/internal/principals/executor.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import { type DelegatedPrincipal, resolvePrincipalSubject } from '@sim/auth/principal'
22
import { generateId } from '@sim/utils/id'
33
import { bindInternalExecutorDelegation } from '@/lib/auth/internal-delegation'
4+
import { MANAGED_MCP_DELEGATION_AUDIENCE } from '@/lib/credentials/application/authorization'
45
import { ExecutorDelegationOriginRequiredError } from '@/lib/internal/tool-operations/identity-faults'
56
import type { InternalToolOperationContext } from '@/lib/internal/tool-operations/types'
7+
import { MCP_SERVER_DELEGATION_AUDIENCE } from '@/lib/mcp/application/authorization'
68
import type { ExecutorDelegationOrigin } from '@/executor/types'
79

810
const EXECUTOR_DELEGATION_TTL_MS = 5 * 60 * 1000
@@ -80,10 +82,14 @@ export async function createExecutorPrincipalFromExecutionContext({
8082
}: CreateExecutorPrincipalFromExecutionContextInput) {
8183
const origin = context.executorDelegationOrigin
8284
if (!origin) throw new ExecutorDelegationOriginRequiredError()
85+
const isMcpAudience =
86+
audience === MCP_SERVER_DELEGATION_AUDIENCE || audience === MANAGED_MCP_DELEGATION_AUDIENCE
8387
return createExecutorPrincipalFromDelegationOrigin(
8488
origin,
8589
audience,
86-
context.mcpBlockId ? { ...resourceScope, mcpBlockId: context.mcpBlockId } : resourceScope,
90+
isMcpAudience && context.mcpBlockId
91+
? { ...resourceScope, mcpBlockId: context.mcpBlockId }
92+
: resourceScope,
8793
expiresAt,
8894
context.userId
8995
)

0 commit comments

Comments
 (0)