Skip to content
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

- Document Helm deployed RBAC permissions and remove unnecessary permissions ([#810]).

- [#810]: https://github.com/stackabletech/druid-operator/pull/810

## [26.3.0] - 2026-03-16

## [26.3.0-rc1] - 2026-03-16
Expand Down
18 changes: 9 additions & 9 deletions Cargo.nix

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 9 additions & 9 deletions crate-hashes.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -6,73 +6,87 @@ metadata:
labels:
{{- include "operator.labels" . | nindent 4 }}
rules:
- apiGroups:
- ""
resources:
- nodes
verbs:
- list
- watch
# For automatic cluster domain detection
- apiGroups:
- ""
resources:
- nodes/proxy
verbs:
- get
# Manage core workload resources created per AirflowCluster.
# All resources are applied via Server-Side Apply (create + patch) and tracked for
# orphan cleanup (list + delete).
- apiGroups:
- ""
resources:
- pods
- configmaps
- secrets
- services
- endpoints
- serviceaccounts
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
# Shared internal authentication secret (cookie passphrase and internal client password).
# Orphan cleanup not needed (instead, Kubernetes GC via owner reference).
- apiGroups:
- rbac.authorization.k8s.io
- ""
resources:
- rolebindings
- secrets
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
# ServiceAccount created per DruidCluster for workload pod identity.
# Applied via SSA and tracked for orphan cleanup. Not watched by the controller.
- apiGroups:
- apps
- ""
resources:
- statefulsets
- serviceaccounts
verbs:
- create
- delete
- get
- list
- patch
# RoleBinding created per DruidCluster to bind the product ClusterRole to the workload
# ServiceAccount. Applied via SSA and tracked for orphan cleanup. Not watched by the controller.
- apiGroups:
- rbac.authorization.k8s.io
resources:
- rolebindings
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
# Required to bind the product ClusterRole to the per-cluster ServiceAccount.
- apiGroups:
- rbac.authorization.k8s.io
resources:
- clusterroles
verbs:
- bind
resourceNames:
- {{ include "operator.name" . }}-clusterrole
# StatefulSet created per role group. Applied via SSA, tracked for orphan cleanup, and
# owned by the controller.
- apiGroups:
- batch
- apps
resources:
- jobs
- statefulsets
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
# PodDisruptionBudget created per role. Applied via SSA and tracked for orphan cleanup.
# Not watched by the controller.
- apiGroups:
- policy
resources:
Expand All @@ -83,23 +97,24 @@ rules:
- get
- list
- patch
- update
- watch
# Required for maintaining the CRDs within the operator (including the conversion webhook info).
# Also for the startup condition check before the controller can run.
- apiGroups:
- apiextensions.k8s.io
resources:
- customresourcedefinitions
verbs:
- get
# Required to maintain the CRD. The operator needs to do this, as it needs to enter e.g. it's
# generated certificate in the conversion webhook.
{{- if .Values.maintenance.customResourceDefinitions.maintain }}
- create
- patch
{{- end }}
# Required for startup condition
- list
- watch
{{- end }}
# Listener created per role group for external access. Applied via SSA and tracked for orphan
# cleanup.
- apiGroups:
- listeners.stackable.tech
resources:
Expand All @@ -110,29 +125,31 @@ rules:
- get
- list
- patch
- watch
# Required to report reconciliation results and warnings back to the DruidCluster object.
- apiGroups:
- events.k8s.io
resources:
- events
verbs:
- create
- patch
# Primary CRD: watched by Controller::new() and read during reconciliation.
- apiGroups:
- {{ include "operator.name" . }}.stackable.tech
resources:
- {{ include "operator.name" . }}clusters
verbs:
- get
- list
- patch
- watch
# Status subresource: updated at the end of every reconciliation.
- apiGroups:
- {{ include "operator.name" . }}.stackable.tech
resources:
- {{ include "operator.name" . }}clusters/status
verbs:
- patch
# Read S3 connection and bucket configuration referenced in the DruidCluster spec.
- apiGroups:
- s3.stackable.tech
resources:
Expand All @@ -142,6 +159,7 @@ rules:
- get
- list
- watch
# Read authentication class configuration referenced in the DruidCluster spec.
- apiGroups:
- authentication.stackable.tech
resources:
Expand All @@ -150,45 +168,3 @@ rules:
- get
- list
- watch
- apiGroups:
- rbac.authorization.k8s.io
resources:
- clusterroles
verbs:
- bind
resourceNames:
- {{ include "operator.name" . }}-clusterrole

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ include "operator.name" . }}-clusterrole
labels:
{{- include "operator.labels" . | nindent 4 }}
rules:
- apiGroups:
- ""
resources:
- configmaps
- secrets
- serviceaccounts
verbs:
- get
Comment on lines -170 to -177
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed these permissions (as I did for the Airflow product ClusterRole), and tests ran fine. It looks like copy/pasta.

@adwk67 do you have any reason to think Druid needs runtime access to k8s Secrets?

- apiGroups:
- events.k8s.io
resources:
- events
verbs:
- create
- patch
{{ if .Capabilities.APIVersions.Has "security.openshift.io/v1" }}
- apiGroups:
- security.openshift.io
resources:
- securitycontextconstraints
resourceNames:
- nonroot-v2
verbs:
- use
{{ end }}
29 changes: 29 additions & 0 deletions deploy/helm/druid-operator/templates/clusterrole-product.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
# Product ClusterRole: bound (via per DruidCluster RoleBinding) to the ServiceAccount that Druid
# workload pods (brokers, coordinators, historicals, middleManagers, routers) run as.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ include "operator.name" . }}-clusterrole
labels:
{{- include "operator.labels" . | nindent 4 }}
rules:
# Allows Druid pods to emit Kubernetes events (e.g. for lifecycle notifications).
- apiGroups:
- events.k8s.io
resources:
- events
verbs:
- create
- patch
{{ if .Capabilities.APIVersions.Has "security.openshift.io/v1" }}
# Required on OpenShift to allow the Druid pods to run as a non-root user.
- apiGroups:
- security.openshift.io
resources:
- securitycontextconstraints
resourceNames:
- nonroot-v2
verbs:
- use
{{ end }}
Loading