mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-07 02:59:05 +00:00
fix: add headers to metadata for guardrails on pass-through endpoints (#17992)
Fixes #17477 Guardrails couldn't access request headers (like User-Agent) on Bedrock pass-through endpoints because headers were only stored in data["proxy_server_request"]["headers"] but not in data["metadata"]["headers"] where guardrails typically look for them. This fix adds headers to metadata in add_litellm_data_to_request() so guardrails can access User-Agent, API keys, and other header-based checks on all endpoints including Bedrock pass-through. Test added to verify headers are available in metadata for guardrails.
This commit is contained in:
parent
50606bf090
commit
09ba89d4fe
2 changed files with 75 additions and 0 deletions
|
|
@ -843,6 +843,11 @@ async def add_litellm_data_to_request( # noqa: PLR0915
|
|||
)
|
||||
)
|
||||
|
||||
# Add headers to metadata for guardrails to access (fixes #17477)
|
||||
# Guardrails use metadata["headers"] to access request headers (e.g., User-Agent)
|
||||
if _metadata_variable_name in data and isinstance(data[_metadata_variable_name], dict):
|
||||
data[_metadata_variable_name]["headers"] = _headers
|
||||
|
||||
# check for forwardable headers
|
||||
data = LiteLLMProxyRequestSetup.add_headers_to_llm_call_by_model_group(
|
||||
data=data, headers=_headers, user_api_key_dict=user_api_key_dict
|
||||
|
|
|
|||
|
|
@ -1884,3 +1884,73 @@ async def test_bedrock_router_passthrough_metadata_initialization():
|
|||
|
||||
# Verify response was returned
|
||||
assert result == mock_response
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_add_litellm_data_to_request_adds_headers_to_metadata():
|
||||
"""
|
||||
Test that add_litellm_data_to_request adds headers to metadata for guardrails.
|
||||
|
||||
This test verifies the fix for issue #17477 where guardrails couldn't access
|
||||
request headers (like User-Agent) on Bedrock pass-through endpoints.
|
||||
|
||||
The fix ensures headers are available in data["metadata"]["headers"] so
|
||||
guardrails can validate User-Agent, API keys, and other header-based checks.
|
||||
"""
|
||||
from litellm.proxy.litellm_pre_call_utils import add_litellm_data_to_request
|
||||
from litellm.proxy._types import UserAPIKeyAuth
|
||||
|
||||
# Create mock request with headers including User-Agent
|
||||
mock_request = MagicMock(spec=Request)
|
||||
mock_request.method = "POST"
|
||||
mock_request.url = MagicMock()
|
||||
mock_request.url.path = "/bedrock/model/my-model/converse"
|
||||
mock_request.headers = Headers(
|
||||
{
|
||||
"content-type": "application/json",
|
||||
"user-agent": "claude-cli/2.0.69 (external, cli)",
|
||||
"authorization": "Bearer sk-test-key",
|
||||
"x-custom-header": "test-value",
|
||||
}
|
||||
)
|
||||
mock_request.query_params = QueryParams({})
|
||||
|
||||
# Create mock user API key dict
|
||||
mock_user_api_key_dict = UserAPIKeyAuth()
|
||||
|
||||
# Create mock proxy config
|
||||
mock_proxy_config = MagicMock()
|
||||
mock_proxy_config.pass_through_endpoints = []
|
||||
|
||||
# Initial data dict (simulating Bedrock pass-through)
|
||||
data = {
|
||||
"model": "my-bedrock-model",
|
||||
"messages": [{"role": "user", "content": "Hello"}],
|
||||
}
|
||||
|
||||
# Call add_litellm_data_to_request
|
||||
result = await add_litellm_data_to_request(
|
||||
data=data,
|
||||
request=mock_request,
|
||||
user_api_key_dict=mock_user_api_key_dict,
|
||||
proxy_config=mock_proxy_config,
|
||||
general_settings={},
|
||||
version="1.0",
|
||||
)
|
||||
|
||||
# Verify headers are added to metadata for guardrails
|
||||
assert "metadata" in result, "metadata should be present in result"
|
||||
assert "headers" in result["metadata"], "headers should be present in metadata"
|
||||
assert isinstance(
|
||||
result["metadata"]["headers"], dict
|
||||
), "headers should be a dictionary"
|
||||
|
||||
# Verify specific headers are accessible (important for guardrails)
|
||||
headers = result["metadata"]["headers"]
|
||||
assert (
|
||||
"user-agent" in headers or "User-Agent" in headers
|
||||
), "User-Agent header should be accessible in metadata"
|
||||
|
||||
# Also verify proxy_server_request has headers (original location)
|
||||
assert "proxy_server_request" in result
|
||||
assert "headers" in result["proxy_server_request"]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue