Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
58231a2
Add api secret_key for 3.0+ instead of webserver secret_key
albundy83 Jun 25, 2025
4ef7550
Some tests
albundy83 Jun 25, 2025
9f0c911
Add AIRFLOW__API__SECRET_KEY in enableBuiltInSecretEnvVars for tests
albundy83 Jun 26, 2025
b4e1bb6
Merge branch 'main' into api_secret_key
albundy83 Jun 26, 2025
87765a8
Merge branch 'apache:main' into api_secret_key
albundy83 Jun 26, 2025
b9d49ab
Merge branch 'main' into api_secret_key
albundy83 Jun 26, 2025
9bd6168
Merge branch 'main' into api_secret_key
albundy83 Jun 26, 2025
4295c7f
Merge branch 'main' into api_secret_key
albundy83 Jun 26, 2025
40b681d
Precise airflow version
albundy83 Jun 26, 2025
19e2761
Merge branch 'main' into api_secret_key
albundy83 Jun 26, 2025
0870adf
Merge branch 'main' into api_secret_key
albundy83 Jun 26, 2025
0ffea1d
Fix component name
albundy83 Jun 26, 2025
67bcc91
Simple condition
albundy83 Jun 26, 2025
14f816b
Merge branch 'main' into api_secret_key
albundy83 Jun 27, 2025
5ee0392
Fix b64enc encoded twice
albundy83 Jun 27, 2025
d37e174
Merge branch 'main' into api_secret_key
albundy83 Jun 30, 2025
0005c3b
Fix for tests template "api_secret_key_secret" not defined
albundy83 Jun 30, 2025
628fa5a
Merge branch 'main' into api_secret_key
albundy83 Jun 30, 2025
a36495b
Fix for webserver when airflow is 3+
albundy83 Jun 30, 2025
b16d0c8
Add test for api-secret-key
albundy83 Jun 30, 2025
ac541f6
Merge branch 'main' into api_secret_key
albundy83 Jun 30, 2025
cbb25fb
Split webserver api Secret
albundy83 Jun 30, 2025
6b5f8cc
Merge branch 'main' into api_secret_key
albundy83 Jun 30, 2025
a50a6a1
Merge branch 'main' into api_secret_key
albundy83 Jun 30, 2025
624eb26
Merge branch 'main' into api_secret_key
albundy83 Jun 30, 2025
774c660
Merge branch 'main' into api_secret_key
albundy83 Jun 30, 2025
f2ea098
Merge branch 'main' into api_secret_key
albundy83 Jul 1, 2025
54f5b7d
Merge branch 'main' into api_secret_key
albundy83 Jul 1, 2025
021f085
Merge branch 'main' into api_secret_key
albundy83 Jul 1, 2025
f542119
Merge branch 'main' into api_secret_key
albundy83 Jul 2, 2025
56567c1
Merge branch 'main' into api_secret_key
albundy83 Jul 2, 2025
eced084
Merge branch 'main' into api_secret_key
albundy83 Jul 2, 2025
dc91b1d
Tests basic helm fixed, airflow name was missing
albundy83 Jul 2, 2025
2e20cd7
Fix for test airflow_common
albundy83 Jul 2, 2025
ba006de
Merge branch 'main' into api_secret_key
albundy83 Jul 2, 2025
b28d662
Merge branch 'main' into api_secret_key
albundy83 Jul 2, 2025
f4ad45b
Fixed tests for rbac security
albundy83 Jul 2, 2025
5eab381
Merge branch 'apache:main' into api_secret_key
albundy83 Jul 2, 2025
867ec75
Merge branch 'main' into api_secret_key
albundy83 Jul 2, 2025
8cc458e
Merge branch 'main' into api_secret_key
albundy83 Jul 2, 2025
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
13 changes: 12 additions & 1 deletion chart/templates/_helpers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,20 @@ If release name contains chart name it will be used as a full name.
name: {{ template "airflow_metadata_secret" . }}
key: kedaConnection
{{- end }}
{{- if .Values.enableBuiltInSecretEnvVars.AIRFLOW__WEBSERVER__SECRET_KEY }}
{{- if and (semverCompare "<3.0.0" .Values.airflowVersion) .Values.enableBuiltInSecretEnvVars.AIRFLOW__WEBSERVER__SECRET_KEY }}
- name: AIRFLOW__WEBSERVER__SECRET_KEY
valueFrom:
secretKeyRef:
name: {{ template "webserver_secret_key_secret" . }}
key: webserver-secret-key
{{- end }}
{{- if and (semverCompare ">=3.0.0" .Values.airflowVersion) .Values.enableBuiltInSecretEnvVars.AIRFLOW__API__SECRET_KEY }}
- name: AIRFLOW__API__SECRET_KEY
valueFrom:
secretKeyRef:
name: {{ template "api_secret_key_secret" . }}
key: api-secret-key
{{- end }}
{{- if and (semverCompare ">=3.0.0" .Values.airflowVersion) .Values.enableBuiltInSecretEnvVars.AIRFLOW__API_AUTH__JWT_SECRET }}
- name: AIRFLOW__API_AUTH__JWT_SECRET
valueFrom:
Expand Down Expand Up @@ -411,6 +418,10 @@ If release name contains chart name it will be used as a full name.
{{- default (printf "%s-webserver-secret-key" (include "airflow.fullname" .)) .Values.webserverSecretKeySecretName }}
{{- end }}

