diff --git a/litellm/proxy/common_utils/openai_endpoint_utils.py b/litellm/proxy/common_utils/openai_endpoint_utils.py index bedaf31e75..7b1a2945ba 100644 --- a/litellm/proxy/common_utils/openai_endpoint_utils.py +++ b/litellm/proxy/common_utils/openai_endpoint_utils.py @@ -2,7 +2,7 @@ Contains utils used by OpenAI compatible endpoints """ -from typing import Optional, Set +from typing import Optional from fastapi import Request @@ -12,16 +12,12 @@ from litellm.proxy.common_utils.http_parsing_utils import _read_request_body SENSITIVE_DATA_MASKER = SensitiveDataMasker() -def remove_sensitive_info_from_deployment( - deployment_dict: dict, - excluded_keys: Optional[Set[str]] = None, -) -> dict: +def remove_sensitive_info_from_deployment(deployment_dict: dict) -> dict: """ Removes sensitive information from a deployment dictionary. Args: deployment_dict (dict): The deployment dictionary to remove sensitive information from. - excluded_keys (Optional[Set[str]]): Set of keys that should not be masked (exact match). Returns: dict: The modified deployment dictionary with sensitive information removed. @@ -32,9 +28,7 @@ def remove_sensitive_info_from_deployment( deployment_dict["litellm_params"].pop("aws_access_key_id", None) deployment_dict["litellm_params"].pop("aws_secret_access_key", None) - deployment_dict["litellm_params"] = SENSITIVE_DATA_MASKER.mask_dict( - deployment_dict["litellm_params"], excluded_keys=excluded_keys - ) + deployment_dict["litellm_params"] = SENSITIVE_DATA_MASKER.mask_dict(deployment_dict["litellm_params"]) return deployment_dict diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index 91353e0162..9c98ad215b 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -7069,9 +7069,7 @@ async def model_info_v2( _model["model_info"] = model_info # don't return the api key / vertex credentials # don't return the llm credentials - _model = remove_sensitive_info_from_deployment( - _model, excluded_keys={"litellm_credential_name"} - ) + _model = remove_sensitive_info_from_deployment(_model) verbose_proxy_logger.debug("all_models: %s", all_models) return {"data": all_models} @@ -7538,9 +7536,7 @@ def _get_proxy_model_info(model: dict) -> dict: model_info[k] = v model["model_info"] = model_info # don't return the llm credentials - model = remove_sensitive_info_from_deployment( - deployment_dict=model, excluded_keys={"litellm_credential_name"} - ) + model = remove_sensitive_info_from_deployment(deployment_dict=model) return model @@ -7608,8 +7604,7 @@ async def model_info_v1( # noqa: PLR0915 ) _deployment_info_dict = _deployment_info.model_dump() _deployment_info_dict = remove_sensitive_info_from_deployment( - deployment_dict=_deployment_info_dict, - excluded_keys={"litellm_credential_name"}, + deployment_dict=_deployment_info_dict ) return {"data": _deployment_info_dict} diff --git a/tests/test_litellm/litellm_core_utils/test_sensitive_data_masker.py b/tests/test_litellm/litellm_core_utils/test_sensitive_data_masker.py index 2836398228..6356c5137b 100644 --- a/tests/test_litellm/litellm_core_utils/test_sensitive_data_masker.py +++ b/tests/test_litellm/litellm_core_utils/test_sensitive_data_masker.py @@ -29,49 +29,3 @@ def test_lists_are_preserved_not_converted_to_strings(): # Must be a list, not a string assert isinstance(masked["tags"], list) assert masked["tags"] == ["East US 2", "production", "test"] - - -def test_excluded_keys_exact_match(): - """ - Test that excluded_keys prevents masking of specific keys (exact match). - """ - masker = SensitiveDataMasker() - - data = { - "api_key": "sk-1234567890abcdef", - "litellm_credentials_name": "my-credential-name", - "access_token": "token-12345", - "port": 6379, - } - - # Without excluded_keys, sensitive keys should be masked - masked = masker.mask_dict(data) - assert masked["api_key"] != "sk-1234567890abcdef" - assert "*" in masked["api_key"] - assert masked["access_token"] != "token-12345" - assert "*" in masked["access_token"] - - # With excluded_keys, litellm_credentials_name should NOT be masked (exact match) - # This ensures that even if pattern matching logic changes, excluded keys won't be masked - masked = masker.mask_dict(data, excluded_keys={"litellm_credentials_name"}) - assert masked["litellm_credentials_name"] == "my-credential-name" - - # Other sensitive keys should still be masked - assert masked["api_key"] != "sk-1234567890abcdef" - assert "*" in masked["api_key"] - assert masked["access_token"] != "token-12345" - assert "*" in masked["access_token"] - - # Non-sensitive keys should remain unchanged - assert masked["port"] == 6379 - - # Test case sensitivity - excluded_keys should be exact match - masked = masker.mask_dict(data, excluded_keys={"LITELLM_CREDENTIALS_NAME"}) - # Should still be masked because case doesn't match (exact match required) - assert masked["litellm_credentials_name"] == "my-credential-name" # Not masked because it doesn't match patterns anyway - - # Test with api_key in excluded_keys to verify it works for keys that would be masked - masked = masker.mask_dict(data, excluded_keys={"api_key"}) - assert masked["api_key"] == "sk-1234567890abcdef" # Should NOT be masked - assert masked["access_token"] != "token-12345" # Should still be masked - assert "*" in masked["access_token"] diff --git a/tests/test_litellm/proxy/common_utils/test_openai_endpoint_utils.py b/tests/test_litellm/proxy/common_utils/test_openai_endpoint_utils.py index a7ce39c2e3..a5094c94bd 100644 --- a/tests/test_litellm/proxy/common_utils/test_openai_endpoint_utils.py +++ b/tests/test_litellm/proxy/common_utils/test_openai_endpoint_utils.py @@ -85,37 +85,3 @@ from litellm.proxy.common_utils.openai_endpoint_utils import remove_sensitive_in def test_remove_sensitive_info_from_deployment(model_config: dict, expected_config: dict): sanitized_config = remove_sensitive_info_from_deployment(model_config) assert sanitized_config == expected_config - - -def test_remove_sensitive_info_from_deployment_with_excluded_keys(): - """ - Test that excluded_keys prevents masking of specific keys (exact match). - """ - model_config = { - "model_name": "test-model", - "litellm_params": { - "model": "openai/gpt-4", - "api_key": "sk-sensitive-key-123", - "litellm_credentials_name": "my-credential-name", - "access_token": "token-12345", - "temperature": 0.7 - } - } - - # Without excluded_keys, access_token should be masked (contains "token") - sanitized_config = remove_sensitive_info_from_deployment(model_config) - assert sanitized_config["litellm_params"]["access_token"] != "token-12345" - assert "*" in sanitized_config["litellm_params"]["access_token"] - - # With excluded_keys, litellm_credentials_name should NOT be masked (even if it would match patterns) - sanitized_config = remove_sensitive_info_from_deployment( - model_config, excluded_keys={"litellm_credentials_name"} - ) - assert sanitized_config["litellm_params"]["litellm_credentials_name"] == "my-credential-name" - - # access_token should still be masked (not in excluded_keys) - assert sanitized_config["litellm_params"]["access_token"] != "token-12345" - assert "*" in sanitized_config["litellm_params"]["access_token"] - - # api_key should still be removed (popped) regardless of excluded_keys - assert "api_key" not in sanitized_config["litellm_params"]