Merge pull request #26513 from BerriAI/litellm_/intelligent-maxwell-35e39d

[Fix] Harden /model/info redaction for plural credential field names
This commit is contained in:
yuneng-jiang
2026-04-25 14:02:31 -07:00
committed by GitHub
4 changed files with 13 additions and 8 deletions
@@ -21,6 +21,7 @@ class SensitiveDataMasker:
"auth",
"authorization",
"credential",
"credentials",
"access",
"private",
"certificate",
@@ -29,6 +29,7 @@ def remove_sensitive_info_from_deployment(
deployment_dict["litellm_params"].pop("api_key", None)
deployment_dict["litellm_params"].pop("client_secret", None)
deployment_dict["litellm_params"].pop("vertex_credentials", None)
deployment_dict["litellm_params"].pop("vertex_ai_credentials", None)
deployment_dict["litellm_params"].pop("aws_access_key_id", None)
deployment_dict["litellm_params"].pop("aws_secret_access_key", None)
@@ -65,12 +65,13 @@ def test_excluded_keys_exact_match():
# Non-sensitive keys should remain unchanged
assert masked["port"] == 6379
# Test case sensitivity - excluded_keys should be exact match
# Test case sensitivity - excluded_keys should be exact match. Supplying an
# uppercase variant must NOT exclude the lowercase key, so the field falls
# back to pattern matching ("credentials" is in the sensitive pattern set)
# and is masked.
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
assert masked["litellm_credentials_name"] != "my-credential-name"
assert "*" in masked["litellm_credentials_name"]
# 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"})
@@ -1,3 +1,5 @@
import copy
import pytest
from litellm.proxy.common_utils.openai_endpoint_utils import (
@@ -86,7 +88,7 @@ def test_remove_sensitive_info_from_deployment_with_excluded_keys():
"""
Test that excluded_keys prevents masking of specific keys (exact match).
"""
model_config = {
base_config = {
"model_name": "test-model",
"litellm_params": {
"model": "openai/gpt-4",
@@ -98,13 +100,13 @@ def test_remove_sensitive_info_from_deployment_with_excluded_keys():
}
# Without excluded_keys, access_token should be masked (contains "token")
sanitized_config = remove_sensitive_info_from_deployment(model_config)
sanitized_config = remove_sensitive_info_from_deployment(copy.deepcopy(base_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"}
copy.deepcopy(base_config), excluded_keys={"litellm_credentials_name"}
)
assert (
sanitized_config["litellm_params"]["litellm_credentials_name"]