weaviate/weaviate · warning
can only create roles with less or equal permissions as the
Error message
can only create roles with less or equal permissions as the current user: %w
What it means
RBAC guard thrown by authorizeRoleScopes when a principal attempts to create or modify a role whose permissions exceed the caller's own privileges. Weaviate forbids privilege escalation: a role's combined permissions must be a subset of the current user's effective permissions. The wrapped error details which permission was excessive.
Source
Thrown at adapters/handlers/rest/authz/handlers_authz.go:138
if !confinedToNamespace {
if err = h.authorizer.Authorize(ctx, principal, authorization.VerbWithScope(originalVerb, authorization.ROLE_SCOPE_ALL), authorization.Roles(roleName)...); err == nil {
return nil
}
}
// Check if user can manage roles with matching permissions
if err = h.authorizer.Authorize(ctx, principal, authorization.VerbWithScope(originalVerb, authorization.ROLE_SCOPE_MATCH), authorization.Roles(roleName)...); err == nil {
// Verify user has all permissions they're trying to grant
var errs error
for _, policy := range policies {
if err := h.authorizer.AuthorizeSilent(ctx, principal, policy.Verb, policy.Resource); err != nil {
errs = errors.Join(errs, err)
}
}
return errs
}
return fmt.Errorf("can only create roles with less or equal permissions as the current user: %w", err)
}
// validateLocalRoleAssignment blocks assigning a namespace-local role unless the
// caller is confined to that role's namespace. A local role is managed entirely
// within its namespace, so a global operator (and any cross-namespace caller)
// cannot assign it; global roles carry no namespace and assign anywhere. This is
// what keeps a namespace1 role from ever reaching a namespace2 (or global)
// subject. No-op on NS-disabled clusters, where ':' is a valid name character.
func (h *authZHandlers) validateLocalRoleAssignment(principal *models.Principal, roleNames []string) error {
if !h.namespacesEnabled {
return nil
}
callerNS := namespacing.ConfinedNamespace(principal)
for _, roleName := range roleNames {
if ns := namespacing.NamespaceFromQualified(roleName); ns != "" && ns != callerNS {
return fmt.Errorf("a namespace-local role can only be assigned by an administrator of its own namespace")
}
}View on GitHub (pinned to 75aa4b6d11)
Solutions
- Grant the calling user (or its role) the permissions being assigned to the new role, then retry
- Reduce the new role's permissions to a subset of the caller's own permissions
- Perform role management with a root/admin-level identity
- Inspect the wrapped error to identify the exact offending permission
Example fix
// before
// caller has only collections read; creating role with objects create permission
createRole("writer", perms=[{action:"create_objects",...}]) // denied
// after
// first grant caller create_objects, or scope the new role to:
createRole("reader", perms=[{action:"read_objects",...}]) // subset of caller perms Defensive patterns
Strategy: validation
Validate before calling
// Go: intersect desired role permissions with the caller's own before create/modify
mine := effectivePermissionsOf(principal)
for _, p := range desiredPerms {
if !containsPermission(mine, p) {
return fmt.Errorf("cannot grant %v: exceeds caller's own permissions", p)
}
} Type guard
func isSubset(desired, mine []Permission) bool {
set := map[Permission]bool{}
for _, m := range mine {
set[m] = true
}
for _, d := range desired {
if !set[d] {
return false
}
}
return true
} Try / catch
err := authz.CreateRole(ctx, name, perms)
if err != nil && strings.Contains(err.Error(), "less or equal permissions") {
// inspect wrapped error for the offending permission, drop it or elevate caller
return fmt.Errorf("role exceeds caller privileges: %v", err)
} Prevention
- Perform role management with a root/full-admin identity
- Model new roles as strict subsets of the managing principal's permissions
- Audit permission typos that introduce unintended actions
- For namespace-confined users, create namespace-scoped roles only
When it happens
Trigger: createRole, addPermissions, removePermissions, or deleteRole called (directly or via authorizeRoleRead/resolveRoleForRead) where the target role includes a permission (action, resource type, or scope) the calling user does not itself hold.
Common situations: Admin holding cluster-scoped permissions tries to create a role with data-level permissions they lack; automation tokens with narrow scopes attempting to define broad roles; namespace-confined users creating global roles; permission typo introducing an action outside the caller's set.
Related errors
- role grants a permission you do not hold
- a namespace-local role can only be assigned by an administra
- insufficient permissions to view role
- unauthorized: namespaced OIDC principal cannot be granted th
- resource bound to a different namespace
AI-assisted analysis of weaviate/weaviate@75aa4b6d11 (2026-09-04).
Data as JSON: /api/errors/ea7c4cfaf0102120.
Report an issue: GitHub.