From 99cc933405e86f10d07963d743d60fd72dbce49e Mon Sep 17 00:00:00 2001 From: Aarkin7 Date: Mon, 29 Jun 2026 18:20:17 +0530 Subject: [PATCH 1/3] fix: redact token from TokenSecret repr to prevent API key leaks in logs and tracebacks --- haystack/utils/auth.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/haystack/utils/auth.py b/haystack/utils/auth.py index 774492c521c..5682f3559fe 100644 --- a/haystack/utils/auth.py +++ b/haystack/utils/auth.py @@ -162,6 +162,10 @@ def _from_dict(_: dict[str, Any]) -> "Secret": "Cannot deserialize token-based secret. Use an alternative secret type like environment variables." ) + def __repr__(self) -> str: + # Hide the token so it can't leak through print/log/traceback formatting. + return f"TokenSecret(_token=, _type={self._type!r})" + def resolve_value(self) -> Any | None: """Return the token.""" return self._token From 4b58c7aa0f08f6345658684416476e6a7f4fa913 Mon Sep 17 00:00:00 2001 From: Aarkin7 Date: Mon, 29 Jun 2026 18:20:40 +0530 Subject: [PATCH 2/3] test: assert TokenSecret repr and str never expose the raw token --- test/utils/test_auth.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/utils/test_auth.py b/test/utils/test_auth.py index a7b40424ffe..0d7fd36188f 100644 --- a/test/utils/test_auth.py +++ b/test/utils/test_auth.py @@ -36,6 +36,11 @@ def test_token_secret(): with pytest.raises(FrozenInstanceError): secret._type = SecretType.ENV_VAR + secret = Secret.from_token("sk-supersecret-1234567890ABCDEF") + assert "sk-supersecret-1234567890ABCDEF" not in repr(secret) + assert "sk-supersecret-1234567890ABCDEF" not in str(secret) + assert "" in repr(secret) + def test_env_var_secret(): secret = Secret.from_env_var("TEST_ENV_VAR1") From f2543c90540fa080338910e54d3a94657f3bbf0b Mon Sep 17 00:00:00 2001 From: Aarkin7 Date: Mon, 29 Jun 2026 18:20:53 +0530 Subject: [PATCH 3/3] docs: add release note for TokenSecret repr redaction --- .../notes/redact-tokensecret-repr-34c7549247f4b6e4.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 releasenotes/notes/redact-tokensecret-repr-34c7549247f4b6e4.yaml diff --git a/releasenotes/notes/redact-tokensecret-repr-34c7549247f4b6e4.yaml b/releasenotes/notes/redact-tokensecret-repr-34c7549247f4b6e4.yaml new file mode 100644 index 00000000000..50914758978 --- /dev/null +++ b/releasenotes/notes/redact-tokensecret-repr-34c7549247f4b6e4.yaml @@ -0,0 +1,8 @@ +--- +security: + - | + The ``repr()`` of a ``Secret`` built via ``Secret.from_token(...)`` no longer + includes the raw token. Previously the dataclass-generated repr printed the + token verbatim, so any path that formats a component's locals — exception + tracebacks, ``print()``, Jupyter echo, log aggregators — could leak the API + key. The token is now rendered as ````.