From 3cc4091730b95e5625bb042fb0af672ff8ba4df1 Mon Sep 17 00:00:00 2001 From: 72004 Date: Sat, 10 Oct 2026 18:59:14 +0500 Subject: [PATCH] fix(otel): honor redact_user_api_key_info for span metadata and team attributes When litellm.redact_user_api_key_info is True, OTEL spans still emitted metadata.user_api_key_* attributes (hash, user id, email, team id) and stamped team_id/team_alias onto every child span. Filter span metadata through redact_user_api_key_info and skip team attributes when the flag is set. Fixes #36758 --- litellm/integrations/opentelemetry.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/litellm/integrations/opentelemetry.py b/litellm/integrations/opentelemetry.py index 90383ddb60d..be4a6742f05 100644 --- a/litellm/integrations/opentelemetry.py +++ b/litellm/integrations/opentelemetry.py @@ -1516,6 +1516,8 @@ class OpenTelemetry(OTELGenAISemconvMixin, CustomLogger): in ``standard_logging_object.metadata``; propagating that to every span only adds noise that makes traces look mis-instrumented. """ + if litellm.redact_user_api_key_info is True: + return if team_id: self.safe_set_attribute( span=span, @@ -2411,7 +2413,9 @@ class OpenTelemetry(OTELGenAISemconvMixin, CustomLogger): ############################################# ############ LLM CALL METADATA ############## ############################################# - metadata: Final = standard_logging_payload["metadata"] + from litellm.litellm_core_utils.redact_messages import redact_user_api_key_info + + metadata: Final = redact_user_api_key_info(metadata=dict(standard_logging_payload["metadata"])) for key, value in metadata.items(): self.safe_set_attribute(span=span, key=f"metadata.{key}", value=value) decision: Final = metadata.get("routing_decision")