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:
Sameer Kankute 2026-06-08 18:24:02 +05:30
parent 098cca6d5d
commit 5ffea2f1d7
No known key found for this signature in database
2 changed files with 55 additions and 0 deletions

View file

@ -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 (

View file

@ -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