provectus/kafka-ui · error · AccessDeniedException
Access denied
Error message
Access denied
What it means
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.
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
Example fix
// roles.yml before
roles:
- name: viewer
resources: [topic]
actions: [read]
// after
roles:
- name: viewer
resources: [topic, applicationconfig]
actions: [read] Defensive patterns
Strategy: try-catch
Validate before calling
// Check before calling: does any role grant applicationconfig access to this user?
boolean canEditAppConfig = roles.stream().anyMatch(r ->
r.getResources().contains("applicationconfig") && r.getActions().contains("edit")); Try / catch
webClient.get()
.uri("/api/config")
.retrieve()
.onStatus(HttpStatusCode::is4xxClientForbidden,
r -> Mono.error(new IllegalStateException("User lacks applicationconfig RBAC grant")))
.bodyToMono(String.class); Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
AI-assisted analysis of provectus/kafka-ui@83b5a60cc0 (2026-09-08).
Data as JSON: /api/errors/f7faf3aa9588a44d.
Report an issue: GitHub.
Appendix: source
Thrown at kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/rbac/AccessControlService.java:109
if (!properties.getRoles().isEmpty()
&& "oauth2".equalsIgnoreCase(environment.getProperty("auth.type"))
&& (clientRegistrationRepository == null || !clientRegistrationRepository.iterator().hasNext())) {
log.error("Roles are configured but no authentication methods are present. Authentication might fail.");
}
}
public Mono<Void> validateAccess(AccessContext context) {
if (!rbacEnabled) {
return Mono.empty();
}
if (CollectionUtils.isNotEmpty(context.getApplicationConfigActions())) {
return getUser()
.doOnNext(user -> {
boolean accessGranted = isApplicationConfigAccessible(context, user);
if (!accessGranted) {
throw new AccessDeniedException(ACCESS_DENIED);
}
}).then();
}
return getUser()
.doOnNext(user -> {
boolean accessGranted =
isApplicationConfigAccessible(context, user)
&& isClusterAccessible(context, user)
&& isClusterConfigAccessible(context, user)
&& isTopicAccessible(context, user)
&& isConsumerGroupAccessible(context, user)
&& isConnectAccessible(context, user)
&& isConnectorAccessible(context, user) // TODO connector selectors
&& isSchemaAccessible(context, user)
&& isKsqlAccessible(context, user)
&& isAclAccessible(context, user)
&& isAuditAccessible(context, user);View on GitHub (pinned to 83b5a60cc0)