From 35c6a768c0cdce2a618c9579c3215279b7d6c8cd Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 3 Sep 2026 15:42:55 +0000 Subject: [PATCH] fix(spend-tracking): keep internal service-account key names readable in spend logs Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .../spend_tracking/spend_tracking_utils.py | 13 ++++-- .../test_spend_tracking_utils.py | 43 +++++++++++++++++++ 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/litellm/proxy/spend_tracking/spend_tracking_utils.py b/litellm/proxy/spend_tracking/spend_tracking_utils.py index 7442d71bd96..a1f0dbfcefe 100644 --- a/litellm/proxy/spend_tracking/spend_tracking_utils.py +++ b/litellm/proxy/spend_tracking/spend_tracking_utils.py @@ -14,6 +14,8 @@ from litellm.constants import ( LITELLM_PROXY_MASTER_KEY_ALIAS, LITELLM_TRUNCATED_PAYLOAD_FIELD, LITELLM_TRUNCATION_DB_SAFEGUARD_NOTE, + LITTELM_CLI_SERVICE_ACCOUNT_NAME, + LITTELM_INTERNAL_HEALTH_SERVICE_ACCOUNT_NAME, REDACTED_BY_LITELM_STRING, ) from litellm.constants import ( @@ -72,13 +74,18 @@ def _is_master_key(api_key: str | None, _master_key: str | None) -> bool: _HASHED_JWT_RE = re.compile(r"hashed-jwt-[a-fA-F0-9]{64}") +_NON_SECRET_KEY_ALIASES: Final = frozenset( + { + LITELLM_PROXY_MASTER_KEY_ALIAS, + LITTELM_INTERNAL_HEALTH_SERVICE_ACCOUNT_NAME, + LITTELM_CLI_SERVICE_ACCOUNT_NAME, + } +) def _is_non_secret_key_value(value: str) -> bool: return ( - value == LITELLM_PROXY_MASTER_KEY_ALIAS - or is_valid_sha256_hash(value) - or _HASHED_JWT_RE.fullmatch(value) is not None + value in _NON_SECRET_KEY_ALIASES or is_valid_sha256_hash(value) or _HASHED_JWT_RE.fullmatch(value) is not None ) diff --git a/tests/test_litellm/proxy/spend_tracking/test_spend_tracking_utils.py b/tests/test_litellm/proxy/spend_tracking/test_spend_tracking_utils.py index 9e5917637a8..f2164547a6f 100644 --- a/tests/test_litellm/proxy/spend_tracking/test_spend_tracking_utils.py +++ b/tests/test_litellm/proxy/spend_tracking/test_spend_tracking_utils.py @@ -13,9 +13,13 @@ import litellm from litellm.constants import ( LITELLM_TRUNCATED_PAYLOAD_FIELD, LITELLM_TRUNCATION_DB_SAFEGUARD_NOTE, + LITTELM_CLI_SERVICE_ACCOUNT_NAME, + LITTELM_INTERNAL_HEALTH_SERVICE_ACCOUNT_NAME, REDACTED_BY_LITELM_STRING, ) from litellm.litellm_core_utils.safe_json_dumps import safe_dumps +from litellm.proxy._types import UserAPIKeyAuth +from litellm.proxy.litellm_pre_call_utils import LiteLLMProxyRequestSetup from litellm.proxy.spend_tracking.spend_tracking_utils import ( _get_messages_for_spend_logs_payload, _get_proxy_server_request_for_spend_logs_payload, @@ -3044,6 +3048,45 @@ def test_get_logging_payload_keeps_master_key_alias_readable(): assert parsed_meta["user_api_key"] == LITELLM_PROXY_MASTER_KEY_ALIAS +@pytest.mark.parametrize( + "service_account", + [LITTELM_INTERNAL_HEALTH_SERVICE_ACCOUNT_NAME, LITTELM_CLI_SERVICE_ACCOUNT_NAME], +) +def test_get_logging_payload_keeps_internal_service_account_key_readable(service_account: str): + data = LiteLLMProxyRequestSetup.add_user_api_key_auth_to_request_metadata( + data={"metadata": {}}, + user_api_key_dict=UserAPIKeyAuth( + api_key=service_account, + team_id=service_account, + key_alias=service_account, + team_alias=service_account, + ), + _metadata_variable_name="metadata", + ) + kwargs = { + "model": "openai/gpt-4.1", + "messages": [{"role": "user", "content": "Hello"}], + "call_type": "acompletion", + "litellm_params": {"metadata": data["metadata"]}, + } + payload = get_logging_payload( + kwargs=kwargs, + response_obj=Exception("error"), + start_time=datetime.datetime.now(timezone.utc), + end_time=datetime.datetime.now(timezone.utc), + ) + + assert payload["api_key"] == service_account + parsed_meta = json.loads(payload["metadata"]) + assert parsed_meta["user_api_key"] == service_account + assert parsed_meta["user_api_key_alias"] == service_account + + +def test_redact_logged_api_key_service_account_name_without_provenance_is_hashed(): + result = _redact_logged_api_key(LITTELM_INTERNAL_HEALTH_SERVICE_ACCOUNT_NAME) + assert result == hash_token(LITTELM_INTERNAL_HEALTH_SERVICE_ACCOUNT_NAME) + + @patch("litellm.proxy.proxy_server.master_key", None) @patch("litellm.proxy.proxy_server.general_settings", {}) def test_get_logging_payload_hashes_bearer_prefixed_api_key():