mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-04 02:31:27 +00:00
Fix Vertex metadata redaction bypass in logging callbacks.
Scrub Vertex provider fields from litellm_params.metadata.hidden_params during perform_redaction so streaming success_handler merges do not leak prompt-derived metadata when message logging is disabled. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
098cca6d5d
commit
5ffea2f1d7
2 changed files with 55 additions and 0 deletions
|
|
@ -128,6 +128,30 @@ def _redact_vertex_provider_metadata(obj: Any) -> None:
|
|||
hidden_params.pop(field, None)
|
||||
|
||||
|
||||
def _redact_vertex_provider_metadata_from_litellm_params(
|
||||
model_call_details: dict,
|
||||
) -> None:
|
||||
"""
|
||||
Scrub Vertex provider metadata copied into litellm_params metadata.
|
||||
|
||||
success_handler() merges response._hidden_params into
|
||||
litellm_params.metadata['hidden_params'] before perform_redaction() runs.
|
||||
"""
|
||||
litellm_params = model_call_details.get("litellm_params")
|
||||
if not isinstance(litellm_params, dict):
|
||||
return
|
||||
|
||||
for metadata_key in ("metadata", "litellm_metadata"):
|
||||
metadata = litellm_params.get(metadata_key)
|
||||
if not isinstance(metadata, dict):
|
||||
continue
|
||||
hidden_params = metadata.get("hidden_params")
|
||||
if not isinstance(hidden_params, dict):
|
||||
continue
|
||||
for field in VERTEX_PROVIDER_METADATA_FIELDS:
|
||||
hidden_params.pop(field, None)
|
||||
|
||||
|
||||
def _redact_standard_logging_object(model_call_details: dict):
|
||||
"""Redact messages and response inside standard_logging_object if present."""
|
||||
standard_logging_object = model_call_details.get("standard_logging_object")
|
||||
|
|
@ -194,6 +218,7 @@ def perform_redaction(model_call_details: dict, result):
|
|||
model_call_details["prompt"] = ""
|
||||
model_call_details["input"] = ""
|
||||
_redact_standard_logging_object(model_call_details)
|
||||
_redact_vertex_provider_metadata_from_litellm_params(model_call_details)
|
||||
|
||||
# Redact streaming response
|
||||
if (
|
||||
|
|
|
|||
|
|
@ -412,3 +412,33 @@ class TestPerformRedaction:
|
|||
assert response.choices[0].message.content == "redacted-by-litellm"
|
||||
assert getattr(response, "vertex_ai_grounding_metadata") == []
|
||||
assert "vertex_ai_grounding_metadata" not in response._hidden_params
|
||||
|
||||
def test_redacts_vertex_provider_metadata_from_metadata_hidden_params(self):
|
||||
"""Streaming success_handler copies _hidden_params into metadata before redaction."""
|
||||
details = {
|
||||
"stream": True,
|
||||
"litellm_params": {
|
||||
"metadata": {
|
||||
"hidden_params": {
|
||||
"response_cost": 0.01,
|
||||
"vertex_ai_grounding_metadata": [
|
||||
{"webSearchQueries": ["sensitive search term"]}
|
||||
],
|
||||
"vertex_ai_url_context_metadata": [
|
||||
{"urlMetadata": [{"retrievedUrl": "https://example.com"}]}
|
||||
],
|
||||
"vertex_ai_safety_ratings": [{"category": "HARM"}],
|
||||
"vertex_ai_citation_metadata": [{"citations": ["source"]}],
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
perform_redaction(details, None)
|
||||
|
||||
hidden_params = details["litellm_params"]["metadata"]["hidden_params"]
|
||||
assert hidden_params["response_cost"] == 0.01
|
||||
assert "vertex_ai_grounding_metadata" not in hidden_params
|
||||
assert "vertex_ai_url_context_metadata" not in hidden_params
|
||||
assert "vertex_ai_safety_ratings" not in hidden_params
|
||||
assert "vertex_ai_citation_metadata" not in hidden_params
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue