{"record":{"id":"af75afae46256226","repo":"weaviate/weaviate","slug":"revoking-w","errorCode":null,"errorMessage":"revoking: %w","messagePattern":"revoking: %w","errorType":"http","errorClass":null,"httpStatus":403,"severity":"error","filePath":"adapters/handlers/rest/authz/handlers_authz.go","lineNumber":1317,"sourceCode":"\t\t\"component\":             authorization.ComponentName,\n\t\t\"user\":                  principal.Username,\n\t\t\"role_to_get_users_for\": params.ID,\n\t}).Info(\"users requested\")\n\n\treturn authz.NewGetUsersForRoleDeprecatedOK().WithPayload(filteredUsers)\n}\n\nfunc (h *authZHandlers) revokeRoleFromUser(params authz.RevokeRoleFromUserParams, principal *models.Principal) middleware.Responder {\n\tctx := params.HTTPRequest.Context()\n\tinternalID := namespacing.QualifyUserIDForLookup(principal, h.namespacesEnabled, params.ID)\n\n\tfor _, role := range params.Body.Roles {\n\t\tif strings.TrimSpace(role) == \"\" {\n\t\t\treturn authz.NewRevokeRoleFromUserBadRequest().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, fmt.Errorf(\"one or more of the roles you want to revoke is empty\")))\n\t\t}\n\n\t\tif err := validateEnvVarRoles(role); err != nil {\n\t\t\treturn authz.NewRevokeRoleFromUserForbidden().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, fmt.Errorf(\"revoking: %w\", err)))\n\t\t}\n\t}\n\n\tif err := h.validateUserIDForNamespaces(internalID); err != nil {\n\t\treturn authz.NewRevokeRoleFromUserBadRequest().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, err))\n\t}\n\n\tif err := h.validateUserTypeForNamespaces(params.Body.UserType); err != nil {\n\t\treturn authz.NewRevokeRoleFromUserBadRequest().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, err))\n\t}\n\n\tif len(params.Body.Roles) == 0 {\n\t\treturn authz.NewRevokeRoleFromUserBadRequest().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, fmt.Errorf(\"roles can not be empty\")))\n\t}\n\n\tif err := h.authorizer.Authorize(ctx, principal, authorization.USER_AND_GROUP_ASSIGN_AND_REVOKE, authorization.Users(internalID)...); err != nil {\n\t\treturn authz.NewRevokeRoleFromUserForbidden().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, err))\n\t}","sourceCodeStart":1299,"sourceCodeEnd":1335,"githubUrl":"https://github.com/weaviate/weaviate/blob/75aa4b6d11f8818305aafd4440b4e32794f7ca04/adapters/handlers/rest/authz/handlers_authz.go#L1299-L1335","documentation":"Wraps a failure from validateEnvVarRoles when revoking a role from a user: the role name refers to a reserved ENV VAR-managed role (name beginning with the env-var role prefix) that cannot be revoked via this endpoint. Returned as HTTP 403 Forbidden. The inner error details the offending role.","triggerScenarios":"POST /users/{id}/roles/revoke with a role name that matches the dynamic/env-var role naming convention (e.g. starts with the ENV_VAR prefixed dynamic role prefix), which is assignment-managed by environment configuration, not the RBAC API.","commonSituations":"Operators copying dynamic role names from GET /roles output and trying to revoke them directly; migrations that list all roles including env-var-generated ones; mixed static/dynamic deployments where some roles come from AUTHORIZATION_ADMIN env settings.","solutions":["Do not revoke env-var-derived roles via the API; change the role assignment in the environment configuration instead","Check the role name against the env-var role prefix before revoking","Filter dynamic roles out of the revoke request"],"exampleFix":"// before\nroles := []string{\"admin\", dynamicRole} // dynamicRole like \"env:xyz\"\n// after\nif validateEnvVarRoles(dynamicRole) == nil {\n\troles = []string{\"admin\", dynamicRole}\n} else {\n\troles = []string{\"admin\"} // manage dynamic role via env config\n}","handlingStrategy":"validation","validationCode":"if strings.HasPrefix(role, envVarRolePrefix) {\n\treturn fmt.Errorf(\"role %q is env-var managed and cannot be revoked via API\", role)\n}","typeGuard":"func isEnvVarRole(role string) bool { return strings.HasPrefix(role, envVarRolePrefix) }","tryCatchPattern":null,"preventionTips":["Filter dynamic/env-var roles out of revoke requests","Manage env-var role assignments in configuration, not via RBAC APIs","Document which roles in your deployment are env-var derived"],"tags":["rest","rbac","forbidden","env-var"],"backgroundTag":"env-var-role-not-revocable","analyzedSha":"75aa4b6d11f8818305aafd4440b4e32794f7ca04","analyzedAt":"2026-09-04T14:58:20.392Z","contentChangedAt":"2026-09-04T14:58:20.392Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}