@@ -295,6 +295,7 @@ func TestBatchUpdateMetadata(t *testing.T) {
295295 now = dbtime .Now ()
296296 // Set up consistent IDs that represent a valid workspace->agent relationship
297297 workspaceID = uuid .MustParse ("12345678-1234-1234-1234-123456789012" )
298+ templateID = uuid .MustParse ("aaaabbbb-cccc-dddd-eeee-ffffffff0000" )
298299 ownerID = uuid .MustParse ("87654321-4321-4321-4321-210987654321" )
299300 orgID = uuid .MustParse ("11111111-1111-1111-1111-111111111111" )
300301 agentID = uuid .MustParse ("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" )
@@ -358,8 +359,48 @@ func TestBatchUpdateMetadata(t *testing.T) {
358359 OrganizationID : orgID ,
359360 })
360361
361- // Create context with system actor so authorization passes
362- ctx := dbauthz .AsSystemRestricted (context .Background ())
362+ // Create roles with workspace permissions
363+ userRoles := rbac .Roles ([]rbac.Role {
364+ {
365+ Identifier : rbac .RoleMember (),
366+ User : []rbac.Permission {
367+ {
368+ Negate : false ,
369+ ResourceType : rbac .ResourceWorkspace .Type ,
370+ Action : policy .WildcardSymbol ,
371+ },
372+ },
373+ ByOrgID : map [string ]rbac.OrgPermissions {
374+ orgID .String (): {
375+ Member : []rbac.Permission {
376+ {
377+ Negate : false ,
378+ ResourceType : rbac .ResourceWorkspace .Type ,
379+ Action : policy .WildcardSymbol ,
380+ },
381+ },
382+ },
383+ },
384+ },
385+ })
386+
387+ agentScope := rbac .WorkspaceAgentScope (rbac.WorkspaceAgentScopeParams {
388+ WorkspaceID : workspaceID ,
389+ OwnerID : ownerID ,
390+ TemplateID : templateID ,
391+ VersionID : uuid .New (),
392+ })
393+
394+ ctx := dbauthz .As (context .Background (), rbac.Subject {
395+ Type : rbac .SubjectTypeUser ,
396+ FriendlyName : "testuser" ,
397+ Email : "testuser@example.com" ,
398+ ID : ownerID .String (),
399+ Roles : userRoles ,
400+ Groups : []string {orgID .String ()},
401+ Scope : agentScope ,
402+ }.WithCachedASTValue ())
403+
363404 resp , err := api .BatchUpdateMetadata (ctx , req )
364405 require .NoError (t , err )
365406 require .NotNil (t , resp )
@@ -376,6 +417,7 @@ func TestBatchUpdateMetadata(t *testing.T) {
376417 pub = & fakePublisher {}
377418 now = dbtime .Now ()
378419 workspaceID = uuid .MustParse ("12345678-1234-1234-1234-123456789012" )
420+ templateID = uuid .MustParse ("aaaabbbb-cccc-dddd-eeee-ffffffff0000" )
379421 ownerID = uuid .MustParse ("87654321-4321-4321-4321-210987654321" )
380422 orgID = uuid .MustParse ("11111111-1111-1111-1111-111111111111" )
381423 agentID = uuid .MustParse ("bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" )
@@ -445,12 +487,53 @@ func TestBatchUpdateMetadata(t *testing.T) {
445487 OrganizationID : uuid .Nil , // Invalid: fails dbauthz fast path validation
446488 })
447489
448- // Create context with system actor so authorization passes
449- ctx := dbauthz .AsSystemRestricted (context .Background ())
490+ // Create roles with workspace permissions
491+ userRoles := rbac .Roles ([]rbac.Role {
492+ {
493+ Identifier : rbac .RoleMember (),
494+ User : []rbac.Permission {
495+ {
496+ Negate : false ,
497+ ResourceType : rbac .ResourceWorkspace .Type ,
498+ Action : policy .WildcardSymbol ,
499+ },
500+ },
501+ ByOrgID : map [string ]rbac.OrgPermissions {
502+ orgID .String (): {
503+ Member : []rbac.Permission {
504+ {
505+ Negate : false ,
506+ ResourceType : rbac .ResourceWorkspace .Type ,
507+ Action : policy .WildcardSymbol ,
508+ },
509+ },
510+ },
511+ },
512+ },
513+ })
514+
515+ agentScope := rbac .WorkspaceAgentScope (rbac.WorkspaceAgentScopeParams {
516+ WorkspaceID : workspaceID ,
517+ OwnerID : ownerID ,
518+ TemplateID : templateID ,
519+ VersionID : uuid .New (),
520+ })
521+
522+ ctx := dbauthz .As (context .Background (), rbac.Subject {
523+ Type : rbac .SubjectTypeUser ,
524+ FriendlyName : "testuser" ,
525+ Email : "testuser@example.com" ,
526+ ID : ownerID .String (),
527+ Roles : userRoles ,
528+ Groups : []string {orgID .String ()},
529+ Scope : agentScope ,
530+ }.WithCachedASTValue ())
531+
450532 resp , err := api .BatchUpdateMetadata (ctx , req )
451533 require .NoError (t , err )
452534 require .NotNil (t , resp )
453535 })
536+
454537 // Test RBAC slow path - no RBAC object in context
455538 // This test verifies that when no RBAC object is present in context, the dbauthz layer
456539 // falls back to the slow path and calls GetWorkspaceByAgentID.
@@ -463,6 +546,7 @@ func TestBatchUpdateMetadata(t *testing.T) {
463546 pub = & fakePublisher {}
464547 now = dbtime .Now ()
465548 workspaceID = uuid .MustParse ("12345678-1234-1234-1234-123456789012" )
549+ templateID = uuid .MustParse ("aaaabbbb-cccc-dddd-eeee-ffffffff0000" )
466550 ownerID = uuid .MustParse ("87654321-4321-4321-4321-210987654321" )
467551 orgID = uuid .MustParse ("11111111-1111-1111-1111-111111111111" )
468552 agentID = uuid .MustParse ("dddddddd-dddd-dddd-dddd-dddddddddddd" )
@@ -523,8 +607,48 @@ func TestBatchUpdateMetadata(t *testing.T) {
523607 },
524608 }
525609
526- // Create context with system actor so authorization passes
527- ctx := dbauthz .AsSystemRestricted (context .Background ())
610+ // Create roles with workspace permissions
611+ userRoles := rbac .Roles ([]rbac.Role {
612+ {
613+ Identifier : rbac .RoleMember (),
614+ User : []rbac.Permission {
615+ {
616+ Negate : false ,
617+ ResourceType : rbac .ResourceWorkspace .Type ,
618+ Action : policy .WildcardSymbol ,
619+ },
620+ },
621+ ByOrgID : map [string ]rbac.OrgPermissions {
622+ orgID .String (): {
623+ Member : []rbac.Permission {
624+ {
625+ Negate : false ,
626+ ResourceType : rbac .ResourceWorkspace .Type ,
627+ Action : policy .WildcardSymbol ,
628+ },
629+ },
630+ },
631+ },
632+ },
633+ })
634+
635+ agentScope := rbac .WorkspaceAgentScope (rbac.WorkspaceAgentScopeParams {
636+ WorkspaceID : workspaceID ,
637+ OwnerID : ownerID ,
638+ TemplateID : templateID ,
639+ VersionID : uuid .New (),
640+ })
641+
642+ ctx := dbauthz .As (context .Background (), rbac.Subject {
643+ Type : rbac .SubjectTypeUser ,
644+ FriendlyName : "testuser" ,
645+ Email : "testuser@example.com" ,
646+ ID : ownerID .String (),
647+ Roles : userRoles ,
648+ Groups : []string {orgID .String ()},
649+ Scope : agentScope ,
650+ }.WithCachedASTValue ())
651+
528652 resp , err := api .BatchUpdateMetadata (ctx , req )
529653 require .NoError (t , err )
530654 require .NotNil (t , resp )
0 commit comments