From 28bce0b05ef4271b65748ed8f47c7f3ec986622b Mon Sep 17 00:00:00 2001 From: Yuneng Jiang Date: Fri, 10 Apr 2026 00:00:53 -0700 Subject: [PATCH] fix: align v1 guardrail and agent list responses with v2 field handling --- litellm/proxy/agent_endpoints/endpoints.py | 39 +++++++++++++++++++ .../proxy/guardrails/guardrail_endpoints.py | 10 ++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/litellm/proxy/agent_endpoints/endpoints.py b/litellm/proxy/agent_endpoints/endpoints.py index 6e5d4562b55..64c20d5ed5e 100644 --- a/litellm/proxy/agent_endpoints/endpoints.py +++ b/litellm/proxy/agent_endpoints/endpoints.py @@ -28,6 +28,7 @@ from litellm.types.agents import ( MakeAgentsPublicRequest, PatchAgentRequest, ) +from litellm.litellm_core_utils.litellm_logging import _get_masked_values from litellm.types.llms.custom_http import httpxSpecialProvider from litellm.types.proxy.management_endpoints.common_daily_activity import ( SpendAnalyticsPaginatedResponse, @@ -36,6 +37,28 @@ from litellm.types.proxy.management_endpoints.common_daily_activity import ( router = APIRouter() +def _redact_sensitive_agent_fields( + agents: List[AgentResponse], +) -> List[AgentResponse]: + """ + Return copies of the given agents with sensitive configuration fields + redacted. The original objects are not modified. + """ + redacted: List[AgentResponse] = [] + for agent in agents: + copy = agent.model_copy(deep=True) + copy.static_headers = None + copy.extra_headers = None + if copy.litellm_params: + copy.litellm_params = _get_masked_values( + copy.litellm_params, + unmasked_length=4, + number_of_asterisks=4, + ) + redacted.append(copy) + return redacted + + def _check_agent_management_permission(user_api_key_dict: UserAPIKeyAuth) -> None: """ Raises HTTP 403 if the caller does not have permission to create, update, @@ -183,6 +206,14 @@ async def get_agents( agent.agent_id in litellm.public_agent_groups ) + # Redact sensitive fields for non-admin users + is_admin = ( + user_api_key_dict.user_role == LitellmUserRoles.PROXY_ADMIN + or user_api_key_dict.user_role == LitellmUserRoles.PROXY_ADMIN.value + ) + if not is_admin: + returned_agents = _redact_sensitive_agent_fields(returned_agents) + if health_check: agents_with_url = [ agent @@ -399,6 +430,14 @@ async def get_agent_by_id( status_code=404, detail=f"Agent with ID {agent_id} not found" ) + # Redact sensitive fields for non-admin users + is_admin = ( + user_api_key_dict.user_role == LitellmUserRoles.PROXY_ADMIN + or user_api_key_dict.user_role == LitellmUserRoles.PROXY_ADMIN.value + ) + if not is_admin: + agent = _redact_sensitive_agent_fields([agent])[0] + return agent except HTTPException: raise diff --git a/litellm/proxy/guardrails/guardrail_endpoints.py b/litellm/proxy/guardrails/guardrail_endpoints.py index 422bdc13780..6814729258f 100644 --- a/litellm/proxy/guardrails/guardrail_endpoints.py +++ b/litellm/proxy/guardrails/guardrail_endpoints.py @@ -60,12 +60,20 @@ def _get_guardrails_list_response( """ Helper function to get the guardrails list response """ + from litellm.litellm_core_utils.litellm_logging import _get_masked_values + guardrail_configs: List[GuardrailInfoResponse] = [] for guardrail in guardrails_config: + litellm_params = guardrail.get("litellm_params") or {} + masked_params = _get_masked_values( + litellm_params, + unmasked_length=4, + number_of_asterisks=4, + ) guardrail_configs.append( GuardrailInfoResponse( guardrail_name=guardrail.get("guardrail_name"), - litellm_params=guardrail.get("litellm_params"), + litellm_params=masked_params, guardrail_info=guardrail.get("guardrail_info"), ) )