{"record":{"id":"a5332ff7f0da9b30","repo":"apolloconfig/apollo","slug":"access-is-denied-a5332f","errorCode":null,"errorMessage":"Access is denied","messagePattern":"Access is denied","errorType":"exception","errorClass":"AccessDeniedException","httpStatus":403,"severity":"error","filePath":"apollo-portal/src/main/java/com/ctrip/framework/apollo/openapi/v1/controller/PortalManagementController.java","lineNumber":634,"sourceCode":"  @PreAuthorize(value = \"@unifiedPermissionValidator.isAppAdmin(#appId)\")\n  public ResponseEntity<Resource> exportAppConfig(String appId, String env, String clusterName) {\n    requirePortalUserRequest();\n    Env targetEnv = parseEnv(env);\n    String filename = String.format(\"%s+%s+%s+%s.zip\", appId, env, clusterName,\n        DateFormatUtils.format(new Date(), \"yyyy_MMdd_HH_mm_ss\"));\n    return exportZipResource(filename, outputStream -> configsExportService\n        .exportAppConfigByEnvAndCluster(appId, targetEnv, clusterName, outputStream),\n        \"export app configs failed\");\n  }\n\n  @Override\n  public ResponseEntity<Resource> exportNamespaceItems(String appId, String env, String clusterName,\n      String namespaceName) {\n    requirePortalUserRequest();\n    Env targetEnv = parseEnv(env);\n    if (unifiedPermissionValidator.shouldHideConfigToCurrentUser(appId, env, clusterName,\n        namespaceName)) {\n      throw new AccessDeniedException(\"Access is denied\");\n    }\n    List<String> fileNameSplit = Splitter.on(\".\").splitToList(namespaceName);\n    String fileName = namespaceName;\n    if (fileNameSplit.size() <= 1\n        || !ConfigFileFormat.isValidFormat(fileNameSplit.get(fileNameSplit.size() - 1))) {\n      fileName = Joiner.on(\".\").join(namespaceName, ConfigFileFormat.Properties.getValue());\n    }\n\n    NamespaceBO namespaceBO =\n        namespaceService.loadNamespaceBO(appId, targetEnv, clusterName, namespaceName, true, false);\n    String configFileContent = NamespaceBOUtils.convert2configFileContent(namespaceBO);\n    return resourceResponse(fileName, configFileContent.getBytes(StandardCharsets.UTF_8));\n  }\n\n  @Override\n  @PreAuthorize(value = \"@unifiedPermissionValidator.isAppAdmin(#appId)\")\n  public ResponseEntity<Void> importAppConfig(String appId, String env, String clusterName,\n      String conflictAction, MultipartFile file) {","sourceCodeStart":616,"sourceCodeEnd":652,"githubUrl":"https://github.com/apolloconfig/apollo/blob/d95fc18d112589efc09ddcbe1507047584d55251/apollo-portal/src/main/java/com/ctrip/framework/apollo/openapi/v1/controller/PortalManagementController.java#L616-L652","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Request the namespace-level 'ModifyNamespace' or 'ReleaseNamespace' role for the current user via the portal permissions page.","Verify you are targeting the correct namespace — some apps have both public and private namespaces with similar names.","Contact the app admin to grant the current user view permission on that namespace."],"exampleFix":"// before: user lacks namespace view permission\nexportNamespaceItems(appId, env, cluster, \"secret-namespace\")\n\n// after: admin grants namespace role first, then export succeeds\n// (portal UI: App > Manage Users > grant role on 'secret-namespace')","handlingStrategy":"validation","validationCode":"// Check visibility before attempting export\nif (unifiedPermissionValidator.shouldHideConfigToCurrentUser(appId, env, clusterName, namespaceName)) {\n  throw new IllegalStateException(\"Current user cannot view namespace: \" + namespaceName);\n}","typeGuard":null,"tryCatchPattern":"try {\n  exportNamespaceItems(appId, env, cluster, namespace);\n} catch (AccessDeniedException e) {\n  if (e.getMessage().contains(\"Access is denied\")) {\n    // request namespace view permission from app admin\n  }\n}","preventionTips":["Verify namespace visibility with shouldHideConfigToCurrentUser before calling export.","Ensure the current user has the namespace role before scripting exports.","Maintain a mapping of restricted namespaces per user for audit."],"tags":["permission","authorization","access-denied","namespace","visibility","apollo-portal"],"backgroundTag":null,"analyzedSha":"d95fc18d112589efc09ddcbe1507047584d55251","analyzedAt":"2026-08-14T04:00:05.477Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}