{"record":{"id":"66bb895591f9c375","repo":"apolloconfig/apollo","slug":"assign-role-permission-is-required","errorCode":null,"errorMessage":"Assign role permission is required","messagePattern":"Assign role permission is required","errorType":"http","errorClass":"AccessDeniedException","httpStatus":403,"severity":"error","filePath":"apollo-portal/src/main/java/com/ctrip/framework/apollo/openapi/v1/controller/AccessKeyController.java","lineNumber":104,"sourceCode":"  public ResponseEntity<Void> enableAccessKey(String appId, String env, Long accessKeyId,\n      Integer mode, String operator) {\n    requireAccessKeyPermissionForUserToken(appId, env);\n    accessKeyOpenApiService.enableAccessKey(appId, env, accessKeyId, mode,\n        operatorResolver.resolve(operator));\n    return ResponseEntity.ok().build();\n  }\n\n  @Override\n  @PreAuthorize(value = \"@unifiedPermissionValidator.isAppAdmin(#appId)\")\n  public ResponseEntity<List<OpenAccessKeyDTO>> findAccessKeys(String appId, String env) {\n    requireAccessKeyPermissionForUserToken(appId, env);\n    return ResponseEntity.ok(accessKeyOpenApiService.findAccessKeys(appId, env));\n  }\n\n  private void requireAccessKeyPermissionForUserToken(String appId, String env) {\n    if (UserIdentityConstants.USER_TOKEN.equals(UserIdentityContextHolder.getAuthType())\n        && !unifiedPermissionValidator.hasAssignRolePermission(appId, env, null, null)) {\n      throw new AccessDeniedException(\"Assign role permission is required\");\n    }\n  }\n}\n","sourceCodeStart":86,"sourceCodeEnd":108,"githubUrl":"https://github.com/apolloconfig/apollo/blob/d95fc18d112589efc09ddcbe1507047584d55251/apollo-portal/src/main/java/com/ctrip/framework/apollo/openapi/v1/controller/AccessKeyController.java#L86-L108","documentation":"Thrown by AccessKeyController.requireAccessKeyPermissionForUserToken when the request is authenticated with a USER_TOKEN identity but the user does not have assign-role permission for the specified app and environment. This guards access-key operations (find/enable/disable) so that only users with elevated role-assignment authority can manage access keys. It is a Spring Security AccessDeniedException, resulting in HTTP 403.","triggerScenarios":"Calling findAccessKeys(appId, env) or enableAccessKey(...) with a user-token credential where unifiedPermissionValidator.hasAssignRolePermission(appId, env, null, null) returns false. Only USER_TOKEN identities hit this check; CONSUMER and USER identities bypass it.","commonSituations":"A user-token (personal access token) lacks the 'AssignRole' permission for the target app/env. The user was recently removed as an app admin but their token is still in use. The environment name does not match any env the user has permissions for.","solutions":["Grant the user assign-role permission (app admin) for the target app and environment via the Portal.","Switch to using a Consumer token (API token) instead of a user-token if the operation is automated.","Verify the env parameter is correct and that the user has permissions in that specific environment."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before calling access key APIs with a user-token, check permission\nif (UserIdentityConstants.USER_TOKEN.equals(UserIdentityContextHolder.getAuthType())) {\n    if (!unifiedPermissionValidator.hasAssignRolePermission(appId, env, null, null)) {\n        throw new IllegalStateException(\n            \"User token lacks assign-role permission for app \" + appId + \" env \" + env);\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use Consumer tokens (not user-tokens) for automated access-key management.","Verify the user behind a user-token has app-admin/assign-role permission before scripting access-key operations.","Document which operations require assign-role permission vs read permission."],"tags":["openapi","authorization","access-key","apollo-portal","user-token","permission"],"backgroundTag":null,"analyzedSha":"d95fc18d112589efc09ddcbe1507047584d55251","analyzedAt":"2026-08-14T04:00:05.477Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}