{"record":{"id":"67602899046207bc","repo":"apache/pulsar","slug":"this-operation-requires-super-user-access-676028","errorCode":null,"errorMessage":"This operation requires super-user access","messagePattern":"This operation requires super-user access","errorType":"http","errorClass":"RestException","httpStatus":401,"severity":"error","filePath":"pulsar-websocket/src/main/java/org/apache/pulsar/websocket/admin/WebSocketWebResource.java","lineNumber":116,"sourceCode":"        return authenticationDataSource;\n    }\n\n    /**\n     * Checks whether the user has Pulsar Super-User access to the system.\n     *\n     * @throws RestException\n     *             if not authorized\n     */\n    protected void validateSuperUserAccess() {\n        if (service().getConfig().isAuthenticationEnabled()) {\n            String appId = clientAppId();\n            log.debug()\n                    .attr(\"requestUri\", uri.getRequestUri())\n                    .attr(\"authenticated\", clientAppId())\n                    .attr(\"role\", appId)\n                    .log(\"Check super user access: Authenticated: -- Role\");\n            if (!service().getConfig().getSuperUserRoles().contains(appId)) {\n                throw new RestException(Status.UNAUTHORIZED, \"This operation requires super-user access\");\n            }\n        }\n    }\n\n    /**\n     * Checks if user has super-user access or user is authorized to produce/consume on a given topic.\n     *\n     * @param topic\n     * @throws RestException\n     */\n    protected void validateUserAccess(TopicName topic) {\n        boolean isAuthorized = false;\n\n        try {\n            validateSuperUserAccess();\n            isAuthorized = true;\n        } catch (Exception e) {\n            try {","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/admin/WebSocketWebResource.java#L98-L134","documentation":"validateSuperUserAccess checks the authenticated appId against config.getSuperUserRoles(); if the role is not listed it throws RestException(UNAUTHORIZED, 'This operation requires super-user access'). Called for admin operations (and via validateUserAccess) on the websocket proxy's REST endpoints.","triggerScenarios":"A non-superuser role calls an admin endpoint requiring super-user privileges, e.g. proxy stats or access validation paths that first check validateSuperUserAccess.","commonSituations":"Role authenticated fine but simply absent from superUserRoles; superUserRoles configured on the broker but not on the websocket proxy config; role string mismatch (case, prefix) between token subject and configured role.","solutions":["Add the authenticated role to superUserRoles in the websocket proxy configuration and restart","Verify the exact role string from the token (use the logs' 'role' attribute) matches the configured entry exactly","Use a role that already has super-user access for admin operations","If the operation should only need topic-level authorization, call a non-superuser endpoint instead"],"exampleFix":"// before\nsuperUserRoles=[]\n// after\nsuperUserRoles=[admin]","handlingStrategy":"try-catch","validationCode":"// client-side pre-check\nSet<String> myRoles = tokenRoles(jwt); if (!myRoles.contains(\"admin\")) { throw new SecurityException(\"operation requires a super-user role\"); }","typeGuard":"boolean isSuperUser(String role, WebSocketProxyConfiguration c) { return role != null && c.getSuperUserRoles().contains(role); }","tryCatchPattern":"try { return webResource.adminOp(); } catch (WebApplicationException e) { if (e.getResponse().getStatus() == 401 && e.getMessage().contains(\"super-user\")) { throw new AccessDeniedException(\"use a super-user role for this operation\"); } throw e; }","preventionTips":["Keep superUserRoles identical across broker and websocket proxy configs","Extract the exact role string from your token and compare before calling admin APIs","Use topic-scoped endpoints when super-user is unnecessary","Review role claims (case/prefix) when tokens are issued by an external IdP"],"tags":["rest","authorization","permissions"],"backgroundTag":"insufficient-permissions","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}