Skip to content

Commit caf0a1b

Browse files
chore: Describe RBAC rules, remove unnecessary rules (#767)
* chore: Describe RBAC rules, remove unnecessary rules * chore: Update changelog * chore: Simplify RBAC descriptions They were a bit too verbose * fix: CRD permissions - Add missing description - Remove `get`, it is never used - Make list/watch unconditional * chore: Reword * chore: Keep rbac.authorization.k8s.io rules together * chore: Remove permissions for AirflowCluster role This was never needed, and if an end-user does happen to need their code reading secrets/configmaps, they should create the applicable role and binding. * chore: Remove unused code * chore(nix): Update hashes to avoid mismatch * chore: Split operator and product roles into separate files * Apply suggestions from code review Co-authored-by: Techassi <git@techassi.dev> * chore: Remove unused node list/watch permissions * Apply suggestions from code review Co-authored-by: Techassi <git@techassi.dev> --------- Co-authored-by: Techassi <git@techassi.dev>
1 parent c335c38 commit caf0a1b

6 files changed

Lines changed: 107 additions & 117 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
## [Unreleased]
44

5+
### Changed
6+
7+
- Document Helm deployed RBAC permissions and remove unnecessary permissions ([#767]).
8+
9+
- [#767]: https://github.com/stackabletech/airflow-operator/pull/767
10+
511
## [26.3.0] - 2026-03-16
612

713
## [26.3.0-rc1] - 2026-03-16

Cargo.nix

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crate-hashes.json

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

deploy/helm/airflow-operator/templates/roles.yaml renamed to deploy/helm/airflow-operator/templates/clusterrole-operator.yaml

Lines changed: 32 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -6,37 +6,32 @@ metadata:
66
labels:
77
{{- include "operator.labels" . | nindent 4 }}
88
rules:
9-
- apiGroups:
10-
- ""
11-
resources:
12-
- nodes
13-
verbs:
14-
- list
15-
- watch
169
# For automatic cluster domain detection
1710
- apiGroups:
1811
- ""
1912
resources:
2013
- nodes/proxy
2114
verbs:
2215
- get
16+
# Manage core workload resources created per AirflowCluster.
17+
# All resources are applied via Server-Side Apply (create + patch) and tracked for
18+
# orphan cleanup (list + delete).
2319
- apiGroups:
2420
- ""
2521
resources:
26-
- pods
2722
- configmaps
2823
- secrets
2924
- services
30-
- endpoints
3125
- serviceaccounts
3226
verbs:
3327
- create
3428
- delete
3529
- get
3630
- list
3731
- patch
38-
- update
3932
- watch
33+
# Per AirflowCluster RoleBinding for the workload ServiceAccount to the airflow-clusterrole.
34+
# Applied via SSA (create + patch), tracked for orphan cleanup (list + delete).
4035
- apiGroups:
4136
- rbac.authorization.k8s.io
4237
resources:
@@ -47,32 +42,31 @@ rules:
4742
- get
4843
- list
4944
- patch
50-
- update
51-
- watch
45+
# Allows the operator to create RoleBindings that reference the airflow-clusterrole
46+
# (the product ClusterRole bound to workload pods, defined below)
5247
- apiGroups:
53-
- apps
48+
- rbac.authorization.k8s.io
5449
resources:
55-
- statefulsets
50+
- clusterroles
5651
verbs:
57-
- get
58-
- create
59-
- delete
60-
- list
61-
- patch
62-
- update
63-
- watch
52+
- bind
53+
resourceNames:
54+
- {{ include "operator.name" . }}-clusterrole
55+
# StatefulSets for each role group (webserver, scheduler, worker, triggerer, dag-processor).
56+
# Applied via SSA (create + patch), tracked for orphan cleanup (list + delete).
6457
- apiGroups:
65-
- batch
58+
- apps
6659
resources:
67-
- jobs
60+
- statefulsets
6861
verbs:
6962
- create
7063
- delete
7164
- get
7265
- list
7366
- patch
74-
- update
7567
- watch
68+
# PodDisruptionBudgets per role to protect against simultaneous pod evictions.
69+
# Applied via SSA (create + patch), tracked for orphan cleanup (list + delete).
7670
- apiGroups:
7771
- policy
7872
resources:
@@ -83,49 +77,54 @@ rules:
8377
- get
8478
- list
8579
- patch
86-
- update
87-
- watch
80+
# Required for maintaining the CRDs within the operator (including the conversion webhook info).
81+
# Also for the startup condition check before the controller can run.
8882
- apiGroups:
8983
- apiextensions.k8s.io
9084
resources:
9185
- customresourcedefinitions
9286
verbs:
93-
- get
9487
# Required to maintain the CRD. The operator needs to do this, as it needs to enter e.g. it's
9588
# generated certificate in the conversion webhook.
9689
{{- if .Values.maintenance.customResourceDefinitions.maintain }}
9790
- create
9891
- patch
92+
{{- end }}
9993
# Required for startup condition
10094
- list
10195
- watch
102-
{{- end }}
96+
# Listener for the Webserver role to expose HTTP access via a configurable ListenerClass.
97+
# Applied via SSA (create + patch), tracked for orphan cleanup (list + delete).
10398
- apiGroups:
10499
- listeners.stackable.tech
105100
resources:
106101
- listeners
107102
verbs:
103+
- create
104+
- delete
108105
- get
109106
- list
110-
- watch
111107
- patch
112-
- create
113-
- delete
108+
# Primary reconciliation target: the controller watches AirflowCluster resources (list + watch)
109+
# and reads them during reconciliation (get).
114110
- apiGroups:
115111
- {{ include "operator.name" . }}.stackable.tech
116112
resources:
117113
- {{ include "operator.name" . }}clusters
118114
verbs:
119115
- get
120116
- list
121-
- patch
122117
- watch
118+
# Write reconciliation status conditions back to AirflowCluster objects
123119
- apiGroups:
124120
- {{ include "operator.name" . }}.stackable.tech
125121
resources:
126122
- {{ include "operator.name" . }}clusters/status
127123
verbs:
128124
- patch
125+
# Resolve TLS and authentication provider configuration.
126+
# Watched (list + watch) to re-reconcile when an AuthenticationClass changes,
127+
# and fetched individually (get) during reconciliation via resolve_class().
129128
- apiGroups:
130129
- authentication.stackable.tech
131130
resources:
@@ -134,69 +133,11 @@ rules:
134133
- get
135134
- list
136135
- watch
136+
# Publish Kubernetes events for reconciliation activity
137137
- apiGroups:
138138
- events.k8s.io
139139
resources:
140140
- events
141141
verbs:
142142
- create
143143
- patch
144-
- apiGroups:
145-
- rbac.authorization.k8s.io
146-
resources:
147-
- clusterroles
148-
verbs:
149-
- bind
150-
resourceNames:
151-
- {{ include "operator.name" . }}-clusterrole
152-
---
153-
apiVersion: rbac.authorization.k8s.io/v1
154-
kind: ClusterRole
155-
metadata:
156-
name: {{ include "operator.name" . }}-clusterrole
157-
labels:
158-
{{- include "operator.labels" . | nindent 4 }}
159-
rules:
160-
- apiGroups:
161-
- ""
162-
resources:
163-
- configmaps
164-
- secrets
165-
- serviceaccounts
166-
verbs:
167-
- get
168-
- apiGroups:
169-
- ""
170-
resources:
171-
- pods
172-
verbs:
173-
- create
174-
- delete
175-
- get
176-
- list
177-
- patch
178-
- update
179-
- watch
180-
- apiGroups:
181-
- ""
182-
resources:
183-
- pods/log
184-
verbs:
185-
- get
186-
- apiGroups:
187-
- events.k8s.io
188-
resources:
189-
- events
190-
verbs:
191-
- create
192-
- patch
193-
{{ if .Capabilities.APIVersions.Has "security.openshift.io/v1" }}
194-
- apiGroups:
195-
- security.openshift.io
196-
resources:
197-
- securitycontextconstraints
198-
resourceNames:
199-
- nonroot-v2
200-
verbs:
201-
- use
202-
{{ end }}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
---
2+
# Product ClusterRole: bound (via per AirflowCluster RoleBinding) to the ServiceAccount that Airflow
3+
# workload pods (webserver, scheduler, worker, triggerer, dag-processor) run as.
4+
apiVersion: rbac.authorization.k8s.io/v1
5+
kind: ClusterRole
6+
metadata:
7+
name: {{ include "operator.name" . }}-clusterrole
8+
labels:
9+
{{- include "operator.labels" . | nindent 4 }}
10+
rules:
11+
# KubernetesExecutor: the Airflow scheduler creates, monitors, and cleans up task pods directly
12+
- apiGroups:
13+
- ""
14+
resources:
15+
- pods
16+
verbs:
17+
- create
18+
- delete
19+
- get
20+
- list
21+
- patch
22+
- update
23+
- watch
24+
# KubernetesExecutor: the scheduler reads task pod logs for display in the Airflow UI
25+
- apiGroups:
26+
- ""
27+
resources:
28+
- pods/log
29+
verbs:
30+
- get
31+
# Airflow components publish Kubernetes events
32+
- apiGroups:
33+
- events.k8s.io
34+
resources:
35+
- events
36+
verbs:
37+
- create
38+
- patch
39+
{{ if .Capabilities.APIVersions.Has "security.openshift.io/v1" }}
40+
# On OpenShift: allows workload pods to use the nonroot-v2 SecurityContextConstraint
41+
- apiGroups:
42+
- security.openshift.io
43+
resources:
44+
- securitycontextconstraints
45+
resourceNames:
46+
- nonroot-v2
47+
verbs:
48+
- use
49+
{{ end }}

0 commit comments

Comments
 (0)