Passthrough Auth - make Auth checks OSS + Anthropic - only show 'reasoning_effort' for supported models (#12847)

* fix(anthropic/chat/transformation.py): move 'reasoning_effort' to inside 'supports_reasoning' check

Fixes https://github.com/BerriAI/litellm/issues/12833

* fix(proxy_settings_endpoints.py): change order of checks - don't add allowed ip unless db is connected

Fixes https://github.com/BerriAI/litellm/issues/12815

* feat(user_api_key_auth.py): make passthrough auth checks OSS

Fixes https://github.com/BerriAI/litellm/issues/12789

* docs(enterprise.md): clarify on docs
This commit is contained in:
Krish Dholakia
2025-07-21 21:55:41 -07:00
committed by GitHub
parent 49d40a1c3d
commit 70ffdcd210
6 changed files with 14 additions and 74 deletions
-1
View File
@@ -21,7 +21,6 @@ Features:
- ✅ [[BETA] AWS Key Manager v2 - Key Decryption](#beta-aws-key-manager---key-decryption)
- ✅ IP addressbased access control lists
- ✅ Track Request IP Address
- ✅ [Use LiteLLM keys/authentication on Pass Through Endpoints](pass_through#✨-enterprise---use-litellm-keysauthentication-on-pass-through-endpoints)
- ✅ [Set Max Request Size / File Size on Requests](#set-max-request--response-size-on-litellm-proxy)
- ✅ [Enforce Required Params for LLM Requests (ex. Reject requests missing ["metadata"]["generation_name"])](#enforce-required-params-for-llm-requests)
- ✅ [Key Rotations](./virtual_keys.md#-key-rotations)
@@ -154,35 +154,6 @@ general_settings:
---
## ✨ Enterprise Features
### Authentication & Rate Limiting
Enable LiteLLM authentication and rate limiting on pass through endpoints:
```yaml
general_settings:
master_key: sk-1234
pass_through_endpoints:
- path: "/v1/rerank"
target: "https://api.cohere.com/v1/rerank"
auth: true # Enable LiteLLM auth
headers:
Authorization: "bearer os.environ/COHERE_API_KEY"
content-type: application/json
```
**Test with LiteLLM key:**
```shell
curl --request POST \
--url http://localhost:4000/v1/rerank \
--header 'Authorization: Bearer sk-1234' \
--header 'content-type: application/json' \
--data '{"model": "rerank-english-v3.0", "query": "test"}'
```
---
## Configuration Reference
### Complete Specification
@@ -127,7 +127,6 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig):
"parallel_tool_calls",
"response_format",
"user",
"reasoning_effort",
"web_search_options",
]
@@ -136,6 +135,7 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig):
custom_llm_provider=self.custom_llm_provider,
):
params.append("thinking")
params.append("reasoning_effort")
return params
+10 -33
View File
@@ -456,31 +456,6 @@ def is_pass_through_provider_route(route: str) -> bool:
return False
def should_run_auth_on_pass_through_provider_route(route: str) -> bool:
"""
Use this to decide if the rest of the LiteLLM Virtual Key auth checks should run on /vertex-ai/{endpoint} routes
Use this to decide if the rest of the LiteLLM Virtual Key auth checks should run on provider pass through routes
ex /vertex-ai/{endpoint} routes
Run virtual key auth if the following is try:
- User is premium_user
- User has enabled litellm_setting.use_client_credentials_pass_through_routes
"""
from litellm.proxy.proxy_server import general_settings, premium_user
if premium_user is not True:
return False
# premium use has opted into using client credentials
if (
general_settings.get("use_client_credentials_pass_through_routes", False)
is True
):
return False
# only enabled for LiteLLM Enterprise
return True
def _has_user_setup_sso():
"""
Check if the user has set up single sign-on (SSO) by verifying the presence of Microsoft client ID, Google client ID or generic client ID and UI username environment variables.
@@ -499,7 +474,9 @@ def _has_user_setup_sso():
return sso_setup
def get_end_user_id_from_request_body(request_body: dict, request_headers: Optional[dict] = None) -> Optional[str]:
def get_end_user_id_from_request_body(
request_body: dict, request_headers: Optional[dict] = None
) -> Optional[str]:
# Import general_settings here to avoid potential circular import issues at module level
# and to ensure it's fetched at runtime.
from litellm.proxy.proxy_server import general_settings
@@ -508,10 +485,10 @@ def get_end_user_id_from_request_body(request_body: dict, request_headers: Optio
# User query: "system not respecting user_header_name property"
# This implies the key in general_settings is 'user_header_name'.
if request_headers is not None:
user_id_header_config_key = "user_header_name"
custom_header_name_to_check = general_settings.get(user_id_header_config_key)
user_id_header_config_key = "user_header_name"
custom_header_name_to_check = general_settings.get(user_id_header_config_key)
if custom_header_name_to_check and isinstance(custom_header_name_to_check, str):
user_id_from_header = request_headers.get(custom_header_name_to_check)
if user_id_from_header is not None and user_id_from_header.strip():
@@ -530,12 +507,12 @@ def get_end_user_id_from_request_body(request_body: dict, request_headers: Optio
return str(user_from_litellm_metadata)
# Check 4: 'metadata.user_id' in request_body (another common pattern)
metadata_dict = request_body.get("metadata")
if isinstance(metadata_dict, dict):
metadata_dict = request_body.get("metadata")
if isinstance(metadata_dict, dict):
user_id_from_metadata_field = metadata_dict.get("user_id")
if user_id_from_metadata_field is not None:
return str(user_id_from_metadata_field)
return None
-7
View File
@@ -43,10 +43,8 @@ from litellm.proxy.auth.auth_utils import (
get_end_user_id_from_request_body,
get_model_from_request,
get_request_route,
is_pass_through_provider_route,
pre_db_read_auth_checks,
route_in_additonal_public_routes,
should_run_auth_on_pass_through_provider_route,
)
from litellm.proxy.auth.handle_jwt import JWTAuthManager, JWTHandler
from litellm.proxy.auth.oauth2_check import check_oauth2_token
@@ -440,11 +438,6 @@ async def _user_api_key_auth_builder( # noqa: PLR0915
):
# check if public endpoint
return UserAPIKeyAuth(user_role=LitellmUserRoles.INTERNAL_USER_VIEW_ONLY)
elif is_pass_through_provider_route(route=route):
if should_run_auth_on_pass_through_provider_route(route=route) is False:
return UserAPIKeyAuth(
user_role=LitellmUserRoles.INTERNAL_USER_VIEW_ONLY
)
########## End of Route Checks Before Reading DB / Cache for "token" ########
@@ -73,6 +73,9 @@ async def add_allowed_ip(ip_address: IPAddress):
store_model_in_db,
)
if prisma_client is None:
raise Exception("No DB Connected")
_allowed_ips: List = general_settings.get("allowed_ips", [])
if ip_address.ip not in _allowed_ips:
_allowed_ips.append(ip_address.ip)
@@ -80,9 +83,6 @@ async def add_allowed_ip(ip_address: IPAddress):
else:
raise HTTPException(status_code=400, detail="IP address already exists")
if prisma_client is None:
raise Exception("No DB Connected")
if store_model_in_db is not True:
raise HTTPException(
status_code=500,