apolloconfig/apollo · error · AccessDeniedException

Access is denied

Error message

Access is denied

What it means

Thrown in exportNamespaceItems when shouldHideConfigToCurrentUser returns true for the given appId/env/cluster/namespace, meaning the current portal user is not permitted to view that namespace's configuration. Apollo supports hiding specific namespaces (e.g. sensitive or restricted ones) from users who lack the appropriate role. This is a data-visibility guard, not an authentication failure.

Source

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

  @PreAuthorize(value = "@unifiedPermissionValidator.isAppAdmin(#appId)")
  public ResponseEntity<Resource> exportAppConfig(String appId, String env, String clusterName) {
    requirePortalUserRequest();
    Env targetEnv = parseEnv(env);
    String filename = String.format("%s+%s+%s+%s.zip", appId, env, clusterName,
        DateFormatUtils.format(new Date(), "yyyy_MMdd_HH_mm_ss"));
    return exportZipResource(filename, outputStream -> configsExportService
        .exportAppConfigByEnvAndCluster(appId, targetEnv, clusterName, outputStream),
        "export app configs failed");
  }

  @Override
  public ResponseEntity<Resource> exportNamespaceItems(String appId, String env, String clusterName,
      String namespaceName) {
    requirePortalUserRequest();
    Env targetEnv = parseEnv(env);
    if (unifiedPermissionValidator.shouldHideConfigToCurrentUser(appId, env, clusterName,
        namespaceName)) {
      throw new AccessDeniedException("Access is denied");
    }
    List<String> fileNameSplit = Splitter.on(".").splitToList(namespaceName);
    String fileName = namespaceName;
    if (fileNameSplit.size() <= 1
        || !ConfigFileFormat.isValidFormat(fileNameSplit.get(fileNameSplit.size() - 1))) {
      fileName = Joiner.on(".").join(namespaceName, ConfigFileFormat.Properties.getValue());
    }

    NamespaceBO namespaceBO =
        namespaceService.loadNamespaceBO(appId, targetEnv, clusterName, namespaceName, true, false);
    String configFileContent = NamespaceBOUtils.convert2configFileContent(namespaceBO);
    return resourceResponse(fileName, configFileContent.getBytes(StandardCharsets.UTF_8));
  }

  @Override
  @PreAuthorize(value = "@unifiedPermissionValidator.isAppAdmin(#appId)")
  public ResponseEntity<Void> importAppConfig(String appId, String env, String clusterName,
      String conflictAction, MultipartFile file) {

View on GitHub (pinned to d95fc18d11)

Solutions

  1. Request the namespace-level 'ModifyNamespace' or 'ReleaseNamespace' role for the current user via the portal permissions page.
  2. Verify you are targeting the correct namespace — some apps have both public and private namespaces with similar names.
  3. Contact the app admin to grant the current user view permission on that namespace.

Example fix

// before: user lacks namespace view permission
exportNamespaceItems(appId, env, cluster, "secret-namespace")

// after: admin grants namespace role first, then export succeeds
// (portal UI: App > Manage Users > grant role on 'secret-namespace')
Defensive patterns

Strategy: validation

Validate before calling

// Check visibility before attempting export
if (unifiedPermissionValidator.shouldHideConfigToCurrentUser(appId, env, clusterName, namespaceName)) {
  throw new IllegalStateException("Current user cannot view namespace: " + namespaceName);
}

Try / catch

try {
  exportNamespaceItems(appId, env, cluster, namespace);
} catch (AccessDeniedException e) {
  if (e.getMessage().contains("Access is denied")) {
    // request namespace view permission from app admin
  }
}

Prevention

When it happens

Trigger: A portal user requests to export a namespace's items, but the namespace is configured to be hidden from that user based on their role assignments.

Common situations: The user has read access to the app but not to a specific restricted namespace; namespace-level visibility was tightened after the user was granted app-level access; or the user is viewing a namespace they were never authorized to see.

Related errors


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