Commit graph

154 commits

Author SHA1 Message Date
Ishaan Jaff
371cabfebd
Add MCP Security guardrail to block unregistered MCP servers (#21429)
* Add MCP_SECURITY enum to SupportedGuardrailIntegrations

* Add MCP security guardrail initializer

* Add MCPSecurityGuardrail implementation

* Add MCP Security policy template

* Add Type filter to policy templates UI

* Add unit tests for MCP security guardrail

* fix(lint): remove unused Dict import from mcp_security_guardrail

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Add French language support for EU AI Act Article 5 guardrail (#21427)

* Add French language support for EU AI Act Article 5 template

- Create eu_ai_act_article5_fr.yaml with comprehensive French keywords
- Includes identifier words: concevoir, créer, développer, noter, classer, etc.
- Includes block words: crédit social, comportement social, émotion des employés, etc.
- Includes always-block keywords for explicit prohibited practices
- Includes exceptions for research, compliance, and legitimate use cases
- Catches circumvention attempts with phrase variations

* Add comprehensive tests for French EU AI Act guardrail

- Test 3 critical scenarios: blocked query, circumvention attempt, safe query
- Test edge cases: case-insensitive, mixed language, research exceptions
- All 7 tests passing
- Validates both blocking and allowing behavior

* Fix content filter to support conditional matching without inherit_from

- Enable conditional matching when identifier_words + additional_block_words are present
- Previously required inherit_from, but EU AI Act templates are self-contained
- Fixes Greptile feedback: conditional matching now works as documented

* Add pure conditional matching test for French guardrail

- Test identifier + block word combinations not in always_block_keywords
- Verifies conditional matching works independently
- Addresses Greptile feedback about test coverage gap

* Fix exception word bypass risk in French template

- Replace short words (film, jeu, juste) with context-specific phrases
- Prevents substring matching bypasses (e.g., enjeu matching jeu)
- Add tests for bypass prevention and legitimate game context
- Addresses Greptile security feedback

* Make conditional match assertion more robust

- Use getattr to safely access exception detail field
- Check if detail is dict before calling .get()
- Addresses Greptile feedback about brittle string assertion

* Add French EU AI Act Article 5 policy template to registry

- Add eu-ai-act-article5-fr template for French language support
- Includes French description and guardrail info
- Matches structure of English template

* Address greptile review feedback (greploop iteration 1)

- Use status_code=400 instead of 403 to match guardrail logging convention
- Use prefix stripping instead of split('/')[-1] for robust server name extraction

* remove French EU AI Act template from policy_templates.json

---------

Co-authored-by: Julio Quinteros Pro <jquinter@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-17 21:19:13 -08:00
Julio Quinteros Pro
e6abb865d3 fix: properly reload litellm in setup_and_teardown fixture
Use importlib.import_module + reload uniformly in both code paths
to ensure fresh module state regardless of whether litellm was
previously in sys.modules. This fixes the inconsistency where the
"not in sys.modules" branch didn't reload the module.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-17 21:29:13 -03:00
Julio Quinteros Pro
77f315eb11 fix: address Greptile review feedback for test isolation
- test_pillar_guardrails.py: Fix fixture to properly update module-level
  litellm reference using global keyword and assignment from reload
- test_anthropic_experimental_pass_through_messages_handler.py: Add missing
  assert keywords to kwargs comparison statements (lines 36, 60-62)
- test_proxy_server.py: Replace silent pytest.skip with explicit assertion
  to catch router initialization regressions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-17 21:28:23 -03:00
Sameer Kankute
fe20e66a1d Fix : test_exception_without_scanners 2026-02-17 20:12:02 +05:30
Sameer Kankute
8374b4d939 Fix : test_exception_without_scanners 2026-02-17 20:11:20 +05:30
Ishaan Jaff
1a8525d02a
Add GDPR Art. 32 EU PII Protection Policy Template (#21340)
* Add 6 new EU PII patterns for GDPR compliance

- fr_nir: French Social Security Number (NIR/INSEE) with validation
- eu_iban_enhanced: Enhanced IBAN detection with specific format
- fr_phone: French phone numbers (+33, 0033, 0 formats)
- eu_vat: EU VAT identification numbers (all 27 member states)
- eu_passport_generic: Generic EU passport format
- fr_postal_code: French postal codes with contextual keywords

* Add GDPR Art. 32 EU PII Protection policy template

- Comprehensive GDPR Article 32 compliance policy
- 4 guardrail groups: National IDs, Financial, Contact Info, Business IDs
- Masks French NIR/INSEE, EU IBANs, French phones, EU VAT numbers
- Includes EU passport numbers and email addresses
- Medium complexity template with indigo icon

* Add comprehensive tests for EU PII patterns

- Test French NIR validation (sex digit, month range)
- Test enhanced IBAN detection (French, German)
- Test French phone number formats
- Test EU VAT numbers
- Test generic EU passport format
- Test French postal code pattern

* Add EU pattern loading and category validation tests

- Verify all 6 EU PII patterns are loaded correctly
- Verify patterns are categorized as 'EU PII Patterns'
- Ensure pattern loading consistency

* Add end-to-end tests for GDPR policy template

- 4 tests for PII that should be masked (NIR, IBAN, phone, VAT)
- 4 tests for text that should pass through (invalid patterns, no PII)
- 1 bonus test for multiple PII types in same message
- All tests verify correct masking behavior

* Add region field to policy templates

- Added region field to all 6 templates (EU, AU, Global)
- Updated both main and backup JSON files
- Enables region-based filtering in UI

* Add region filter to policy templates UI

- Added Radio.Group filter for regions (All, AU, EU, Global)
- Efficient filtering with useMemo hooks
- Clean button-based UI matching existing design
- Defaults missing regions to Global

* Apply suggestion from @greptile-apps[bot]

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* Address Greptile review: add contextual guards and negative tests

- Added keyword_pattern to eu_vat (VAT, tax number, fiscal code, etc.)
- Added keyword_pattern to eu_passport_generic (passport, travel document, etc.)
- Added 3 negative unit tests for false positive prevention
- Added 2 E2E tests verifying no masking without keyword context
- All patterns now require contextual keywords to prevent false positives

* address greptile review feedback (greploop iteration 1)

- Remove unused HTTPException import from test file
- Add keyword_pattern to eu_vat for contextual VAT matching
- Add allow_word_numbers: false to eu_passport_generic
- Add negative test cases for EU VAT false positives
- All 5 Greptile comments addressed

* Address Greptile feedback: fix patterns and sync backup

- Fix fr_phone pattern: use negative lookbehind (?<!\d) to prevent false matches in longer digit strings
- Add keyword_pattern to eu_passport_generic to reduce false positives on version strings/SKUs
- Sync policy_templates_backup.json with main file (add GDPR template)
- Add keyword_pattern to eu_vat (was auto-added by formatter)

All pattern tests passing

* address greptile review feedback (greploop iteration 2)

- Update test to document that eu_vat raw pattern is intentionally broad
- Test verifies pattern DOES match common words (by design)
- Documents that keyword_pattern guard prevents false positives in production
- Addresses Greptile's false positive risk concern

* address greptile review feedback (greploop iteration 3)

- Fix test_eu_vat_masked: change gap from 2 words to 1 word (VAT number: FR...)
- This ensures keyword matching works within MAX_KEYWORD_VALUE_GAP_WORDS=1 limit
- fr_phone pattern already works correctly (verified with tests)
- test_pattern_requires_keyword_context already updated in iteration 2

Addresses final issues from Greptile 2/5 review

* fix: remove country-specific passport patterns from GDPR template

- Remove passport_france, passport_germany, passport_netherlands from template
- These patterns lack keyword guards and cause false positives
- Only eu_passport_generic remains (has keyword_pattern guard)
- Sync policy_templates_backup.json with main file
- Update test setup to match template

All 11 E2E tests now passing ✅

* Update tests/test_litellm/proxy/guardrails/guardrail_hooks/content_filter/test_gdpr_policy_e2e.py

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* Update litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/content_filter.py

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-02-16 15:28:46 -08:00
Julio Quinteros Pro
ab658d7d50 Fix pillar guardrails tests for parallel execution
The setup_and_teardown fixture was failing with "ImportError: module
litellm not in sys.modules" during parallel test execution. This occurs
because another worker might have removed/modified litellm from
sys.modules before this test tries to reload it.

Fix: Check if litellm is in sys.modules before attempting reload.
2026-02-15 13:08:41 -03:00
Krish Dholakia
e41ecc7a71
Guardrails - add nsfw policy template, toxic keywords in multiple languages, child safety content filter, json content viewer (#21205)
* fix(content_filter.py): fix filter on toxic keywords

* feat: improve toxic/abusive language detection

* fix: additional improvements to nsfw filters

* feat: more improvements to nsfw filter

* feat(content_filter.json): add new australia specific nsfw content filter

ensure complete coverage for australia nsfw

* fix: cleanup policy templates

* fix(index.tsx): alert notice

* fix(index.tsx): add disclaimer notice

* feat(harmful_child_safety.yaml): new child safety content filter

ensure we catch inappropriate, child-specific content

* feat(policy_templates.json): add child safety and self harm filters

* fix(content_filter.py): improve racial bias filter to use a similar identifier + block word pattern and cover a wider range of ethnicities

* feat(policy_templates.json): add racial bias to nsfw policy template

* feat: add json content viewer
2026-02-14 09:41:55 -08:00
Sameer Kankute
e17c639fb1
Merge pull request #21085 from BerriAI/litellm_oss_staging_02_13_2026
Litellm oss staging 02 13 2026
2026-02-13 18:38:14 +05:30
Sameer Kankute
d8f114e363
Merge branch 'main' into litellm_oss_staging_02_07_20262 2026-02-13 17:53:03 +05:30
Harshit Jain
7f6563f1a6
fix: openai moderation guardrails (#20718)
* fix: openai moderation guardrails

* adds missing import

* mv: test file to right place
2026-02-12 21:03:11 -08:00
mubashir1osmani
1bc90d2db7
fix guardrail status error (#20972)
* fix guardrail status error

* fix function imports
2026-02-12 20:19:13 -08:00
Sameer Kankute
59d6ab8a00
Merge branch 'main' into litellm_oss_staging_02_11_2026 2026-02-12 20:04:46 +05:30
Varun Chawla
e587370f67 fix(proxy): add regression tests for #20441 - <script> tags in messages (#20573)
* fix: empty guardrails/policies arrays should not trigger enterprise license check (#20304)

The UI sends empty arrays for enterprise-only fields (guardrails, policies,
logging) even when the user has not configured these features. The backend
`is not None` check treated `[]` as a truthy intent to use the feature,
falsely requiring an enterprise license for basic team operations.

Backend: Add `and updated_kv[field] != [] and updated_kv[field] != {}`
guards in `_update_metadata_fields` so empty collections are skipped.

UI: Conditionally omit guardrails, logging, and policies from the
payload when empty instead of defaulting to `[]`.

Fixes #20304

* fix: allow clearing fields with empty collections while skipping enterprise check

Address PR review feedback:

1. Move the empty-collection guard into _update_metadata_field (singular)
   so that empty lists/dicts skip only the premium license check but still
   get written into metadata. This lets users intentionally clear a
   previously-set field (e.g. guardrails: []) without being blocked, while
   the UI's default empty arrays still don't trigger a false enterprise
   error.

2. Remove sys.path hack from test file; use standard imports that work
   with pytest discovery.

3. Add tests verifying that empty collections are moved into metadata
   (field clearing works) even though they bypass the premium check.

Fixes #20304

* fix(proxy): add regression tests for #20441 - ensure <script> tags in LLM messages are not blocked

The 403 Forbidden error when sending messages containing `<script>` is caused
by external WAF/reverse proxy infrastructure (confirmed by the standard nginx
HTML 403 response format), not by LiteLLM's own content filtering. However,
these regression tests ensure that:

1. The content filter guardrail's built-in patterns do not match HTML tags
2. Messages containing <script> and other HTML tags pass through the content
   filter unchanged when no explicit HTML-blocking rules are configured
3. The HTTP request body parser correctly handles JSON payloads containing
   HTML content without modification

These tests guard against accidentally introducing HTML/XSS filtering that
would break legitimate LLM API usage (e.g., discussing HTML/JavaScript code).

Closes #20441

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 19:57:40 +05:30
Krish Dholakia
af3acdda18
Guardrails - add toxic/abusive content filter guardrails 2026-02-11 18:08:16 -08:00
Neel Harsola
ce421df1ef
fix(azure): preserve content_policy_violation error details from Azure OpenAI (#20883)
* feat: add opus 4.5 and 4.6 to use outout_format param

* generate poetry lock with 2.3.2 poetry

* restore poetry lock

* e2e tests, key delete, update tpm rpm, and regenerate

* Split e2e ui testing for browser

* new login with sso button in login page

* option to hide usage indicator

* fix(cloudzero): update CBF field mappings per LIT-1907 (#20906)

* fix(cloudzero): update CBF field mappings per LIT-1907

Phase 1 field updates for CloudZero integration:

ADD/UPDATE:
- resource/account: Send concat(api_key_alias, '|', api_key_prefix)
- resource/service: Send model_group instead of service_type
- resource/usage_family: Send provider instead of hardcoded 'llm-usage'
- action/operation: NEW - Send team_id
- resource/id: Send model name instead of CZRN
- resource/tag:organization_alias: Add if exists
- resource/tag:project_alias: Add if exists
- resource/tag:user_alias: Add if exists

REMOVE:
- resource/tag:total_tokens: Removed
- resource/tag:team_id: Removed (team_id now in action/operation)

Fixes LIT-1907

* Update litellm/integrations/cloudzero/transform.py

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* fix: define api_key_alias variable, update CBFRecord docstring

- Fix F821 lint error: api_key_alias was used but not defined
- Update CBFRecord docstring to reflect LIT-1907 field mappings
- Remove unused Optional import

---------

Co-authored-by: Ishaan Jaff <ishaanjaffer0324@gmail.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* Add banner notifying of breaking change

* Add semgrep & Fix OOMs (#20912)

* [Feat] Policies - Allow connecting Policies to Tags, Simulating Policies, Viewing how many keys, teams it applies on  (#20904)

* init schema with TAGS

* ui: add policy test

* resolvePoliciesCall

* add_policy_sources_to_metadata + headers

* types Policy

* preview Impact

* def _describe_match_reason(

* match based on TAGs

* TestTagBasedAttachments

* test fixes

* add policy_resolve_router

* add_guardrails_from_policy_engine

* TestMatchAttribution

* refactor

* fix

* fix: address Greptile review feedback on policy resolve endpoints

- Track unnamed keys/teams as separate counts instead of inflating
  affected_keys_count with duplicate "(unnamed key)" placeholders.
  Added unnamed_keys_count and unnamed_teams_count to response.
- Push alias pattern matching to DB via _build_alias_where() which
  converts exact patterns to Prisma "in" and suffix wildcards to
  "startsWith" filters.
- Gate sync_policies_from_db/sync_attachments_from_db behind
  force_sync query param (default false) to avoid 2 DB round-trips
  on every /policies/resolve request.
- Remove worktree-only conftest.py that cleared sys.modules at import
  time — no longer needed since code moved to main repo.
- Rename MAX_ESTIMATE_IMPACT_ROWS → MAX_POLICY_ESTIMATE_IMPACT_ROWS.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: eliminate duplicate DB queries and fix header delimiter ambiguity

- Fetch teams table once in estimate_attachment_impact and reuse for
  both tag-based and alias-based lookups (was querying teams twice when
  both tag_patterns and team_patterns were provided).
- Convert tag/team filter functions from async DB queries to sync
  filters that operate on pre-fetched data (_filter_keys_by_tags,
  _filter_teams_by_tags).
- Fix comma ambiguity in x-litellm-policy-sources header: use '; '
  as entry delimiter since matched_via values can contain commas.
- Use '+' as the within-value separator in matched_via reason strings
  (e.g. "tag:healthcare+team:health-team") to avoid conflict with
  header delimiters.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Update litellm/proxy/policy_engine/policy_resolve_endpoints.py

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* fix: type error & better error handling (#20689)

* [Docs] Add docs guide for using policies  (#20914)

* init schema with TAGS

* ui: add policy test

* resolvePoliciesCall

* add_policy_sources_to_metadata + headers

* types Policy

* preview Impact

* def _describe_match_reason(

* match based on TAGs

* TestTagBasedAttachments

* test fixes

* add policy_resolve_router

* add_guardrails_from_policy_engine

* TestMatchAttribution

* refactor

* fix

* fix: address Greptile review feedback on policy resolve endpoints

- Track unnamed keys/teams as separate counts instead of inflating
  affected_keys_count with duplicate "(unnamed key)" placeholders.
  Added unnamed_keys_count and unnamed_teams_count to response.
- Push alias pattern matching to DB via _build_alias_where() which
  converts exact patterns to Prisma "in" and suffix wildcards to
  "startsWith" filters.
- Gate sync_policies_from_db/sync_attachments_from_db behind
  force_sync query param (default false) to avoid 2 DB round-trips
  on every /policies/resolve request.
- Remove worktree-only conftest.py that cleared sys.modules at import
  time — no longer needed since code moved to main repo.
- Rename MAX_ESTIMATE_IMPACT_ROWS → MAX_POLICY_ESTIMATE_IMPACT_ROWS.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: eliminate duplicate DB queries and fix header delimiter ambiguity

- Fetch teams table once in estimate_attachment_impact and reuse for
  both tag-based and alias-based lookups (was querying teams twice when
  both tag_patterns and team_patterns were provided).
- Convert tag/team filter functions from async DB queries to sync
  filters that operate on pre-fetched data (_filter_keys_by_tags,
  _filter_teams_by_tags).
- Fix comma ambiguity in x-litellm-policy-sources header: use '; '
  as entry delimiter since matched_via values can contain commas.
- Use '+' as the within-value separator in matched_via reason strings
  (e.g. "tag:healthcare+team:health-team") to avoid conflict with
  header delimiters.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs v1 guide with UI imgs

* docs fix

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add dashscope/qwen3-max model with tiered pricing (#20919)

Add support for Alibaba Cloud's Qwen3-Max model with:
- 258K input tokens, 65K output tokens
- Tiered pricing based on context window usage (0-32K, 32K-128K, 128K-252K)
- Function calling and tool choice support
- Reasoning capabilities enabled

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix linting

* docs: add Greptile review requirement to PR template (#20762)

* fix(azure): preserve content_policy_violation error details from Azure OpenAI

Closes #20811

Azure OpenAI returns rich error payloads for content policy violations
(inner_error with ResponsibleAIPolicyViolation, content_filter_results,
revised_prompt). Previously these details were lost when:

1. The top-level error code was not "content_policy_violation" but the
   inner_error.code was "ResponsibleAIPolicyViolation" -- the structured
   check only examined the top-level code.

2. The DALL-E image generation polling path stringified the error JSON
   into the message field instead of setting the structured body, making
   it impossible for exception_type() to extract error details.

3. The string-based fallback detector used "invalid_request_error" as a
   content-policy indicator, which is too broad and could misclassify
   regular bad-request errors.

Changes:
- exception_mapping_utils.py: Check inner_error.code for
  ResponsibleAIPolicyViolation when top-level code is not
  content_policy_violation. Replace overly broad "invalid_request_error"
  string match with specific Azure safety-system messages.
- azure.py: Set structured body on AzureOpenAIError in both async and
  sync DALL-E polling paths so exception_type() can inspect error details.
- test_azure_exception_mapping.py: Add regression tests covering the
  exact error payloads from issue #20811.
- Fix pre-existing lint: duplicate PerplexityResponsesConfig dict key,
  unused RouteChecks top-level import.

---------

Co-authored-by: Kelvin Tran <kelvin-tran@users.noreply.github.com>
Co-authored-by: yuneng-jiang <yuneng.jiang@gmail.com>
Co-authored-by: shin-bot-litellm <shin-bot-litellm@berri.ai>
Co-authored-by: Ishaan Jaff <ishaanjaffer0324@gmail.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Alexsander Hamir <alexsanderhamirgomesbaptista@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Harshit Jain <48647625+Harshit28j@users.noreply.github.com>
Co-authored-by: ken <122603020@qq.com>
Co-authored-by: Sameer Kankute <sameer@berri.ai>
2026-02-10 22:47:03 -08:00
Itay Ovadia
126522ab91
Generic Guardrails: Forward request headers + litellm_version to gene… (#20729)
* Generic Guardrails: Forward request headers + litellm_version to generic guardrail API

* Generic Guardrail: Change the request headers addition to be with allowlist instead denylist
2026-02-10 22:41:05 -08:00
Harshit Jain
bc0622692d
fix: type error & better error handling (#20689) 2026-02-10 18:33:57 -08:00
yuneng-jiang
6b938f81d1 guardrails list sensitive values fix 2026-02-09 17:11:54 -08:00
Ishaan Jaff
887a907e42
[Fix] Guardrails API - Ensure OpenAI Moderations Guard works with OpenAI Embeddings (#20523)
* init OpenAIEmbeddingsHandler

* init apply_guardrail

* use apply guardrails for OpenAI moderations

* test_embeddings_handler_string_input

* test_openai_moderation_guardrail_apply_guardrail

* fix typing

* test_openai_moderation_responses_api_input_field

* test fixes
2026-02-05 14:40:15 -08:00
Sameer Kankute
453d1bd5e1
Merge branch 'main' into litellm_oss_staging_02_04_2026 2026-02-05 12:19:03 +05:30
Sameer Kankute
54b5c7d2cd Fix: litellm/tests/test_litellm/proxy/guardrails/guardrail_hooks/test_grayswan.py 2026-02-04 17:35:26 +05:30
akraines
774a015aad
fix: Preserve streaming content on guardrail-sampled chunks (#20027)
The unified guardrail's streaming iterator hook processes every Nth
chunk (sampling_rate, default 5). On each sampled chunk it calls
process_output_streaming_response, which combines all accumulated text
into the first chunk and clears all subsequent chunks to "".

The hook then yielded `processed_items[-1]` — the last item, whose
content had been cleared to "". This permanently lost every Nth
chunk's content, causing random missing words/tokens in the client
output (observed in Roo Code, Open WebUI, etc.).

Fix: deep-copy the current chunk before guardrail processing runs,
then yield the original (unmodified) chunk. The guardrail validation
still executes and can block if it detects a problem, but the stream
content is preserved.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 22:44:30 -08:00
Krish Dholakia
ca34b4ee13
Revert "feat(guardrails): implement team-based isolation guardrails mgmnt (#1…" (#20393)
This reverts commit 76a399ba69.
2026-02-03 20:55:46 -08:00
Xiaohan Fu
2b25d03046
Fix fail-open for grayswan and pass metadata to cygnal api endpoint (#19837)
* fix fail-open for grayswan; pass metadata to cygnal api endpoint; update docs

* pass litellm_metadata to cygnal in payload

* switch error msg to const, and clean exception handling.

* update pyproject.toml as requested

* Revert "update pyproject.toml as requested"

This reverts commit 4eece154d0.
2026-02-03 14:41:31 -08:00
Harshit Jain
76a399ba69
feat(guardrails): implement team-based isolation guardrails mgmnt (#19889)
* feat(guardrails): implement team-based isolation guardrails mgmnt

* fix lint errors

* add allow_team_guardrail_config for admin permissions
2026-02-02 19:14:55 -08:00
Hi120ki
c9757cd0d7 fix(guardrails): populate applied_guardrails when Model Armor blocks content (#20034)
Previously, when Model Armor guardrail blocked a request/response,
the `applied_guardrails` field was not populated in the logs because
`add_guardrail_to_applied_guardrails_header()` was called after the
HTTPException was raised.

This fix moves the `add_guardrail_to_applied_guardrails_header()` call
to before the blocking check in all hooks:
- async_pre_call_hook (pre_call mode)
- async_moderation_hook (during_call mode)
- async_post_call_success_hook (post_call mode)
- async_post_call_streaming_iterator_hook (streaming)

This ensures that even when a guardrail blocks content, the guardrail
name is properly recorded in the logs for observability.

Added regression tests to verify applied_guardrails is populated when
content is blocked.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-02 18:21:44 +05:30
Ishaan Jaffer
66c7233f61 test_get_session_iterator_thread_safety 2026-01-31 12:05:09 -08:00
Harshit Jain
d0939075bc
fix: guardrails issues streaming-response regex (#19901) 2026-01-27 17:36:18 -08:00
Sameer Kankute
0214cb04cd
Merge branch 'main' into litellm_oss_staging_01_26_2026 2026-01-27 17:00:58 +05:30
Sameer Kankute
adf6d7e1db
Merge pull request #19692 from BerriAI/litellm_oss_staging_01_24_2026
Litellm oss staging 01 24 2026
2026-01-27 16:59:28 +05:30
Tamir Kiviti
aa8134fee9
add timeout to onyx guardrail (#19731)
* add timeout to onyx guardrail

* add tests
2026-01-25 23:13:46 -08:00
Harshit Jain
05fdd099ba
fix(presidio): resolve runtime error by handling asyncio loops in bac… (#19714)
* fix(presidio): resolve runtime error by handling asyncio loops in background threads

* add test case for thread safety
2026-01-24 15:36:49 -08:00
jquinter
f43757f71b
Feature/guardrail model argument (#19619)
* [Feat] Add model parameter to Generic Guardrail API

Add model information to guardrail requests, allowing guardrails to make
model-specific security decisions.

Changes:
- Add `model` field to GenericGuardrailAPIInputs TypedDict
- Add `model` field to GenericGuardrailAPIRequest Pydantic model
- Update OpenAI and Anthropic handlers to pass model from request/response
- Add unit tests for model parameter handling

* [Feat] Add model parameter to all guardrail_translation handlers

Extend model parameter support to all guardrail handlers for consistent
implementation across all endpoint types:
- OpenAI Responses API (input/output + streaming)
- OpenAI Image Generation (input only)
- OpenAI Text Completion (input/output)
- OpenAI Text-to-Speech (input only)
- OpenAI Audio Transcription (output only)
- Cohere Rerank (input only)
- Pass-through Endpoints (input/output)
- MCP Server (input only)

This addresses the review feedback requesting consistent model parameter
handling across all guardrail_translation/handler.py files.

---------

Co-authored-by: Igal Boxerman <igal@pillar.security>
2026-01-23 20:48:42 -08:00
davida-ps
7777aeb695
fixing prompt-security's guardrail implementation (#19374)
* Consolidated change

* fix(prompt_security): update message processing to persist sanitized files and filter for API calls

* fix per krrishdholakia suggestion
2026-01-21 20:09:40 -08:00
YutaSaito
eec4ed640b
Revert "Stabilise mock tests" 2026-01-17 06:26:18 +09:00
Sameer Kankute
b0c6a1b308
Merge pull request #19203 from BerriAI/main
merge main
2026-01-16 15:16:29 +05:30
Sameer Kankute
8c454eb74f Fix: mock test tests 2026-01-15 22:02:51 +05:30
Sameer Kankute
4bdda9cc28 Fix: tests/test_litellm/proxy/test_proxy_server.py::test_embedding_input_array_of_tokens 2026-01-15 19:46:35 +05:30
YutaSaito
075f7ebb5f
feat: contextual gap checks, word-form digits (#18301)
Co-authored-by: Krish Dholakia <krrishdholakia@gmail.com>
2026-01-14 17:50:16 +05:30
Sameer Kankute
b2d4f67e17
Merge pull request #19023 from eagle-p/feat/guardrail-clean-error-message
fix(guardrails): use clean error messages for blocked requests
2026-01-14 14:03:16 +05:30
Yuta Saito
82ed6283fa test: reorganize unified guardrail tests into nested classes 2026-01-14 13:38:43 +09:00
Yuta Saito
c5ced033c9 fix: anthropic during call guardrail error 2026-01-14 13:37:01 +09:00
Igal Boxerman
8cff86ff01 fix(guardrails): use clean error messages for blocked requests (#19022)
- Add `should_wrap_with_default_message` parameter to GuardrailRaisedException
- Update Generic Guardrail API to use clean error messages without wrapper
- When should_wrap_with_default_message=False, exception shows the original
  blocked_reason directly (e.g., "pii detected") instead of verbose format
- Update test to verify GuardrailRaisedException is raised with clean message
2026-01-13 11:02:06 +02:00
Igal Boxerman
6bb63525db
fix(guardrails): fix SerializationIterator error and pass tools to guardrail (#18932)
* fix(generic-guardrail-api): fix SerializationIterator error on multimodal requests

When sending multimodal messages (with images) through the Generic Guardrail API,
the `model_dump()` call fails with "Object of type SerializationIterator is not
JSON serializable" error.

Root cause: The `ChatCompletionAssistantMessage` type defines `content` as an
`Iterable` (not just `List`), and Pydantic's `model_dump()` creates a
`SerializationIterator` for iterables which is not JSON serializable.

Fix: Use `model_dump(mode="json")` which properly converts all iterables to
lists and ensures all complex objects are JSON serializable.

* fix(guardrails): pass tools (function definitions) to guardrail inputs

The unified guardrail handler was not passing the `tools` parameter
(function definitions) from the request to the guardrail inputs.
This meant guardrails could not inspect or validate tool definitions.

Added extraction of `data.get("tools")` and inclusion in the
GenericGuardrailAPIInputs passed to `apply_guardrail()`.

* test(guardrails): add tests for tools passed to guardrail

Added tests verifying that tools (function definitions) are correctly
passed to guardrails in the unified guardrail handler:
- test_tools_passed_to_guardrail
- test_multiple_tools_passed_to_guardrail
- test_no_tools_in_request
- test_tools_and_tool_calls_both_passed
2026-01-12 16:27:54 +05:30
Yuta Saito
cef087f88b fix: respect pangea guardrail default_on during initialization 2026-01-11 08:33:31 +09:00
drorIvry
000913fa12
Hotfix - docs qualifire (#18724)
* Hotfix - docs qualifire

* Hotfix - docs qualifire

* Hotfix - docs qualifire

* Hotfix - docs qualifire

* Hotfix - docs qualifire

* Hotfix - docs qualifire

* Hotfix - docs qualifire
2026-01-07 17:23:12 +05:30
Sameer Kankute
9f65f82c56 Fix: ImportError: qualifire package is required for QualifireGuardrail. Install it with: pip install qualifire 2026-01-06 13:52:26 +05:30
drorIvry
b6a64ff99a
feature/ add qualifire guardrails (#18594)
* init guardrails

* init guardrails

* some fixes

* some fixes

* ruff

* some fixes

* some fixes

* some fixes

* some fixes

* some fixes

* some fixes

* docs
2026-01-06 01:34:43 +05:30
Krish Dholakia
b5aa7d1838
feat: Add api_key to GenericGuardrailAPI and set x-api-key header (#18647)
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-01-06 01:05:51 +05:30