-
-
Notifications
You must be signed in to change notification settings - Fork 6.9k
Revert "fix: langfuse trace leak key on model params" #23868
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,7 +25,6 @@ | |
| reconstruct_model_name, | ||
| filter_exceptions_from_params, | ||
| ) | ||
| from litellm.litellm_core_utils.model_param_helper import ModelParamHelper | ||
| from litellm.litellm_core_utils.redact_messages import redact_user_api_key_info | ||
| from litellm.integrations.langfuse.langfuse_mock_client import ( | ||
| create_mock_langfuse_client, | ||
|
|
@@ -292,6 +291,8 @@ def log_event_on_langfuse( | |
|
|
||
| functions = optional_params.pop("functions", None) | ||
| tools = optional_params.pop("tools", None) | ||
| # Remove secret_fields to prevent leaking sensitive data (e.g., authorization headers) | ||
| optional_params.pop("secret_fields", None) | ||
| if functions is not None: | ||
| prompt["functions"] = functions | ||
| if tools is not None: | ||
|
|
@@ -504,18 +505,13 @@ def _log_langfuse_v1( | |
| kwargs.get("model", ""), custom_llm_provider, metadata | ||
| ) | ||
|
|
||
| # Use whitelisted model parameters to prevent leaking secrets | ||
| sanitized_model_params = ModelParamHelper.get_standard_logging_model_parameters( | ||
| optional_params | ||
| ) | ||
|
|
||
| trace.generation( | ||
| CreateGeneration( | ||
| name=metadata.get("generation_name", "litellm-completion"), | ||
| startTime=start_time, | ||
| endTime=end_time, | ||
| model=model_name, | ||
| modelParameters=sanitized_model_params, | ||
| modelParameters=optional_params, | ||
| prompt=input, | ||
| completion=output, | ||
| usage={ | ||
|
|
@@ -835,26 +831,13 @@ def _log_langfuse_v2( # noqa: PLR0915 | |
| kwargs.get("model", ""), custom_llm_provider, metadata | ||
| ) | ||
|
|
||
| # Use whitelisted model_parameters from StandardLoggingPayload | ||
| # to prevent leaking secrets (api_key, auth headers, etc.) | ||
| if standard_logging_object is not None: | ||
| sanitized_model_params = standard_logging_object.get( | ||
| "model_parameters", optional_params | ||
| ) | ||
| else: | ||
| sanitized_model_params = ( | ||
| ModelParamHelper.get_standard_logging_model_parameters( | ||
| optional_params | ||
| ) | ||
| ) | ||
|
|
||
| generation_params = { | ||
| "name": generation_name, | ||
| "id": clean_metadata.pop("generation_id", generation_id), | ||
| "start_time": start_time, | ||
| "end_time": end_time, | ||
| "model": model_name, | ||
| "model_parameters": sanitized_model_params, | ||
| "model_parameters": optional_params, | ||
| "input": input if not mask_input else "redacted-by-litellm", | ||
|
Comment on lines
839
to
841
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Same credential leak issue as the v1 path: The removed logic previously fell back to |
||
| "output": output if not mask_output else "redacted-by-litellm", | ||
| "usage": usage, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5569,23 +5569,21 @@ def scrub_sensitive_keys_in_metadata(litellm_params: Optional[dict]): | |
| litellm_params["_langfuse_masking_function"] = masking_fn | ||
| litellm_params["metadata"] = metadata | ||
|
|
||
| ## remove sensitive logging/callback keys from metadata dicts | ||
| ## these contain credentials (langfuse_secret_key, langfuse_public_key, etc.) | ||
| _sensitive_keys = {"logging", "callback_settings"} | ||
|
|
||
| for metadata_field in ( | ||
| "user_api_key_metadata", | ||
| "user_api_key_auth_metadata", | ||
| "user_api_key_team_metadata", | ||
| ## check user_api_key_metadata for sensitive logging keys | ||
| cleaned_user_api_key_metadata = {} | ||
| if "user_api_key_metadata" in metadata and isinstance( | ||
| metadata["user_api_key_metadata"], dict | ||
| ): | ||
| if metadata_field in metadata and isinstance(metadata[metadata_field], dict): | ||
| for sensitive_key in _sensitive_keys: | ||
| metadata[metadata_field].pop(sensitive_key, None) | ||
|
|
||
| ## remove user_api_key_auth entirely - contains full auth object with nested credentials | ||
| metadata.pop("user_api_key_auth", None) | ||
| for k, v in metadata["user_api_key_metadata"].items(): | ||
| if k == "logging": # prevent logging user logging keys | ||
| cleaned_user_api_key_metadata[k] = ( | ||
| "scrubbed_by_litellm_for_sensitive_keys" | ||
| ) | ||
| else: | ||
| cleaned_user_api_key_metadata[k] = v | ||
|
|
||
| litellm_params["metadata"] = metadata | ||
| metadata["user_api_key_metadata"] = cleaned_user_api_key_metadata | ||
| litellm_params["metadata"] = metadata | ||
|
Comment on lines
+5572
to
+5586
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The original
Additionally, the |
||
|
|
||
| return litellm_params | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After this revert, the raw
optional_paramsdict (with onlysecret_fieldspopped) is passed directly to Langfuse asmodelParameters. Fields likeapi_key,api_base,authorization, andheaderscan still leak to Langfuse traces.The existing test
test_langfuse_model_parameters_no_secret_leakageexplicitly verifies that these fields must NOT appear in the logged parameters:Popping only
secret_fieldsis insufficient — these other keys will still pass through to Langfuse. The whitelist approach fromModelParamHelper.get_standard_logging_model_parameters()was what prevented leakage of all non-standard keys.