diff --git a/litellm/integrations/otel/model/metadata.py b/litellm/integrations/otel/model/metadata.py index 28d6ad54607..71a0f6e938f 100644 --- a/litellm/integrations/otel/model/metadata.py +++ b/litellm/integrations/otel/model/metadata.py @@ -152,8 +152,9 @@ class RequestIdentity: ) if (value := get(attr)) ) + key_meta: Final = flatten_metadata({"user_api_key_auth_metadata": get("metadata")}) request_meta: Final = flatten_metadata(request_metadata) if request_metadata is not None else () - metadata: Final = MappingProxyType(dict((*request_meta, *auth_meta))) + metadata: Final = MappingProxyType(dict((*request_meta, *auth_meta, *key_meta))) return cls( team_id=as_str(get("team_id")), team_alias=as_str(get("team_alias")), diff --git a/tests/unit/integrations/otel/test_otel_v2_sources_of_truth.py b/tests/unit/integrations/otel/test_otel_v2_sources_of_truth.py index c29da4607eb..23c918a4bbc 100644 --- a/tests/unit/integrations/otel/test_otel_v2_sources_of_truth.py +++ b/tests/unit/integrations/otel/test_otel_v2_sources_of_truth.py @@ -1641,6 +1641,32 @@ def test_request_identity_from_user_api_key_auth(): assert ident.metadata["user_api_key_end_user_id"] == "eu9" +def test_virtual_key_metadata_reaches_baggage_only_for_allowlisted_sub_keys(): + from litellm.integrations.otel.model.baggage import DEFAULT_BAGGAGE_METADATA_KEYS, promoted_baggage + from litellm.integrations.otel.model.payloads import RequestIdentity + from litellm.proxy._types import UserAPIKeyAuth + + auth: Final = UserAPIKeyAuth( + key_alias="cost-key", + metadata={"team": "a", "cost": {"center": "cc-42"}, "owner": "not-allowlisted"}, + ) + identity: Final = RequestIdentity.from_user_api_key_auth(auth) + + allowlisted: Final = promoted_baggage( + identity, + None, + promoted_keys=(), + metadata_keys=("user_api_key_auth_metadata.team", "user_api_key_auth_metadata.cost.center"), + ) + default: Final = promoted_baggage(identity, None, promoted_keys=(), metadata_keys=DEFAULT_BAGGAGE_METADATA_KEYS) + + assert allowlisted == { + "litellm.metadata.user_api_key_auth_metadata.team": "a", + "litellm.metadata.user_api_key_auth_metadata.cost.center": "cc-42", + } + assert default == {"litellm.metadata.user_api_key_alias": "cost-key"} + + # --- request-metadata translation layer (RequestContext) -------------------- #