fix(health): drop a stored-credential reference along with the credentials it names

A connection test that redirects the destination already leaves the configured
credentials behind. It kept litellm_credential_name, which names the same stored
secrets and is resolved further down the call, so the reference is now dropped
with them. A request that sets no connection fields of its own is unaffected,
which is how the Admin UI tests a configured model.

(cherry picked from commit 298fb8ce56)
This commit is contained in:
Yuneng Jiang 2026-08-05 16:07:04 -07:00
parent 2d88b52da6
commit d5efca5baf
No known key found for this signature in database
2 changed files with 29 additions and 1 deletions

View file

@ -98,7 +98,11 @@ def _reject_os_environ_references(params: dict) -> None:
_CONFIG_CONNECTION_FIELDS: Final[frozenset[str]] = frozenset(
(*_ADMIN_CONFIG_FIELDS_TO_CLEAR_ON_BASE_OVERRIDE, *clientside_credential_keys)
(
*_ADMIN_CONFIG_FIELDS_TO_CLEAR_ON_BASE_OVERRIDE,
*clientside_credential_keys,
"litellm_credential_name",
)
)
@ -115,6 +119,11 @@ def _config_base_for_health_check(
still comes from the configuration, which is what lets a request name a
configured model and test it as configured.
``litellm_credential_name`` is dropped alongside the literal credential
fields: it names a stored credential that ``load_credentials_from_list``
resolves into the same secrets further down the call, so leaving it in place
would reintroduce them by reference.
``general_settings.allow_client_side_credentials`` is the existing proxy-wide
opt-in for callers supplying their own connection parameters. Where an admin
has enabled it, a request may pair its own endpoint with the configured

View file

@ -2438,3 +2438,22 @@ class TestConfigBaseForHealthCheck:
allow_client_side_credentials=True,
)
assert base["api_key"] == "sk-configured"
def test_stored_credential_reference_is_dropped_with_the_credentials(self):
"""A stored-credential name resolves to the same secrets downstream, so a
request that redirects the destination must not keep it either."""
config = {**self.CONFIG, "litellm_credential_name": "OpenAI-prod"}
base = self._base(config, {"api_base": "https://caller.example/v1"})
assert "litellm_credential_name" not in base
assert "api_key" not in base
def test_stored_credential_reference_kept_when_request_sets_no_connection(self):
"""The Admin UI tests a configured model by naming it plus its stored
credential and nothing else; that keeps working."""
config = {**self.CONFIG, "litellm_credential_name": "OpenAI-prod"}
base = self._base(
config,
{"model": "openai/gpt-4o", "litellm_credential_name": "OpenAI-prod", "custom_llm_provider": "openai"},
)
assert base["litellm_credential_name"] == "OpenAI-prod"
assert base["api_key"] == "sk-configured"