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 @@ -2,6 +2,12 @@

## [Unreleased]

### Changed

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

- [#767]: https://github.com/stackabletech/airflow-operator/pull/767

## [26.3.0] - 2026-03-16

## [26.3.0-rc1] - 2026-03-16
Expand Down
62 changes: 38 additions & 24 deletions deploy/helm/airflow-operator/templates/roles.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ metadata:
labels:
{{- include "operator.labels" . | nindent 4 }}
rules:
# For automatic cluster domain detection
- apiGroups:
- ""
resources:
Expand All @@ -20,23 +21,32 @@ rules:
- 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). Resources watched by the controller also need watch.
# - configmaps: role group configuration (webserver_config.py, log config, vector config)
# and KubernetesExecutor pod template; also watched for OPA discovery ConfigMap changes
# - secrets: auto-generated internal secret, JWT secret, and Fernet key (get for existence
# check, create + patch for initial creation via SSA, list + delete for orphan cleanup)
# - services: headless service (StatefulSet DNS) and metrics service (Prometheus) per role
# group; also watched via .owns() to re-reconcile on external changes
# - serviceaccounts: per-cluster ServiceAccount for workload pods
- apiGroups:
- ""
resources:
- pods
- configmaps
- secrets
- services
- endpoints
- serviceaccounts
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
# Per-cluster RoleBinding binding the workload ServiceAccount to the airflow-clusterrole.
# Applied via SSA (create + patch), tracked for orphan cleanup (list + delete).
- apiGroups:
- rbac.authorization.k8s.io
resources:
Expand All @@ -47,32 +57,22 @@ rules:
- get
- list
- patch
- update
- watch
# StatefulSets for each role group (webserver, scheduler, worker, triggerer, dag-processor).
# Applied via SSA (create + patch), tracked for orphan cleanup (list + delete).
# Also watched via .owns() to re-reconcile on external changes.
- 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 per role to protect against simultaneous pod evictions.
# Applied via SSA (create + patch), tracked for orphan cleanup (list + delete).
- apiGroups:
- policy
resources:
Expand All @@ -83,8 +83,6 @@ rules:
- get
- list
- patch
- update
- watch
- apiGroups:
- apiextensions.k8s.io
resources:
Expand All @@ -100,32 +98,38 @@ rules:
- list
- watch
{{- end }}
# Listener for the Webserver role to expose HTTP access via a configurable ListenerClass.
# Applied via SSA (create + patch), tracked for orphan cleanup (list + delete).
- apiGroups:
- listeners.stackable.tech
resources:
- listeners
verbs:
- create
- delete
- get
- list
- watch
- patch
- create
- delete
# Primary reconciliation target: the controller watches AirflowCluster resources (list + watch)
# and reads them during reconciliation (get).
- apiGroups:
- {{ include "operator.name" . }}.stackable.tech
resources:
- {{ include "operator.name" . }}clusters
verbs:
- get
- list
- patch
- watch
# Write reconciliation status conditions back to AirflowCluster objects
- apiGroups:
- {{ include "operator.name" . }}.stackable.tech
resources:
- {{ include "operator.name" . }}clusters/status
verbs:
- patch
# Resolve LDAP and OIDC authentication provider configuration.
# Watched (list + watch) to re-reconcile when an AuthenticationClass changes,
# and fetched individually (get) during reconciliation via resolve_class().
- apiGroups:
- authentication.stackable.tech
resources:
Expand All @@ -134,13 +138,16 @@ rules:
- get
- list
- watch
# Publish Kubernetes events for reconciliation activity
- apiGroups:
- events.k8s.io
resources:
- events
verbs:
- create
- patch
# Allows the operator to create RoleBindings that reference the airflow-clusterrole
# (the product ClusterRole bound to workload pods, defined below)
- apiGroups:
- rbac.authorization.k8s.io
resources:
Expand All @@ -150,13 +157,16 @@ rules:
resourceNames:
- {{ include "operator.name" . }}-clusterrole
---
# Product ClusterRole: bound (via per-cluster RoleBinding) to the ServiceAccount that Airflow
# workload pods (webserver, scheduler, worker, triggerer, dag-processor) run as.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ include "operator.name" . }}-clusterrole
labels:
{{- include "operator.labels" . | nindent 4 }}
rules:
# Airflow pods read their own configuration, credentials, and service account token
- apiGroups:
- ""
resources:
Expand All @@ -165,6 +175,7 @@ rules:
- serviceaccounts
verbs:
- get
# KubernetesExecutor: the Airflow scheduler creates, monitors, and cleans up task pods directly
- apiGroups:
- ""
resources:
Expand All @@ -177,12 +188,14 @@ rules:
- patch
- update
- watch
# KubernetesExecutor: the scheduler reads task pod logs for display in the Airflow UI
- apiGroups:
- ""
resources:
- pods/log
verbs:
- get
# Airflow components publish Kubernetes events
- apiGroups:
- events.k8s.io
resources:
Expand All @@ -191,6 +204,7 @@ rules:
- create
- patch
{{ if .Capabilities.APIVersions.Has "security.openshift.io/v1" }}
# On OpenShift: allows workload pods to use the nonroot-v2 SecurityContextConstraint
- apiGroups:
- security.openshift.io
resources:
Expand Down
Loading