Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.

## [Unreleased]

### Changed

- Helm deployed RBAC permissions documented, with unnecessary permissions removed ([#953]).

[#953]: https://github.com/stackabletech/kafka-operator/pull/953

## [26.3.0] - 2026-03-16

## [26.3.0-rc1] - 2026-03-16
Expand Down
63 changes: 36 additions & 27 deletions deploy/helm/kafka-operator/templates/roles.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,44 @@ metadata:
labels:
{{- include "operator.labels" . | nindent 4 }}
rules:
# For automatic cluster domain detection (list nodes to infer the cluster DNS domain)
- apiGroups:
- ""
resources:
- nodes
verbs:
- list
- watch
# For automatic cluster domain detection
# For automatic cluster domain detection (probe node proxy to read DNS config)
- apiGroups:
- ""
resources:
- nodes/proxy
verbs:
- get
# Manage core namespaced resources created per KafkaCluster.
# All resources are applied via Server-Side Apply (create + patch) and tracked for
# orphan cleanup (list + delete). The ReconciliationPaused strategy calls get instead
# of apply_patch, so get is also needed. All three are watched by the controller via
# .owns(), so watch is required.
# - configmaps: per-rolegroup configuration, and the discovery ConfigMap
# - services: per-rolegroup headless and metrics services
# - serviceaccounts: one per KafkaCluster, created by build_rbac_resources()
- apiGroups:
- ""
resources:
- pods
- configmaps
- secrets
- services
- endpoints
- serviceaccounts
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
# RoleBindings bind the product ClusterRole to the per-cluster ServiceAccount.
# Applied via SSA, tracked for orphan cleanup, and watched via .owns().
- apiGroups:
- rbac.authorization.k8s.io
resources:
Expand All @@ -47,32 +54,23 @@ rules:
- get
- list
- patch
- update
- watch
# StatefulSets run the broker and (KRaft) controller role groups.
# Applied via SSA, tracked for orphan cleanup, and watched via .owns().
- apiGroups:
- apps
resources:
- statefulsets
verbs:
- get
- create
- delete
- list
- patch
- update
- watch
- apiGroups:
- batch
resources:
- jobs
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
# PodDisruptionBudgets protect broker and controller role groups during voluntary disruptions.
# Applied via SSA and tracked for orphan cleanup. PDBs are not watched by the controller
# (no .owns() / .watches()), so watch is not needed.
- apiGroups:
- policy
resources:
Expand All @@ -83,8 +81,6 @@ rules:
- get
- list
- patch
- update
- watch
- apiGroups:
- apiextensions.k8s.io
resources:
Expand All @@ -100,47 +96,55 @@ rules:
- list
- watch
{{- end }}
# Record Kubernetes events for reconciliation outcomes
- apiGroups:
- events.k8s.io
resources:
- events
verbs:
- create
- patch
# Watch and reconcile KafkaCluster resources (the primary resource for this controller)
- apiGroups:
- {{ include "operator.name" . }}.stackable.tech
resources:
- {{ include "operator.name" . }}clusters
verbs:
- get
- list
- patch
- watch
# Write status conditions back to the KafkaCluster object
- apiGroups:
- {{ include "operator.name" . }}.stackable.tech
resources:
- {{ include "operator.name" . }}clusters/status
verbs:
- patch
# Read AuthenticationClasses to resolve TLS and Kerberos authentication configuration.
# Only get is needed: the operator resolves classes via a direct client.get() call
# during reconciliation; there is no controller watch on AuthenticationClass.
- apiGroups:
- authentication.stackable.tech
resources:
- authenticationclasses
verbs:
- get
- list
- watch
# Manage Listener resources for broker bootstrap and per-rolegroup exposure.
# Applied via SSA, tracked for orphan cleanup, and watched via .owns().
- apiGroups:
- listeners.stackable.tech
resources:
- listeners
verbs:
- create
- delete
- get
- list
- watch
- patch
- create
- delete
- watch
# Bind the product ClusterRole to per-cluster ServiceAccounts (via RoleBindings above).
# The operator creates RoleBindings that reference this ClusterRole, so it must have
# permission to bind it.
- apiGroups:
- rbac.authorization.k8s.io
resources:
Expand All @@ -157,6 +161,9 @@ metadata:
labels:
{{- include "operator.labels" . | nindent 4 }}
rules:
# The Kafka broker and KRaft controller pods need to read their own ConfigMaps,
# Secrets, ServiceAccounts, and Services at runtime (e.g. via the Stackable secret
# operator or init containers that inspect cluster configuration).
- apiGroups:
- ""
resources:
Expand All @@ -166,6 +173,7 @@ rules:
- services
verbs:
- get
# Kafka pods may emit Kubernetes events (e.g. via the Stackable commons init container)
- apiGroups:
- events.k8s.io
resources:
Expand All @@ -174,6 +182,7 @@ rules:
- create
- patch
{{ if .Capabilities.APIVersions.Has "security.openshift.io/v1" }}
# On OpenShift, the workload pods must be allowed to use the nonroot-v2 SCC
- apiGroups:
- security.openshift.io
resources:
Expand Down
Loading