This is an automated email from the ASF dual-hosted git repository.
ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/v3-1-test by this push:
new 2663f982cce [v3-1-test] Add secret masking for Jinja template
rendering exceptions (#57467) (#57962)
2663f982cce is described below
commit 2663f982ccee5d9dbfcc624231c09839a2b07d6d
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Mon Nov 10 13:29:19 2025 +0100
[v3-1-test] Add secret masking for Jinja template rendering exceptions
(#57467) (#57962)
(cherry picked from commit afa5bff62a77f217aeebdf492b6745e36bc5b6ad)
Co-authored-by: Ankit Chaurasia <[email protected]>
---
.../sdk/definitions/_internal/abstractoperator.py | 7 ++++--
task-sdk/tests/task_sdk/bases/test_operator.py | 25 ++++++++++++++++++++++
2 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/task-sdk/src/airflow/sdk/definitions/_internal/abstractoperator.py
b/task-sdk/src/airflow/sdk/definitions/_internal/abstractoperator.py
index 2189c14ad79..65e8f1c4d92 100644
--- a/task-sdk/src/airflow/sdk/definitions/_internal/abstractoperator.py
+++ b/task-sdk/src/airflow/sdk/definitions/_internal/abstractoperator.py
@@ -304,12 +304,15 @@ class AbstractOperator(Templater, DAGNode):
else:
rendered_content = self.render_template(value, context,
jinja_env, seen_oids)
except Exception:
- # TODO: Mask the value. Depends on
https://github.com/apache/airflow/issues/45438
+ # Mask sensitive values in the template before logging
+ from airflow.sdk._shared.secrets_masker import redact
+
+ masked_value = redact(value)
log.exception(
"Exception rendering Jinja template for task '%s', field
'%s'. Template: %r",
self.task_id,
attr_name,
- value,
+ masked_value,
)
raise
else:
diff --git a/task-sdk/tests/task_sdk/bases/test_operator.py
b/task-sdk/tests/task_sdk/bases/test_operator.py
index 683bca1d574..c49b9db9650 100644
--- a/task-sdk/tests/task_sdk/bases/test_operator.py
+++ b/task-sdk/tests/task_sdk/bases/test_operator.py
@@ -30,6 +30,7 @@ import pytest
import structlog
from airflow.sdk import task as task_decorator
+from airflow.sdk._shared.secrets_masker import _secrets_masker, mask_secret
from airflow.sdk.bases.operator import (
BaseOperator,
BaseOperatorMeta,
@@ -918,6 +919,30 @@ def test_render_template_fields_logging(
assert not_expected_log not in caplog.text
[email protected]_redact
+def test_render_template_fields_secret_masking(caplog):
+ """Test that sensitive values are masked in Jinja template rendering
exceptions."""
+ masker = _secrets_masker()
+ masker.reset_masker()
+
+ masker.sensitive_variables_fields = ["password", "secret", "token"]
+
+ mask_secret("mysecretpassword", "password")
+
+ task = MockOperator(task_id="op1", arg1="{{ password + 1 }}")
+ context = {"password": "mysecretpassword"}
+
+ with (
+ pytest.raises(TypeError),
+ caplog.at_level(logging.ERROR,
logger="airflow.sdk.definitions.templater"),
+ ):
+ task.render_template_fields(context=context)
+
+ assert "mysecretpassword" not in caplog.text
+ assert "Template: '{{ password + 1 }}'" in caplog.text
+ assert "Exception rendering Jinja template for task 'op1', field 'arg1'"
in caplog.text
+
+
class HelloWorldOperator(BaseOperator):
log = structlog.get_logger(__name__)