{{- define "api_secret_key_secret" -}}
{{- default (printf "%s-api-secret-key" (include "airflow.fullname" .)) .Values.apiSecretKeySecretName }}
{{- end }}

{{- define "redis_password_secret" -}}
{{- default (printf "%s-redis-password" .Release.Name) .Values.redis.passwordSecretName }}
{{- end }}
Expand Down
44 changes: 44 additions & 0 deletions chart/templates/secrets/api-secret-key-secret.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{{/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/}}

############################################
## Airflow Api Flask Secret Key Secret
############################################
{{- if and (semverCompare ">=3.0.0" .Values.airflowVersion) (not .Values.apiSecretKeySecretName) }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "airflow.fullname" . }}-api-secret-key
labels:
tier: airflow
component: api-server
release: {{ .Release.Name }}
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
heritage: {{ .Release.Service }}
{{- with .Values.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.apiSecretAnnotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
type: Opaque
data:
api-secret-key: {{ (.Values.apiSecretKey) | default (randAlphaNum 32) | b64enc | quote }}
{{- end }}
3 changes: 1 addition & 2 deletions chart/templates/secrets/fernetkey-secret.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
## Airflow Fernet Key Secret
#################################
{{- if not .Values.fernetKeySecretName }}
{{- $generated_fernet_key := (randAlphaNum 32 | b64enc) }}
apiVersion: v1
kind: Secret
metadata:
Expand All @@ -43,5 +42,5 @@ metadata:
{{- end }}
type: Opaque
data:
fernet-key: {{ (default $generated_fernet_key .Values.fernetKey) | b64enc | quote }}
fernet-key: {{ (.Values.fernetKey) | default (randAlphaNum 32) | b64enc | quote }}
{{- end }}
5 changes: 2 additions & 3 deletions chart/templates/secrets/webserver-secret-key-secret.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@
############################################
## Airflow Webserver Flask Secret Key Secret
############################################
{{- if not .Values.webserverSecretKeySecretName }}
{{ $generated_secret_key := (randAlphaNum 32 | b64enc) }}
{{- if and (semverCompare "<3.0.0" .Values.airflowVersion) .Values.webserver.enabled (not .Values.webserverSecretKeySecretName) }}
apiVersion: v1
kind: Secret
metadata:
Expand All @@ -41,5 +40,5 @@ metadata:
{{- end }}
type: Opaque
data:
webserver-secret-key: {{ (default $generated_secret_key .Values.webserverSecretKey) | b64enc | quote }}
webserver-secret-key: {{ (.Values.webserverSecretKey) | default (randAlphaNum 32) | b64enc | quote }}
{{- end }}
32 changes: 32 additions & 0 deletions chart/values.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1064,6 +1064,11 @@
"type": "boolean",
"default": true
},
"AIRFLOW__API__SECRET_KEY": {
"description": "Enable ``AIRFLOW__API__SECRET_KEY`` variable to be read from the Api Secret Key Secret",
"type": "boolean",
"default": true
},
"AIRFLOW__API_AUTH__JWT_SECRET": {
"description": "Enable ``AIRFLOW__API_AUTH__JWT_SECRET`` variable to be read from the JWT Secret",
"type": "boolean",
Expand Down Expand Up @@ -1464,6 +1469,33 @@
"type": "string"
}
},
"apiSecretKey": {
"description": "The Flask secret key for Airflow Api to encrypt browser session.",
"type": [
"string",
"null"
],
"x-docsSection": "Common",
"default": null
},
"apiSecretAnnotations": {
"description": "Annotations to add to the Api secret.",
"type": "object",
"x-docsSection": "Common",
"default": {},
"additionalProperties": {
"type": "string"
}
},
"apiSecretKeySecretName": {
"description": "The Secret name containing Flask secret_key for the Api.",
"type": [
"string",
"null"
],
"x-docsSection": "Airflow",
"default": null
},
"jwtSecret": {
"description": "Secret key used to encode and decode JWTs to authenticate to public and private APIs (can only be set during install, not upgrade).",
"type": [
Expand Down
17 changes: 12 additions & 5 deletions chart/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@ enableBuiltInSecretEnvVars:
AIRFLOW__CORE__SQL_ALCHEMY_CONN: true
AIRFLOW__DATABASE__SQL_ALCHEMY_CONN: true
AIRFLOW_CONN_AIRFLOW_DB: true
AIRFLOW__API__SECRET_KEY: true
AIRFLOW__API_AUTH__JWT_SECRET: true
AIRFLOW__WEBSERVER__SECRET_KEY: true
AIRFLOW__CELERY__CELERY_RESULT_BACKEND: true
Expand Down Expand Up @@ -551,18 +552,24 @@ fernetKeySecretName: ~
# Add custom annotations to the fernet key secret
fernetKeySecretAnnotations: {}

# Flask secret key for Airflow Webserver: `[webserver] secret_key` in airflow.cfg
webserverSecretKey: ~
# Add custom annotations to the webserver secret
webserverSecretAnnotations: {}
webserverSecretKeySecretName: ~
# Flask secret key for Airflow 3+ Api: `[api] secret_key` in airflow.cfg
apiSecretKey: ~
# Add custom annotations to the api secret
apiSecretAnnotations: {}
apiSecretKeySecretName: ~

# Secret key used to encode and decode JWTs: `[api_auth] jwt_secret` in airflow.cfg
jwtSecret: ~
# Add custom annotations to the JWT secret
jwtSecretAnnotations: {}
jwtSecretName: ~

# Flask secret key for Airflow <3 Webserver: `[webserver] secret_key` in airflow.cfg
webserverSecretKey: ~
# Add custom annotations to the webserver secret
webserverSecretAnnotations: {}
webserverSecretKeySecretName: ~

# In order to use kerberos you need to create secret containing the keytab file
# The secret name should follow naming convention of the application where resources are
# name {{ .Release-name }}-<POSTFIX>. In case of the keytab file, the postfix is "kerberos-keytab"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ def test_should_disable_some_variables(self):
"enableBuiltInSecretEnvVars": {
"AIRFLOW__CORE__SQL_ALCHEMY_CONN": False,
"AIRFLOW__DATABASE__SQL_ALCHEMY_CONN": False,
"AIRFLOW__API__SECRET_KEY": False,
"AIRFLOW__API_AUTH__JWT_SECRET": False,
"AIRFLOW__WEBSERVER__SECRET_KEY": False,
# the following vars only appear if remote logging is set, so disabling them in this test is kind of a no-op
Expand Down Expand Up @@ -370,7 +371,7 @@ def test_have_all_variables(self):
"AIRFLOW__CORE__SQL_ALCHEMY_CONN",
"AIRFLOW__DATABASE__SQL_ALCHEMY_CONN",
"AIRFLOW_CONN_AIRFLOW_DB",
"AIRFLOW__WEBSERVER__SECRET_KEY",
"AIRFLOW__API__SECRET_KEY",
"AIRFLOW__API_AUTH__JWT_SECRET",
"AIRFLOW__CELERY__BROKER_URL",
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
("Secret", "test-basic-airflow-metadata"),
("Secret", "test-basic-broker-url"),
("Secret", "test-basic-fernet-key"),
("Secret", "test-basic-airflow-webserver-secret-key"),
("Secret", "test-basic-redis-password"),
("Secret", "test-basic-postgresql"),
("ConfigMap", "test-basic-airflow-config"),
Expand Down Expand Up @@ -71,6 +70,7 @@
("Deployment", "test-basic-airflow-dag-processor"),
("ServiceAccount", "test-basic-airflow-api-server"),
("ServiceAccount", "test-basic-airflow-dag-processor"),
("Secret", "test-basic-airflow-api-secret-key"),
("Secret", "test-basic-jwt-secret"),
}
)
Expand All @@ -82,6 +82,7 @@
("Service", "test-basic-airflow-webserver"),
("Deployment", "test-basic-airflow-webserver"),
("ServiceAccount", "test-basic-airflow-webserver"),
("Secret", "test-basic-airflow-webserver-secret-key"),
}
)

