fix(guardrails): don't add post_call output scan for MCP-only Presidio modes - #40571
Conversation
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
Greptile SummaryThis PR changes Presidio initialization so guardrails configured exclusively for MCP events default to input-only filtering, preventing an unrelated post-call scan of the final model response. It supports string, list, and tag-based modes while retaining output scanning when explicitly requested. The latest update replaces structural matching in Confidence Score: 5/5The PR appears safe to merge because the latest refactor preserves validated mode handling and both previous findings are resolved Tag-based modes are flattened correctly, the regression test checks observable response redaction, and explicit output-filter scopes retain the existing scan behavior Important Files Changed
Reviews (3): Last reviewed commit: "fix(guardrails): use explicit returns in..." | Re-trigger Greptile |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
7dfda63 to
6bfa1af
Compare
…o modes Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…MCP hooks Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
6bfa1af to
7b3582a
Compare
|
|
|
@greptileai please re-review: tag-based Mode is now classified as MCP-only, the test checks output-scan behavior, and CodeQL return finding is fixed |
|
Fixed in 7b3582a: every match arm returns explicitly and the fallback arm calls assert_never, so there is no implicit None return |
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
@greptileai please re-review: _configured_event_hooks now uses explicit isinstance returns, so the CodeQL mixed-return finding is gone |
|
bugbot run |
|
@veria-ai please review 8a43fed: MCP-only Presidio modes now default to input-only scanning unless presidio_filter_scope asks for output |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 8a43fed. Configure here.
TLDR
Problem this solves:
modeobjects were not recognized as MCP-onlyHow it solves it:
pre_mcp_call/during_mcp_call/post_mcp_calldefault topresidio_filter_scope: inputmode(tags plus default)presidio_filter_scope: bothoroutputstill scans the answerUser Flow
Before: a developer asks the model to run an MCP tool with a phone number in the query, and the whole request fails even though only the tool call should be blocked
mode: pre_mcp_callandPHONE_NUMBER: BLOCK, plus one MCP serverBlocked entity detected: PHONE_NUMBER by Guardrail: pre-mcp-pii-check, so the developer never sees the answer or the blocked tool resultAfter: the same request returns the answer, with the blocked tool result inside it
tool_execution_resultsitem readingTool call blocked: PII entity 'PHONE_NUMBER' detected by guardrail 'pre-mcp-pii-check'Relevant issues
Pylon #8386
Affected release
Linear ticket
Resolves LIT-7459
Pre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
uv run pytest tests/test_litellm/<your_test_file>.py -v. Leave the suites (make test-unit-*,make test-unit) to CI: it finishes in ~15 minutes where a laptop takes an hour or more@greptileaito re-request a review after pushing changes)Delays in PR merge?
If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).
Screenshots / Proof of Fix
Shared setup: Presidio analyzer and anonymizer containers (
mcr.microsoft.com/presidio-analyzer,mcr.microsoft.com/presidio-anonymizer), a local MCP server exposing oneweb_searchtool onhttp://127.0.0.1:27459/mcp, and the proxy started withlitellm --config config.yaml --port 20459 --detailed_debug. Real OpenAI calls togpt-4.1-miniRequest used in every run (
req.json):{ "model": "gpt-4.1-mini", "input": "Use the web_search tool to search for exactly this text: \"call me at 415-555-2671\". Do not modify the query. In your final answer, always repeat the exact query text you searched for, verbatim, even if the tool failed.", "tools": [{"type": "mcp", "server_label": "litellm", "server_url": "litellm_proxy", "require_approval": "never"}] }Before (29a712b)
MCP-only mode, default scope
curl -s -i http://127.0.0.1:20459/v1/responses -H 'Authorization: Bearer sk-1234' -H 'content-type: application/json' -d @req.jsonMCP-only mode with explicit
presidio_filter_scope: bothpresidio_filter_scope: bothAfter (8a43fed)
MCP-only mode, default scope
curl -s -i http://127.0.0.1:20459/v1/responses -H 'Authorization: Bearer sk-1234' -H 'content-type: application/json' -d @req.jsonMCP-only mode with explicit
presidio_filter_scope: bothpresidio_filter_scope: bothType
🐛 Bug Fix
Caveats (if any)
Medium
presidio_filter_scope: bothto keep itLow
modecounts as MCP-only only when every tag value and the default are MCP hooks; a mix keeps the oldbothdefaultmode(no tags, no default) also keeps the oldbothdefaultFinal Attestation
Link to Devin session: https://app.devin.ai/sessions/f346adfada8f43468f6d29bcc05630bd
Open in Devin Desktop: https://app.devin.ai/desktop/session/f346adfada8f43468f6d29bcc05630bd?variant=devin
Requested by: @yassin-berriai
Note
Medium Risk
Changes the default Presidio filter scope for MCP-only guardrails; deployments that relied on implicit LLM output scanning must set
presidio_filter_scope: bothexplicitly.Overview
Fixes a regression where Presidio guardrails configured for MCP-only event hooks (
pre_mcp_call,during_mcp_call,post_mcp_call) still registered a post_call output scan by default (presidio_filter_scope: both). That could turn an otherwise successful response into HTTP 400 when the model repeated PII from a blocked MCP tool call in its answer.initialize_presidionow inferspresidio_filter_scope: inputwhen no explicit scope is set and every configured hook inmodeis MCP-only (string, list, or tag-basedMode). Explicitbothoroutputstill enables answer scanning.Adds helpers
_configured_event_hooksand_is_mcp_only_mode, plus a parametrized test that exercises post_call behavior across MCP-only vs mixed modes and explicit filter scopes.Reviewed by Cursor Bugbot for commit 8a43fed. Bugbot is set up for automated code reviews on this repo. Configure here.