apolloconfig/apollo · error · AccessDeniedException

Create application permission is required

Error message

Create application permission is required

What it means

Thrown by AppController.requireCreateAppInEnvPermission when none of the auth-type permission conditions are satisfied. For USER auth type, permission is always granted (legacy compatibility). For CONSUMER and USER_TOKEN, unifiedPermissionValidator.hasCreateApplicationPermission() must return true. If the auth type is unrecognized or the permission check fails, AccessDeniedException is thrown. Results in HTTP 403.

Source

Thrown at apollo-portal/src/main/java/com/ctrip/framework/apollo/openapi/v1/controller/AppController.java:261

  }

  private void requireCreateAppInEnvPermission() {
    String authType = UserIdentityContextHolder.getAuthType();
    if (UserIdentityConstants.USER.equals(authType)) {
      // The legacy Portal WebAPI path for creating an app in a missing environment did not
      // perform method-level authorization. Keep Portal UI behavior compatible after routing
      // it through OpenAPI, but do not extend that compatibility to consumer tokens.
      return;
    }
    if (UserIdentityConstants.CONSUMER.equals(authType)
        && unifiedPermissionValidator.hasCreateApplicationPermission()) {
      return;
    }
    if (UserIdentityConstants.USER_TOKEN.equals(authType)
        && unifiedPermissionValidator.hasCreateApplicationPermission()) {
      return;
    }
    throw new AccessDeniedException("Create application 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.hasText(loginUser.getUserId())) {
        throw new BadRequestException("Current user not found");
      }
      return loginUser.getUserId();
    }

    if (UserIdentityConstants.CONSUMER.equals(authType)) {
      if (!StringUtils.hasText(operator)) {
        throw new BadRequestException("operator should not be null or empty");
      }
      if (userService.findByUserId(operator) == null) {

View on GitHub (pinned to d95fc18d11)

Solutions

  1. Grant the CreateApplication system role to the consumer token via assignCreateApplicationRoleToConsumer(token, operator).
  2. For user-tokens, ensure the user has the CreateApplication permission in the Portal system settings.
  3. Verify the authentication filter is correctly populating UserIdentityContextHolder with a valid auth type.
Defensive patterns

Strategy: validation

Validate before calling

// For CONSUMER auth, verify create-app permission before calling createAppInEnv
if (UserIdentityConstants.CONSUMER.equals(UserIdentityContextHolder.getAuthType())) {
    if (!unifiedPermissionValidator.hasCreateApplicationPermission()) {
        throw new AccessDeniedException(
            "Consumer token lacks CreateApplication system role. Assign it first.");
    }
}

Prevention

When it happens

Trigger: Calling createAppInEnv with a CONSUMER or USER_TOKEN identity that lacks the CreateApplication system-level permission. Also thrown if the auth type in UserIdentityContextHolder is none of USER, CONSUMER, or USER_TOKEN.

Common situations: A consumer token was created but never assigned the CreateApplication system role (via assignCreateApplicationRoleToConsumer). A user-token belongs to a user without app-creation privileges. The auth filter failed to set a recognized auth type in the context holder.

Related errors


AI-assisted analysis of apolloconfig/apollo@d95fc18d11 (2026-08-14). Data as JSON: /api/errors/59eeef1e3641a662. Report an issue: GitHub.