Expand Down Expand Up @@ -137,7 +138,6 @@ def test_basic_deployments(self, version):
("Secret", "test-basic-metadata"),
("Secret", "test-basic-broker-url"),
("Secret", "test-basic-fernet-key"),
("Secret", "test-basic-webserver-secret-key"),
("Secret", "test-basic-postgresql"),
("Secret", "test-basic-redis-password"),
("ConfigMap", "test-basic-config"),
Expand Down Expand Up @@ -171,6 +171,7 @@ def test_basic_deployments(self, version):
("ServiceAccount", "test-basic-api-server"),
("ServiceAccount", "test-basic-dag-processor"),
("Service", "test-basic-triggerer"),
("Secret", "test-basic-api-secret-key"),
("Secret", "test-basic-jwt-secret"),
)
)
Expand All @@ -180,6 +181,7 @@ def test_basic_deployments(self, version):
("Deployment", "test-basic-webserver"),
("Service", "test-basic-webserver"),
("ServiceAccount", "test-basic-webserver"),
("Secret", "test-basic-webserver-secret-key"),
)
)
if version == "default":
Expand Down Expand Up @@ -238,7 +240,6 @@ def test_basic_deployment_with_standalone_dag_processor(self, version):
("Secret", "test-basic-metadata"),
("Secret", "test-basic-broker-url"),
("Secret", "test-basic-fernet-key"),
("Secret", "test-basic-webserver-secret-key"),
("Secret", "test-basic-postgresql"),
("Secret", "test-basic-redis-password"),
("ConfigMap", "test-basic-config"),
Expand Down Expand Up @@ -271,6 +272,7 @@ def test_basic_deployment_with_standalone_dag_processor(self, version):
("Deployment", "test-basic-api-server"),
("Service", "test-basic-api-server"),
("ServiceAccount", "test-basic-api-server"),
("Secret", "test-basic-api-secret-key"),
("Secret", "test-basic-jwt-secret"),
}
)
Expand All @@ -280,6 +282,7 @@ def test_basic_deployment_with_standalone_dag_processor(self, version):
("Service", "test-basic-webserver"),
("Deployment", "test-basic-webserver"),
("ServiceAccount", "test-basic-webserver"),
("Secret", "test-basic-webserver-secret-key"),
}
)
assert list_of_kind_names_tuples == expected
Expand Down Expand Up @@ -447,7 +450,6 @@ def test_labels_are_valid(self, airflow_version):
(f"{release_name}-statsd", "Deployment", "statsd"),
(f"{release_name}-statsd", "Service", "statsd"),
(f"{release_name}-statsd-policy", "NetworkPolicy", "statsd-policy"),
(f"{release_name}-webserver-secret-key", "Secret", "webserver"),
(f"{release_name}-worker", "Service", "worker"),
(f"{release_name}-worker", "StatefulSet", "worker"),
(f"{release_name}-worker-policy", "NetworkPolicy", "airflow-worker-policy"),
Expand All @@ -460,14 +462,17 @@ def test_labels_are_valid(self, airflow_version):
if self._is_airflow_3_or_above(airflow_version):
kind_names_tuples += [
(f"{release_name}-api-server", "Service", "api-server"),
(f"{release_name}-api-server-policy", "NetworkPolicy", "airflow-api-server-policy"),
(f"{release_name}-api-server", "Deployment", "api-server"),
(f"{release_name}-airflow-api-server", "ServiceAccount", "api-server"),
(f"{release_name}-api-secret-key", "Secret", "api-server"),
(f"{release_name}-api-server-policy", "NetworkPolicy", "airflow-api-server-policy"),
]
else:
kind_names_tuples += [
(f"{release_name}-airflow-webserver", "ServiceAccount", "webserver"),
(f"{release_name}-webserver", "Deployment", "webserver"),
(f"{release_name}-webserver", "Service", "webserver"),
(f"{release_name}-webserver-secret-key", "Secret", "webserver"),
(f"{release_name}-webserver-policy", "NetworkPolicy", "airflow-webserver-policy"),
(f"{release_name}-ingress", "Ingress", "airflow-ingress"),
]
Expand Down
16 changes: 16 additions & 0 deletions helm-tests/tests/helm_tests/apiserver/test_apiserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,19 @@ def test_should_add_annotations_to_jwt_secret(self):

