{"record":{"id":"f7faf3aa9588a44d","repo":"provectus/kafka-ui","slug":"access-denied","errorCode":null,"errorMessage":"Access denied","messagePattern":"Access denied","errorType":"http","errorClass":"AccessDeniedException","httpStatus":403,"severity":"error","filePath":"kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/rbac/AccessControlService.java","lineNumber":109,"sourceCode":"    if (!properties.getRoles().isEmpty()\n        && \"oauth2\".equalsIgnoreCase(environment.getProperty(\"auth.type\"))\n        && (clientRegistrationRepository == null || !clientRegistrationRepository.iterator().hasNext())) {\n      log.error(\"Roles are configured but no authentication methods are present. Authentication might fail.\");\n    }\n  }\n\n  public Mono<Void> validateAccess(AccessContext context) {\n    if (!rbacEnabled) {\n      return Mono.empty();\n    }\n\n    if (CollectionUtils.isNotEmpty(context.getApplicationConfigActions())) {\n      return getUser()\n          .doOnNext(user -> {\n            boolean accessGranted = isApplicationConfigAccessible(context, user);\n\n            if (!accessGranted) {\n              throw new AccessDeniedException(ACCESS_DENIED);\n            }\n          }).then();\n    }\n\n    return getUser()\n        .doOnNext(user -> {\n          boolean accessGranted =\n              isApplicationConfigAccessible(context, user)\n                  && isClusterAccessible(context, user)\n                  && isClusterConfigAccessible(context, user)\n                  && isTopicAccessible(context, user)\n                  && isConsumerGroupAccessible(context, user)\n                  && isConnectAccessible(context, user)\n                  && isConnectorAccessible(context, user) // TODO connector selectors\n                  && isSchemaAccessible(context, user)\n                  && isKsqlAccessible(context, user)\n                  && isAclAccessible(context, user)\n                  && isAuditAccessible(context, user);","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/provectus/kafka-ui/blob/83b5a60cc08501b570a0c4d0b4cdfceb1b88d6b7/kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/rbac/AccessControlService.java#L91-L127","documentation":"AccessControlService.validateAccess() checks RBAC permission for the target resource. When the request carries application-config actions, it resolves the current authenticated user and asks isApplicationConfigAccessible(); if no RBAC role grants the user that access it throws Spring's AccessDeniedException with message 'Access denied', which surfaces as HTTP 403.","triggerScenarios":"Calling an endpoint that touches application config (e.g. dynamic config GET/PUT) while logged in as a user whose RBAC roles do not include the `applicationconfig` resource with the required action (view/edit).","commonSituations":"Deploying RBAC roles for admins only, then a regular user opens the dynamic-config screen; role name or subject typo in roles.yml so the grant never matches; JWT/OAuth user whose groups differ from role subjects.","solutions":["Add or fix an RBAC role granting the user's role/subject the `applicationconfig` resource with the needed action (view/edit)","Check roles.yml: resource name must be `applicationconfig`, actions lowercase, subject must match the authenticated user's principal/group","Verify the user actually authenticates with the identity (group/username) the role targets"],"exampleFix":"// roles.yml before\nroles:\n  - name: viewer\n    resources: [topic]\n    actions: [read]\n// after\nroles:\n  - name: viewer\n    resources: [topic, applicationconfig]\n    actions: [read]","handlingStrategy":"try-catch","validationCode":"// Check before calling: does any role grant applicationconfig access to this user?\nboolean canEditAppConfig = roles.stream().anyMatch(r ->\n    r.getResources().contains(\"applicationconfig\") && r.getActions().contains(\"edit\"));","typeGuard":null,"tryCatchPattern":"webClient.get()\n  .uri(\"/api/config\")\n  .retrieve()\n  .onStatus(HttpStatusCode::is4xxClientForbidden,\n             r -> Mono.error(new IllegalStateException(\"User lacks applicationconfig RBAC grant\")))\n  .bodyToMono(String.class);","preventionTips":["Map every UI screen to the RBAC resource/action it requires and review role coverage","Test roles.yml in CI with representative users","Keep subject names (groups) in sync with your IdP"],"tags":["rbac","authorization","access-control"],"backgroundTag":"permission-denied","analyzedSha":"83b5a60cc08501b570a0c4d0b4cdfceb1b88d6b7","analyzedAt":"2026-09-08T04:35:39.002Z","contentChangedAt":"2026-09-08T04:35:39.002Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}