apolloconfig/apollo · error · AccessDeniedException
Assign role permission is required
Error message
Assign role permission is required
What it means
HTTP 403 (AccessDeniedException). Thrown by PermissionController.requirePortalUserOrAssignRolePermission when none of the allow-paths match: caller is not a plain USER, OR is a CONSUMER without app-scoped hasAssignRolePermission(appId), OR is a USER_TOKEN without namespace-scoped hasAssignRolePermission(appId,env,cluster,namespace). Used to gate role-assignment writes — assigning roles requires either being a portal user or holding the ASSIGN_ROLE permission at the right scope.
Source
Thrown at apollo-portal/src/main/java/com/ctrip/framework/apollo/openapi/v1/controller/PermissionController.java:314
private void requirePortalUserOrAssignRolePermission(String appId) {
requirePortalUserOrAssignRolePermission(appId, null, null, null);
}
private void requirePortalUserOrAssignRolePermission(String appId, String env, String clusterName,
String namespaceName) {
String authType = UserIdentityContextHolder.getAuthType();
if (UserIdentityConstants.USER.equals(authType)) {
return;
}
if (UserIdentityConstants.CONSUMER.equals(authType)
&& unifiedPermissionValidator.hasAssignRolePermission(appId)) {
return;
}
if (UserIdentityConstants.USER_TOKEN.equals(authType) && unifiedPermissionValidator
.hasAssignRolePermission(appId, env, clusterName, namespaceName)) {
return;
}
throw new AccessDeniedException("Assign role permission is required");
}
private void requireAppRoleReadPermission(String appId) {
if (UserIdentityConstants.USER_TOKEN.equals(UserIdentityContextHolder.getAuthType())
&& !unifiedPermissionValidator.hasAssignRolePermission(appId)) {
throw new AccessDeniedException("Assign role permission is required");
}
}
private void requireAppRoleReadPermission(String appId, String env, String clusterName,
String namespaceName) {
if (UserIdentityConstants.USER_TOKEN.equals(UserIdentityContextHolder.getAuthType())
&& !unifiedPermissionValidator.hasAssignRolePermission(appId, env, clusterName,
namespaceName)) {
throw new AccessDeniedException("Assign role permission is required");
}
}
View on GitHub (pinned to d95fc18d11)
Solutions
- Grant the caller ASSIGN_ROLE permission at the required scope: app-level for CONSUMER, namespace-level (appId/env/cluster/namespace) for USER_TOKEN.
- Perform role assignment interactively as a portal USER (USER auth always passes this gate).
- Verify the appId/env/cluster/namespace in the request match the scope of the granted ASSIGN_ROLE permission.
- Pre-check hasAssignRolePermission before submitting the assignment.
Example fix
// before: CONSUMER token without ASSIGN_ROLE on appX
client.withConsumerToken(token).assignRole("appX", role); // 403
// after: grant ASSIGN_ROLE (app scope) to the token, or use portal USER
admin.grantAssignRole("appX", token);
client.withConsumerToken(token).assignRole("appX", role); Defensive patterns
Strategy: validation
Validate before calling
// Before role assignment: confirm ASSIGN_ROLE at the right scope.
String authType = currentAuthType();
boolean ok;
if ("CONSUMER".equals(authType)) ok = hasAssignRole(token, appId);
else if ("USER_TOKEN".equals(authType)) ok = hasAssignRole(token, appId, env, cluster, ns);
else ok = "USER".equals(authType);
if (!ok) { /* grant ASSIGN_ROLE or use portal USER; do not call assignRole */ } Type guard
null
Try / catch
try {
client.assignRole(appId, env, cluster, ns, role);
} catch (HttpServerErrorException.Forbidden e) {
// Assign role permission is required -> grant ASSIGN_ROLE at the right scope and retry
} Prevention
- Grant ASSIGN_ROLE at the correct scope: app for CONSUMER, namespace for USER_TOKEN.
- Perform interactive role management as a portal USER.
- Pre-check hasAssignRolePermission before assigning roles.
When it happens
Trigger: POST role-assignment endpoints (grant/remove roles) using a CONSUMER token without ASSIGN_ROLE permission on the app, or a USER_TOKEN without namespace-scoped ASSIGN_ROLE permission.
Common situations: OpenAPI consumer token reused for role management it was never granted; user-token scoped to config ops attempting role assignment; permission revoked after automation was set up; attempting to assign roles on an app the token is not scoped to.
Related errors
- You don't have the permission to modify namespace: %s
- Forbidden operation. Caused by: 1.you don't have release per
- Access is denied
- Access is denied
- Create namespace permission is required
AI-assisted analysis of apolloconfig/apollo@d95fc18d11 (2026-08-14).
Data as JSON: /api/errors/99aea5df7544f66d.
Report an issue: GitHub.