apolloconfig/apollo · error · AccessDeniedException

Access is denied

Error message

Access is denied

What it means

HTTP 403 (AccessDeniedException). Thrown by NamespaceBranchController.requireConfigReadForUserToken when the auth type is USER_TOKEN and UnifiedPermissionValidator.shouldHideConfigToCurrentUser returns true for the given appId/env/cluster/namespace. This is the config-hiding / restricted-namespace feature: certain namespaces are marked hidden from non-privileged users, and a user-token caller whose access would be hidden is denied outright on branch-read endpoints.

Source

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

      return operator;
    }

    throw new BadRequestException("Unsupported auth type: %s", authType);
  }

  private boolean shouldHideConfigToCurrentUser(String appId, String env, String clusterName,
      String namespaceName) {
    return UserIdentityConstants.USER.equals(UserIdentityContextHolder.getAuthType())
        && unifiedPermissionValidator.shouldHideConfigToCurrentUser(appId, env, clusterName,
            namespaceName);
  }

  private void requireConfigReadForUserToken(String appId, String env, String clusterName,
      String namespaceName) {
    if (UserIdentityConstants.USER_TOKEN.equals(UserIdentityContextHolder.getAuthType())
        && unifiedPermissionValidator.shouldHideConfigToCurrentUser(appId, env, clusterName,
            namespaceName)) {
      throw new AccessDeniedException("Access is denied");
    }
  }
}

View on GitHub (pinned to d95fc18d11)

Solutions

  1. Grant the token owner view/read permission on the hidden namespace, or remove the hidden restriction for that namespace.
  2. Use a portal USER session or a CONSUMER OpenAPI token that has been granted access instead of a restricted user-token.
  3. Confirm the namespace is intended to be visible to the caller's identity before requesting it.
  4. If access is legitimately denied, stop reading that namespace from the automated client.

Example fix

// before: user-token owner not authorized for hidden namespace
client.withUserToken(restrictedToken).findBranch(appId, env, cluster, ns); // 403

// after: grant view permission to the owner, or use an authorized token
admin.grantView(appId, ns, ownerId);
client.withUserToken(authorizedToken).findBranch(appId, env, cluster, ns);
Defensive patterns

Strategy: validation

Validate before calling

// For USER_TOKEN branch reads: confirm the namespace is not hidden from the owner.
boolean hidden = shouldHide(tokenOwner, appId, env, cluster, ns); // via role/visibility probe
if (hidden) { /* grant view or skip; do not call findBranch */ }

Type guard

null

Try / catch

try {
  client.withUserToken(token).findBranch(appId, env, cluster, ns);
} catch (HttpServerErrorException.Forbidden e) {
  // Access is denied -> namespace hidden from token owner; grant view or switch identity
}

Prevention

When it happens

Trigger: GET find-branch (or other branch read) using a user-token for a namespace flagged hidden-from-current-user (e.g. a secret/credentials namespace restricted to a specific team) where the token's owner is not in the allowed set.

Common situations: A user-token owned by a user outside the namespace's authorized team reading a restricted namespace; namespace visibility changed to hidden after the token was issued; token reused across apps where the owner lacks view rights.

Related errors


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