This is an automated email from the ASF dual-hosted git repository.

jedcunningham pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new 4f314d0304b Generate JWT secret during HELM install (#49923)
4f314d0304b is described below

commit 4f314d0304b88dfee7a2d1eed77e4c76a4b036e8
Author: Dov Benyomin Sohacheski <[email protected]>
AuthorDate: Fri Jun 13 23:19:14 2025 +0300

    Generate JWT secret during HELM install (#49923)
---
 chart/templates/_helpers.yaml                      | 11 ++++++
 chart/templates/secrets/jwt-secret.yaml            | 45 ++++++++++++++++++++++
 chart/values.schema.json                           | 23 +++++++++++
 chart/values.yaml                                  |  5 +++
 .../helm_tests/airflow_aux/test_airflow_common.py  |  2 +
 .../airflow_aux/test_basic_helm_chart.py           |  3 ++
 helm-tests/tests/helm_tests/security/test_rbac.py  |  1 +
 7 files changed, 90 insertions(+)

diff --git a/chart/templates/_helpers.yaml b/chart/templates/_helpers.yaml
index ac2798d0604..da417a59d4c 100644
--- a/chart/templates/_helpers.yaml
+++ b/chart/templates/_helpers.yaml
@@ -98,6 +98,13 @@ If release name contains chart name it will be used as a 
full name.
         name: {{ template "webserver_secret_key_secret" . }}
         key: webserver-secret-key
   {{- end }}
+  {{- if .Values.enableBuiltInSecretEnvVars.AIRFLOW__API_AUTH__JWT_SECRET }}
+  - name: AIRFLOW__API_AUTH__JWT_SECRET
+    valueFrom:
+      secretKeyRef:
+        name: {{ template "jwt_secret" . }}
+        key: jwt-secret
+  {{- end }}
   {{- if or (contains "CeleryExecutor" .Values.executor) (contains 
"CeleryKubernetesExecutor" .Values.executor) }}
     {{- if or (semverCompare "<2.4.0" .Values.airflowVersion) 
(.Values.data.resultBackendSecretName) (.Values.data.resultBackendConnection) }}
     {{- if 
.Values.enableBuiltInSecretEnvVars.AIRFLOW__CELERY__CELERY_RESULT_BACKEND }}
@@ -396,6 +403,10 @@ If release name contains chart name it will be used as a 
full name.
   {{- default (printf "%s-fernet-key" .Release.Name) 
.Values.fernetKeySecretName }}
 {{- end }}
 
+{{- define "jwt_secret" -}}
+  {{- default (printf "%s-jwt-secret" .Release.Name) .Values.jwtSecretName }}
+{{- end }}
+
 {{- define "webserver_secret_key_secret" -}}
   {{- default (printf "%s-webserver-secret-key" (include "airflow.fullname" 
.)) .Values.webserverSecretKeySecretName }}
 {{- end }}
diff --git a/chart/templates/secrets/jwt-secret.yaml 
b/chart/templates/secrets/jwt-secret.yaml
new file mode 100644
index 00000000000..a097a55d556
--- /dev/null
+++ b/chart/templates/secrets/jwt-secret.yaml
@@ -0,0 +1,45 @@
+{{/*
+ 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 JWT Secret
+############################################
+{{- if not .Values.jwtSecretName }}
+{{ $generated_secret_key := (randAlphaNum 32 | b64enc) }}
+apiVersion: v1
+kind: Secret
+metadata:
+  name: {{ include "airflow.fullname" . }}-jwt-secret
+  labels:
+    tier: airflow
+    component: api-server
+    release: {{ .Release.Name }}
+    chart: {{ .Chart.Name }}
+    heritage: {{ .Release.Service }}
+    {{- with .Values.labels }}
+      {{- toYaml . | nindent 4 }}
+    {{- end }}
+  annotations:
+    "helm.sh/hook": "pre-install"
+    "helm.sh/hook-delete-policy": "before-hook-creation"
+    "helm.sh/hook-weight": "0"
+type: Opaque
+data:
+  jwt-secret: {{ (default $generated_secret_key .Values.jwtSecret) | b64enc | 
quote }}
+{{- end }}
diff --git a/chart/values.schema.json b/chart/values.schema.json
index 1aaa2efc041..9636d3a07e5 100644
--- a/chart/values.schema.json
+++ b/chart/values.schema.json
@@ -1064,6 +1064,11 @@
                     "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",
+                    "default": true
+                },
                 "AIRFLOW__WEBSERVER__SECRET_KEY": {
                     "description": "Enable ``AIRFLOW__WEBSERVER__SECRET_KEY`` 
variable to be read from the Webserver Secret Key Secret",
                     "type": "boolean",
@@ -1459,6 +1464,24 @@
                 "type": "string"
             }
         },
+        "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": [
+                "string",
+                "null"
+            ],
+            "x-docsSection": "Common",
+            "default": null
+        },
+        "jwtSecretName": {
+            "description": "The JWT secret name.",
+            "type": [
+                "string",
+                "null"
+            ],
+            "x-docsSection": "Airflow",
+            "default": null
+        },
         "webserverSecretKey": {
             "description": "The Flask secret key for Airflow Webserver to 
encrypt browser session.",
             "type": [
diff --git a/chart/values.yaml b/chart/values.yaml
index 6a512d8fe4d..c777b03fdd3 100644
--- a/chart/values.yaml
+++ b/chart/values.yaml
@@ -407,6 +407,7 @@ enableBuiltInSecretEnvVars:
   AIRFLOW__CORE__SQL_ALCHEMY_CONN: true
   AIRFLOW__DATABASE__SQL_ALCHEMY_CONN: true
   AIRFLOW_CONN_AIRFLOW_DB: true
+  AIRFLOW__API_AUTH__JWT_SECRET: true
   AIRFLOW__WEBSERVER__SECRET_KEY: true
   AIRFLOW__CELERY__CELERY_RESULT_BACKEND: true
   AIRFLOW__CELERY__RESULT_BACKEND: true
@@ -556,6 +557,10 @@ webserverSecretKey: ~
 webserverSecretAnnotations: {}
 webserverSecretKeySecretName: ~
 
+# Secret key used to encode and decode JWTs: `[api_auth] jwt_secret` in 
airflow.cfg
+jwtSecret: ~
+jwtSecretName: ~
+
 # 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"
diff --git a/helm-tests/tests/helm_tests/airflow_aux/test_airflow_common.py 
b/helm-tests/tests/helm_tests/airflow_aux/test_airflow_common.py
index 78b43d02f73..e6b247afb1c 100644
--- a/helm-tests/tests/helm_tests/airflow_aux/test_airflow_common.py
+++ b/helm-tests/tests/helm_tests/airflow_aux/test_airflow_common.py
@@ -323,6 +323,7 @@ class TestAirflowCommon:
                 "enableBuiltInSecretEnvVars": {
                     "AIRFLOW__CORE__SQL_ALCHEMY_CONN": False,
                     "AIRFLOW__DATABASE__SQL_ALCHEMY_CONN": 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
                     "AIRFLOW__ELASTICSEARCH__HOST": False,
@@ -370,6 +371,7 @@ class TestAirflowCommon:
             "AIRFLOW__DATABASE__SQL_ALCHEMY_CONN",
             "AIRFLOW_CONN_AIRFLOW_DB",
             "AIRFLOW__WEBSERVER__SECRET_KEY",
+            "AIRFLOW__API_AUTH__JWT_SECRET",
             "AIRFLOW__CELERY__BROKER_URL",
         ]
         expected_vars_in_worker = ["DUMB_INIT_SETSID"] + expected_vars
diff --git a/helm-tests/tests/helm_tests/airflow_aux/test_basic_helm_chart.py 
b/helm-tests/tests/helm_tests/airflow_aux/test_basic_helm_chart.py
index 91829848f8e..d7977f7e528 100644
--- a/helm-tests/tests/helm_tests/airflow_aux/test_basic_helm_chart.py
+++ b/helm-tests/tests/helm_tests/airflow_aux/test_basic_helm_chart.py
@@ -38,6 +38,7 @@ OBJECTS_STD_NAMING = {
     ("Secret", "test-basic-airflow-metadata"),
     ("Secret", "test-basic-broker-url"),
     ("Secret", "test-basic-fernet-key"),
+    ("Secret", "test-basic-airflow-jwt-secret"),
     ("Secret", "test-basic-airflow-webserver-secret-key"),
     ("Secret", "test-basic-redis-password"),
     ("Secret", "test-basic-postgresql"),
@@ -136,6 +137,7 @@ class TestBaseChartTest:
             ("Secret", "test-basic-metadata"),
             ("Secret", "test-basic-broker-url"),
             ("Secret", "test-basic-fernet-key"),
+            ("Secret", "test-basic-jwt-secret"),
             ("Secret", "test-basic-webserver-secret-key"),
             ("Secret", "test-basic-postgresql"),
             ("Secret", "test-basic-redis-password"),
@@ -236,6 +238,7 @@ class TestBaseChartTest:
             ("Secret", "test-basic-metadata"),
             ("Secret", "test-basic-broker-url"),
             ("Secret", "test-basic-fernet-key"),
+            ("Secret", "test-basic-jwt-secret"),
             ("Secret", "test-basic-webserver-secret-key"),
             ("Secret", "test-basic-postgresql"),
             ("Secret", "test-basic-redis-password"),
diff --git a/helm-tests/tests/helm_tests/security/test_rbac.py 
b/helm-tests/tests/helm_tests/security/test_rbac.py
index 6271e7cfafc..fcd578daa60 100644
--- a/helm-tests/tests/helm_tests/security/test_rbac.py
+++ b/helm-tests/tests/helm_tests/security/test_rbac.py
@@ -46,6 +46,7 @@ DEPLOYMENT_NO_RBAC_NO_SA_KIND_NAME_TUPLES = [
     ("StatefulSet", "test-rbac-worker"),
     ("Secret", "test-rbac-broker-url"),
     ("Secret", "test-rbac-fernet-key"),
+    ("Secret", "test-rbac-jwt-secret"),
     ("Secret", "test-rbac-redis-password"),
     ("Secret", "test-rbac-webserver-secret-key"),
     ("Job", "test-rbac-create-user"),

Reply via email to