diff --git a/coderd/rbac/authz.go b/coderd/rbac/authz.go index 3bc37d0564..ab35be9081 100644 --- a/coderd/rbac/authz.go +++ b/coderd/rbac/authz.go @@ -39,8 +39,26 @@ func Filter[O Objecter](ctx context.Context, auth Authorizer, subjID string, sub return objects, nil } objectType := objects[0].RBACObject().Type - filtered := make([]O, 0) + + // Running benchmarks on this function, it is **always** faster to call + // auth.ByRoleName on <10 objects. This is because the overhead of + // 'PrepareByRoleName'. Once we cross 10 objects, then it starts to become + // faster + if len(objects) < 10 { + for _, o := range objects { + rbacObj := o.RBACObject() + if rbacObj.Type != objectType { + return nil, xerrors.Errorf("object types must be uniform across the set (%s), found %s", objectType, rbacObj) + } + err := auth.ByRoleName(ctx, subjID, subjRoles, scope, action, o.RBACObject()) + if err == nil { + filtered = append(filtered, o) + } + } + return filtered, nil + } + prepared, err := auth.PrepareByRoleName(ctx, subjID, subjRoles, scope, action, objectType) if err != nil { return nil, xerrors.Errorf("prepare: %w", err)