apolloconfig/apollo · error · AccessDeniedException
Create cluster permission is required
Error message
Create cluster permission is required
What it means
Thrown by ClusterController.requireCreateClusterPermissionForUserToken when a USER_TOKEN identity lacks the cluster:create operation scope for the target appId/env/clusterName combination. The check delegates to unifiedPermissionValidator.hasCreateClusterPermission(appId, env, clusterName), which for USER_TOKEN calls userTokenPermissionValidator.hasCreateClusterPermission. Maps to HTTP 403 AccessDeniedException.
Source
Thrown at apollo-portal/src/main/java/com/ctrip/framework/apollo/openapi/v1/controller/ClusterController.java:142
return;
}
throw new AccessDeniedException("Super admin permission is required");
}
throw new AccessDeniedException("Access is denied");
}
private void requireReadApplicationPermissionForUserToken(String appId) {
if (UserIdentityConstants.USER_TOKEN.equals(UserIdentityContextHolder.getAuthType())
&& !unifiedPermissionValidator.hasReadApplicationPermission(appId)) {
throw new AccessDeniedException("Access is denied");
}
}
private void requireCreateClusterPermissionForUserToken(String appId, String env,
String clusterName) {
if (UserIdentityConstants.USER_TOKEN.equals(UserIdentityContextHolder.getAuthType())
&& !unifiedPermissionValidator.hasCreateClusterPermission(appId, env, clusterName)) {
throw new AccessDeniedException("Create cluster permission is required");
}
}
private String resolveOperator(String operator) {
String authType = UserIdentityContextHolder.getAuthType();
if (UserIdentityConstants.USER.equals(authType)
|| UserIdentityConstants.USER_TOKEN.equals(authType)) {
UserInfo loginUser = userInfoHolder.getUser();
if (loginUser == null || StringUtils.isBlank(loginUser.getUserId())) {
throw new BadRequestException("Current user not found");
}
return loginUser.getUserId();
}
RequestPrecondition.checkArguments(!StringUtils.isContainEmpty(operator),
"operator should not be null or empty");
if (userService.findByUserId(operator) == null) {View on GitHub (pinned to d95fc18d11)
Solutions
- Add the cluster:create operation scope to the USER_TOKEN's grants in the Portal token management page.
- If the token is scoped per-app, ensure the specific appId is included in the token's resource-scoped operations.
- Switch to a CONSUMER token with create-cluster permission if the operation is app-scoped automation.
Defensive patterns
Strategy: validation
Validate before calling
// Before create-cluster with USER_TOKEN, verify cluster:create scope
if (!tokenHasOperation("cluster:create", appId)) {
throw new SecurityException("USER_TOKEN lacks cluster:create scope for appId: " + appId);
} Try / catch
try {
client.post("/openapi/v1/envs/" + env + "/apps/" + appId + "/clusters", cluster);
} catch (AccessDeniedException e) {
logger.error("USER_TOKEN lacks cluster:create for appId={}. Add scope in Portal.", appId);
throw e;
} Prevention
- When provisioning a USER_TOKEN for cluster management, include cluster:create in the scope.
- Document the full list of operations a token needs for each automation scenario.
- Test token scopes against a staging environment before production deployment.
When it happens
Trigger: POST /openapi/v1/envs/{env}/apps/{appId}/clusters with a USER_TOKEN that does not have the cluster:create operation (UserTokenOperation.CLUSTER_CREATE = "cluster:create") granted for the target appId.
Common situations: A developer generates a personal access token for CI/CD but only grants config:read and config:modify scopes, forgetting to add cluster:create. The token can manage items but cannot create new clusters.
Related errors
- Super admin permission is required
- App admin permission is required
- Metadata read permission is required
- Access is denied
- Access is denied
AI-assisted analysis of apolloconfig/apollo@d95fc18d11 (2026-08-14).
Data as JSON: /api/errors/a2daedd5a4e87c19.
Report an issue: GitHub.