litellm/tests/test_litellm/proxy/guardrails
devin-ai-integration[bot] d7d10be063
fix(guardrails): return the full PANW AIRS scan response on blocked requests (#37036)
* fix(guardrails): return the full PANW AIRS scan response on blocked requests

The blocked-request error detail was assembled from a hardcoded allowlist, so audit fields like prompt_detection_details, prompt_masked_data, source, transaction_id and session_id never reached the client even though AIRS returned them.

Resolves LIT-5638

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* style(guardrails): drop redundant comment in AIRS error detail

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(panw_prisma_airs): withhold response_masked_data from the blocked-response error

The full AIRS passthrough also reached the response-side block path, where
response_masked_data carries the model's own generation. That branch is only
reached when mask_response_content is False, so the operator had explicitly
declined to deliver that text, and the error body handed it back anyway.

Withhold response_masked_data from the client-visible detail. prompt_masked_data
stays: it is the caller's own input and one of the fields the ticket asks for.

Every other AIRS field, including prompt_detection_details, source,
transaction_id and session_id, is unchanged.

* fix(panw_prisma_airs): withhold generated tool args from response-side blocks

_scan_tool_calls_for_guardrail calls AIRS with is_response=False because
tool_event is request-side in the AIRS schema, so AIRS returns the scanned
tool arguments under prompt_masked_data. When the tool calls being scanned
are the model's own output, that key holds generated content, and the
_CLIENT_HIDDEN_SCAN_FIELDS default (response_masked_data, empty on this
path) does not cover it. With the default mask_response_content=False the
block branch then shipped the model's masked tool arguments in the 400 --
the same content channel this PR closed for response_masked_data.

_build_error_detail takes an extra_hidden_fields argument so the withholding
stays in one place, and the tool-call block branch passes prompt_masked_data
when is_response is True. Request-side blocks are unchanged and still carry
prompt_masked_data, which is what LIT-5638 asks for.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* style(panw_prisma_airs): apply ruff format

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Yucheng Zhu <yucheng@berri.ai>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-15 15:31:23 -07:00
..
guardrail_hooks fix(guardrails): return the full PANW AIRS scan response on blocked requests (#37036) 2026-08-15 15:31:23 -07:00
test_content_filter_path_traversal.py Litellm OSS Staging 010626 (#29422) 2026-06-01 21:42:51 -07:00
test_content_utils.py fix(guardrails): walk custom_tool_call_output items in _content_utils (#32969) 2026-07-13 09:27:57 -07:00
test_custom_code_security.py fix(guardrails): return HTTP 400 for litellm content filter blocks (#28418) 2026-05-30 14:28:46 -07:00
test_deferred_guardrail_logging.py feat(proxy): enforce key/team guardrails on bedrock passthrough routes (#30194) 2026-06-12 07:23:29 -07:00
test_guardrail_coverage.py fix(tests): use canonical litellm_enterprise import path (#27699) 2026-05-12 12:32:57 -07:00
test_guardrail_endpoints.py fix(bedrock_guardrails): skip ApplyGuardrail when there is no content to scan (#36441) 2026-08-11 17:30:54 -07:00
test_guardrail_registry.py fix(guardrails): refuse scan_only_tool_results combos that scan nothing 2026-08-06 01:58:06 -07:00
test_init_guardrails.py fix(guardrails): chunk oversized Bedrock ApplyGuardrail requests instead of failing (#36119) 2026-08-07 19:44:24 -07:00
test_llm_as_a_judge.py fix(guardrails): resolve judge_model credentials via lazy Router lookup in llm_as_a_judge (#34509) 2026-07-25 20:16:43 -07:00
test_mcp_jwt_signer.py fix(mcp): JWT on tools/list and REST tools/call server resolution (#28227) 2026-05-20 13:31:44 -07:00
test_pillar_guardrails.py chore(proxy): harden request control fields 2026-04-29 22:35:17 -07:00
test_prompt_security_guardrails.py fixing prompt-security's guardrail implementation (#19374) 2026-01-21 20:09:40 -08:00
test_qostodian_nexus_guardrail.py feat: add Qohash Nexus guardrail hook (#24927) 2026-05-01 17:26:32 +05:30
test_usage_endpoints.py fix(guardrails): show YAML-defined guardrails in the Guardrail Monitor 2026-07-10 16:49:30 -07:00