Skip to content
Merged
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
1 change: 1 addition & 0 deletions airflow-core/newsfragments/73793.improvement.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Mask registered secrets at any nesting depth. Secret values registered with the masker are now replaced wherever they appear in a nested structure, instead of only up to the masker's maximum depth.
Original file line number Diff line number Diff line change
Expand Up @@ -356,10 +356,12 @@ def _redact(
self, item: Redactable, name: str | None, depth: int, max_depth: int, replacement: str = "***"
) -> Redacted:
try:
# Key-name-based redaction is unbounded by depth — sensitive keys
# must fail closed at any nesting level. The depth cutoff below is
# only used to bound the work of pattern-based string masking and
# to terminate recursion through self-referential iterables.
# Both key-name-based and pattern-based redaction apply at any
# nesting depth: a registered secret or a sensitive key must fail
# closed wherever it sits in the structure. ``max_depth`` only bounds
# the fail-closed walk of a value already known to be sensitive
# (``_redact_all``); self-referential structures are stopped by
# Python's recursion limit and the except clause below.
if name and self.should_hide_value_for_key(name):
return self._redact_all(item, depth, max_depth, replacement=replacement)
# Always walk dicts so deeper sensitive keys are still caught;
Expand Down Expand Up @@ -395,11 +397,6 @@ def _redact(
)
for subval in item
]
# The depth cutoff only bounds the work of pattern-based string
# masking below — key-name redaction (dicts and iterables above) is
# unbounded so sensitive keys fail closed at any depth.
if depth > max_depth:
return item
if isinstance(item, Enum):
return self._redact(
item=item.value, name=name, depth=depth, max_depth=max_depth, replacement=replacement
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -675,9 +675,14 @@ def test_redact_filehandles(self, caplog):
(["abcdef"], ["***"], 1),
([[[["abcdef"]]]], [[[["***"]]]], None),
([[[[["abcdef"]]]]], [[[[["***"]]]]], None),
# Items below max depth aren't redacted
([[[[[["abcdef"]]]]]], [[[[[["abcdef"]]]]]], None),
([["abcdef"]], [["abcdef"]], 1),
# Registered secrets are redacted at any depth, whatever max_depth says
([[[[[["abcdef"]]]]]], [[[[[["***"]]]]]], None),
([["abcdef"]], [["***"]], 1),
(
{"a": {"b": {"c": {"d": {"e": {"f": {"g": "prefix-abcdef-suffix"}}}}}}},
{"a": {"b": {"c": {"d": {"e": {"f": {"g": "prefix-***-suffix"}}}}}}},
None,
),
],
)
def test_redact_max_depth(self, val, expected, max_depth):
Expand Down