mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-08 03:08:45 +00:00
fix(health)!: let configured deployment parameters win over request overrides
When a connection test names a model that resolves to a configured deployment, that deployment's routing and credential parameters are authoritative. A request supplying a complete connection of its own is unaffected. BREAKING CHANGE: /health/test_connection no longer lets a request replace the routing or credential parameters of a configured model it names. Supply the full connection parameters instead of naming a configured model.
This commit is contained in:
parent
5b2c92d749
commit
e5effcb861
2 changed files with 56 additions and 2 deletions
|
|
@ -5,7 +5,7 @@ import os
|
|||
import secrets
|
||||
import time
|
||||
import traceback
|
||||
from collections.abc import Iterable
|
||||
from collections.abc import Iterable, Mapping
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Any, Final, Literal, TypedDict, cast
|
||||
|
||||
|
|
@ -29,6 +29,9 @@ from litellm.proxy._types import (
|
|||
UserAPIKeyAuth,
|
||||
WebhookEvent,
|
||||
)
|
||||
from litellm.proxy.auth.auth_utils import (
|
||||
_BANNED_REQUEST_BODY_PARAMS, # pyright: ignore[reportPrivateUsage] # one canonical list, shared with the request-body check
|
||||
)
|
||||
from litellm.proxy.auth.user_api_key_auth import user_api_key_auth
|
||||
from litellm.proxy.db.exception_handler import PrismaDBExceptionHandler
|
||||
from litellm.proxy.health_check import (
|
||||
|
|
@ -80,6 +83,27 @@ def _reject_os_environ_references(params: dict) -> None:
|
|||
stack.append(value)
|
||||
|
||||
|
||||
def _reject_banned_param_overrides(request_params: Mapping[str, object]) -> None:
|
||||
"""Reject request params that would replace a configured deployment's routing or credentials.
|
||||
|
||||
Applied only when a configured deployment supplies the base parameters. The
|
||||
request may still adjust benign fields; routing and credential fields come
|
||||
from the configuration. A caller who wants a fully custom connection supplies
|
||||
the complete parameter set instead of naming a configured model.
|
||||
"""
|
||||
for param in _BANNED_REQUEST_BODY_PARAMS:
|
||||
if param in request_params:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail={
|
||||
"error": (
|
||||
f"{param} cannot be overridden when testing a configured model. "
|
||||
"Provide the full connection parameters instead of naming a configured model."
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def get_callback_identifier(callback):
|
||||
"""
|
||||
Get the callback identifier string, handling both strings and objects.
|
||||
|
|
@ -1854,7 +1878,6 @@ async def test_model_connection(
|
|||
)
|
||||
|
||||
# Merge: config params (from proxy config) as base, request params override
|
||||
# This allows users to override specific params while using config for credentials
|
||||
litellm_params = {**config_litellm_params, **request_litellm_params}
|
||||
|
||||
## Auth check
|
||||
|
|
@ -1869,6 +1892,8 @@ async def test_model_connection(
|
|||
prisma_client=prisma_client,
|
||||
premium_user=premium_user,
|
||||
)
|
||||
if config_litellm_params:
|
||||
_reject_banned_param_overrides(request_litellm_params)
|
||||
# Include health_check_params if provided
|
||||
litellm_params = _update_litellm_params_for_health_check(
|
||||
model_info={},
|
||||
|
|
|
|||
|
|
@ -2364,3 +2364,32 @@ def test_clean_endpoint_data_strips_credentials_keeps_routing_fields():
|
|||
assert "aws_access_key_id" not in cleaned
|
||||
assert cleaned.get("api_base") == "https://example.test/v1"
|
||||
assert cleaned.get("api_version") == "2024-10-21"
|
||||
|
||||
|
||||
class TestRejectBannedParamOverrides:
|
||||
"""Routing and credential fields come from the deployment configuration when a
|
||||
request names a configured model; a request that wants its own connection
|
||||
supplies the whole parameter set instead."""
|
||||
|
||||
def test_banned_param_is_refused(self):
|
||||
from fastapi import HTTPException
|
||||
|
||||
from litellm.proxy.health_endpoints._health_endpoints import (
|
||||
_reject_banned_param_overrides,
|
||||
)
|
||||
|
||||
for param in ("api_base", "base_url", "vertex_credentials", "aws_web_identity_token"):
|
||||
with pytest.raises(HTTPException) as exc_info:
|
||||
_reject_banned_param_overrides({"model": "gpt-4o", param: "caller-supplied"})
|
||||
assert exc_info.value.status_code == 400
|
||||
assert param in str(exc_info.value.detail)
|
||||
|
||||
def test_benign_params_are_allowed(self):
|
||||
from litellm.proxy.health_endpoints._health_endpoints import (
|
||||
_reject_banned_param_overrides,
|
||||
)
|
||||
|
||||
_reject_banned_param_overrides({})
|
||||
_reject_banned_param_overrides({"model": "gpt-4o"})
|
||||
_reject_banned_param_overrides({"model": "gpt-4o", "api_key": "sk-caller-owned"})
|
||||
_reject_banned_param_overrides({"mode": "chat", "timeout": 30})
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue