mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-14 23:21:35 +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.
(cherry picked from commit e5effcb861)
This commit is contained in:
parent
dde20e405c
commit
2653829374
2 changed files with 66 additions and 2 deletions
|
|
@ -6,7 +6,17 @@ import secrets
|
|||
import time
|
||||
import traceback
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Any, Dict, Iterable, Literal, Optional, TypedDict, Union, cast
|
||||
from typing import (
|
||||
Any,
|
||||
Dict,
|
||||
Iterable,
|
||||
Literal,
|
||||
Mapping,
|
||||
Optional,
|
||||
TypedDict,
|
||||
Union,
|
||||
cast,
|
||||
)
|
||||
|
||||
import fastapi
|
||||
from fastapi import APIRouter, Depends, HTTPException, Request, Response, status
|
||||
|
|
@ -28,6 +38,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 (
|
||||
|
|
@ -79,6 +92,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.
|
||||
|
|
@ -1860,7 +1894,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
|
||||
|
|
@ -1875,6 +1908,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