This is an automated email from the ASF dual-hosted git repository. rahulvats pushed a commit to branch backport-62964 in repository https://gitbox.apache.org/repos/asf/airflow.git
commit d336be196efeca92cb97c18003689e7596d09807 Author: Pineapple <[email protected]> AuthorDate: Sat Mar 7 05:33:35 2026 +0530 fix: Exclude JWT token from workload repr to prevent log exposure (#62964) Closes: #62428 Closes: #62773 (cherry picked from commit b196cf3d1c5ed20667f39742cd4f8151b18123c9) --- airflow-core/newsfragments/62964.bugfix.rst | 1 + airflow-core/src/airflow/executors/workloads.py | 2 +- .../tests/unit/executors/test_workloads.py | 53 ++++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/airflow-core/newsfragments/62964.bugfix.rst b/airflow-core/newsfragments/62964.bugfix.rst new file mode 100644 index 00000000000..048ba18893b --- /dev/null +++ b/airflow-core/newsfragments/62964.bugfix.rst @@ -0,0 +1 @@ +Prevent JWT tokens from appearing in task logs by excluding the token field from workload object representations. diff --git a/airflow-core/src/airflow/executors/workloads.py b/airflow-core/src/airflow/executors/workloads.py index 43a4aab1dbc..bafb429dcc1 100644 --- a/airflow-core/src/airflow/executors/workloads.py +++ b/airflow-core/src/airflow/executors/workloads.py @@ -40,7 +40,7 @@ log = structlog.get_logger(__name__) class BaseWorkload(BaseModel): - token: str + token: str = Field(repr=False) """The identity token for this workload""" diff --git a/airflow-core/tests/unit/executors/test_workloads.py b/airflow-core/tests/unit/executors/test_workloads.py new file mode 100644 index 00000000000..507204d41dc --- /dev/null +++ b/airflow-core/tests/unit/executors/test_workloads.py @@ -0,0 +1,53 @@ +# 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. +from __future__ import annotations + +from pathlib import PurePosixPath +from uuid import uuid4 + +from airflow.executors.workloads import BundleInfo, ExecuteTask, TaskInstance + + +def test_token_excluded_from_workload_repr(): + """Ensure JWT tokens do not leak into log output via repr().""" + fake_token = "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.secret_payload.signature" + ti = TaskInstance( + id=uuid4(), + dag_version_id=uuid4(), + task_id="test_task", + dag_id="test_dag", + run_id="test_run", + try_number=1, + map_index=-1, + pool_slots=1, + queue="default", + priority_weight=1, + ) + workload = ExecuteTask( + ti=ti, + dag_rel_path=PurePosixPath("test_dag.py"), + token=fake_token, + bundle_info=BundleInfo(name="dags-folder", version=None), + log_path="test.log", + ) + + workload_repr = repr(workload) + + # Token MUST NOT appear in repr (prevents leaking into logs) + assert fake_token not in workload_repr, f"JWT token leaked into repr! Found token in: {workload_repr}" + # But token should still be accessible as an attribute + assert workload.token == fake_token
