{"record":{"id":"4ea061765402bbe3","repo":"apolloconfig/apollo","slug":"access-is-denied-4ea061","errorCode":null,"errorMessage":"Access is denied","messagePattern":"Access is denied","errorType":"exception","errorClass":"AccessDeniedException","httpStatus":403,"severity":"warning","filePath":"apollo-portal/src/main/java/com/ctrip/framework/apollo/openapi/v1/controller/ClusterController.java","lineNumber":128,"sourceCode":"        return;\n      }\n      throw new AccessDeniedException(\"Super admin permission is required\");\n    }\n    if (UserIdentityConstants.CONSUMER.equals(authType)) {\n      // Existing OpenAPI consumers use app-scoped authorization here. Preserve that public\n      // token boundary while keeping the Portal USER path compatible with the legacy WebAPI.\n      if (unifiedPermissionValidator.isAppAdmin(appId)) {\n        return;\n      }\n      throw new AccessDeniedException(\"App admin permission is required\");\n    }\n    if (UserIdentityConstants.USER_TOKEN.equals(authType)) {\n      if (unifiedPermissionValidator.isSuperAdmin()) {\n        return;\n      }\n      throw new AccessDeniedException(\"Super admin permission is required\");\n    }\n    throw new AccessDeniedException(\"Access is denied\");\n  }\n\n  private void requireReadApplicationPermissionForUserToken(String appId) {\n    if (UserIdentityConstants.USER_TOKEN.equals(UserIdentityContextHolder.getAuthType())\n        && !unifiedPermissionValidator.hasReadApplicationPermission(appId)) {\n      throw new AccessDeniedException(\"Access is denied\");\n    }\n  }\n\n  private void requireCreateClusterPermissionForUserToken(String appId, String env,\n      String clusterName) {\n    if (UserIdentityConstants.USER_TOKEN.equals(UserIdentityContextHolder.getAuthType())\n        && !unifiedPermissionValidator.hasCreateClusterPermission(appId, env, clusterName)) {\n      throw new AccessDeniedException(\"Create cluster permission is required\");\n    }\n  }\n\n  private String resolveOperator(String operator) {","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/apolloconfig/apollo/blob/d95fc18d112589efc09ddcbe1507047584d55251/apollo-portal/src/main/java/com/ctrip/framework/apollo/openapi/v1/controller/ClusterController.java#L110-L146","documentation":"Thrown by ClusterController.requireDeleteClusterPermission as the final fallthrough when the authType in UserIdentityContextHolder does not match any of USER, CONSUMER, or USER_TOKEN (e.g. it is ANONYMOUS or null). This indicates the request reached the controller without a recognized authentication identity being set on the thread-local context. Maps to HTTP 403 AccessDeniedException.","triggerScenarios":"DELETE /openapi/v1/envs/{env}/apps/{appId}/clusters/{clusterName} where the authentication filter did not populate UserIdentityContextHolder with a known type — e.g. an ANONYMOUS request bypassing the filter, or a misconfigured auth interceptor that failed to set the auth type.","commonSituations":"A misconfigured security filter chain or a custom authentication interceptor that does not call UserIdentityContextHolder.setAuthType(). Can also occur during local development if the OpenAPI auth filter is disabled or bypassed, or after upgrading Apollo where a new auth type constant was introduced but the delete-permission method was not updated to handle it.","solutions":["Verify the request includes proper authentication (token header or session cookie) and that the auth filter is active.","Check the authentication interceptor configuration to ensure UserIdentityContextHolder.setAuthType() is called with one of USER, CONSUMER, USER_TOKEN.","If a new auth type was introduced, update requireDeleteClusterPermission to handle it explicitly."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// This error indicates a misconfigured auth pipeline — catch and surface a clear diagnostic\ntry {\n    client.delete(\"/openapi/v1/envs/\" + env + \"/apps/\" + appId + \"/clusters/\" + clusterName);\n} catch (AccessDeniedException e) {\n    // Investigate why authType was not set — this is a server-side config issue\n    logger.error(\"Auth type not recognized for delete-cluster. Check security filter configuration.\", e);\n    throw new IllegalStateException(\"Server auth configuration error: authType not set. Contact the platform team.\", e);\n}","preventionTips":["Ensure the OpenAPI authentication filter runs before the controller and sets UserIdentityContextHolder.","Add integration tests that verify authType is populated for authenticated requests.","After Apollo upgrades, verify all auth types are handled in permission-check methods."],"tags":["authorization","openapi","cluster","access-control","auth-type","configuration","http-403"],"backgroundTag":null,"analyzedSha":"d95fc18d112589efc09ddcbe1507047584d55251","analyzedAt":"2026-08-14T04:00:05.477Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}