@@ -2239,6 +2239,63 @@ describe('workflow execute async route', () => {
22392239 : executionCall . snapshot
22402240 expect ( snapshot . metadata . enforceCredentialAccess ) . toBe ( true )
22412241 } )
2242+
2243+ describe ( 'credential actor is derived from the authenticated caller' , ( ) => {
2244+ it . each ( [
2245+ [ 'session without isClientSession' , EXECUTION_CALLERS [ 0 ] , true ] ,
2246+ [ 'personal API key' , EXECUTION_CALLERS [ 1 ] , true ] ,
2247+ [ 'workspace API key' , EXECUTION_CALLERS [ 2 ] , false ] ,
2248+ [ 'public API' , EXECUTION_CALLERS [ 3 ] , false ] ,
2249+ [ 'internal JWT' , EXECUTION_CALLERS [ 4 ] , false ] ,
2250+ ] as const ) ( '%s: authenticated user is actor = %s' , async ( _name , caller , expected ) => {
2251+ configureExecutionCaller ( caller )
2252+
2253+ const response = await POST (
2254+ createCallerExecutionRequest ( caller , undefined , 'sync' ) ,
2255+ createRouteContext ( { id : 'workflow-1' } )
2256+ )
2257+
2258+ expect ( response . status ) . toBe ( 200 )
2259+ expect ( mockPreprocessExecution ) . toHaveBeenCalledWith (
2260+ expect . objectContaining ( { useAuthenticatedUserAsActor : expected } )
2261+ )
2262+ const executionCall = mockExecuteWorkflowCore . mock . calls [ 0 ] [ 0 ]
2263+ const snapshot =
2264+ typeof executionCall . snapshot === 'string'
2265+ ? JSON . parse ( executionCall . snapshot )
2266+ : executionCall . snapshot
2267+ expect ( snapshot . metadata . enforceCredentialAccess ) . toBe ( expected )
2268+ } )
2269+
2270+ it ( 'authorizes a session run that defaults to draft state at write' , async ( ) => {
2271+ const response = await POST (
2272+ createMockRequest ( 'POST' , { input : { } } , { 'Content-Type' : 'application/json' } ) ,
2273+ createRouteContext ( { id : 'workflow-1' } )
2274+ )
2275+
2276+ expect ( response . status ) . toBe ( 200 )
2277+ expect ( mockAuthorizeWorkflowByWorkspacePermission ) . toHaveBeenCalledWith (
2278+ expect . objectContaining ( { action : 'write' } )
2279+ )
2280+ } )
2281+
2282+ it ( 'authorizes a session run of the deployed state at read' , async ( ) => {
2283+ const response = await POST (
2284+ createMockRequest (
2285+ 'POST' ,
2286+ { input : { } , useDraftState : false } ,
2287+ { 'Content-Type' : 'application/json' }
2288+ ) ,
2289+ createRouteContext ( { id : 'workflow-1' } )
2290+ )
2291+
2292+ expect ( response . status ) . toBe ( 200 )
2293+ expect ( mockAuthorizeWorkflowByWorkspacePermission ) . toHaveBeenCalledWith (
2294+ expect . objectContaining ( { action : 'read' } )
2295+ )
2296+ } )
2297+ } )
2298+
22422299 describe ( 'triggerType override gate' , ( ) => {
22432300 it . each ( [
22442301 [ 'personal API key' , EXECUTION_CALLERS [ 1 ] ] ,
0 commit comments