assert "annotations" in jmespath.search("metadata", docs)
assert jmespath.search("metadata.annotations", docs)["test_annotation"] == "test_annotation_value"


class TestApiSecretKeySecret:
"""Tests api secret key secret."""

def test_should_add_annotations_to_api_secret_key_secret(self):
docs = render_chart(
values={
"airflowVersion": "3.0.0",
"apiSecretAnnotations": {"test_annotation": "test_annotation_value"},
},
show_only=["templates/secrets/api-secret-key-secret.yaml"],
)[0]

assert "annotations" in jmespath.search("metadata", docs)
assert jmespath.search("metadata.annotations", docs)["test_annotation"] == "test_annotation_value"
3 changes: 2 additions & 1 deletion helm-tests/tests/helm_tests/security/test_rbac.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
("Secret", "test-rbac-broker-url"),
("Secret", "test-rbac-fernet-key"),
("Secret", "test-rbac-redis-password"),
("Secret", "test-rbac-webserver-secret-key"),
("Job", "test-rbac-create-user"),
("Job", "test-rbac-run-airflow-migrations"),
("CronJob", "test-rbac-cleanup"),
Expand Down Expand Up @@ -121,6 +120,7 @@ def _get_object_tuples(self, version, sa: bool = True):
("Service", "test-rbac-api-server"),
("Deployment", "test-rbac-api-server"),
("Deployment", "test-rbac-dag-processor"),
("Secret", "test-rbac-api-secret-key"),
("Secret", "test-rbac-jwt-secret"),
)
)
Expand All @@ -132,6 +132,7 @@ def _get_object_tuples(self, version, sa: bool = True):
(
("Service", "test-rbac-webserver"),
("Deployment", "test-rbac-webserver"),
("Secret", "test-rbac-webserver-secret-key"),
)
)
if sa:
Expand Down
1 change: 1 addition & 0 deletions helm-tests/tests/helm_tests/webserver/test_webserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -1258,6 +1258,7 @@ class TestWebserverSecretKeySecret:
def test_should_add_annotations_to_webserver_secret_key_secret(self):
docs = render_chart(
values={
"airflowVersion": "2.10.5",
"webserverSecretAnnotations": {"test_annotation": "test_annotation_value"},
},
show_only=["templates/secrets/webserver-secret-key-secret.yaml"],
Expand Down