Commit graph

42355 commits

Author SHA1 Message Date
yuneng-jiang
50a6324d58
Merge pull request #25904 from stuxf/fix/org-boundary-enforcement
fix(proxy): enforce organization boundaries in admin operations
2026-04-17 12:13:57 -07:00
Yuneng Jiang
246a5bd158
Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_yj_apr16 2026-04-17 12:11:51 -07:00
harish-berri
b3ccbb96ba resolve lint errors 2026-04-17 19:06:23 +00:00
harish-berri
9d10ebf49c fix(prometheus): restore labeled-counter tests; tolerate UserAPIKeyLabelValues kwargs 2026-04-17 18:16:38 +00:00
harish-berri
5df3287016 fixing backwards compatibility for tests 2026-04-17 18:08:48 +00:00
ryan-crabbe-berri
c23ce918cd
Merge pull request #25878 from BerriAI/litellm_refactor-pkce-dedup
Refactor: extract shared PKCE helpers into utils/pkce.ts
2026-04-17 10:26:22 -07:00
ryan-crabbe-berri
2b5bf4cba8
Merge pull request #25882 from BerriAI/litellm_fix-latency-config-empty-defaults
fix: return None for routing_strategy_args when strategy is not latency-based
2026-04-17 10:25:42 -07:00
harish-berri
62a189f57c added comments to disable repr 2026-04-17 17:04:31 +00:00
harish-berri
1eb6be9d44 Removed slots attr which was causing test failures in python 3.9.
Improved sentinel handling flagged by greptile
2026-04-17 17:00:13 +00:00
Cesar Garcia
840f95633c
Merge branch 'main' into fix/greptile-logo-quality 2026-04-17 11:21:28 -03:00
Sameer Kankute
b59400145c
Merge pull request #25949 from BerriAI/litellm_internal_staging
Some checks failed
Unit Tests: Proxy DB Operations / proxy-db (auth-checks, tests/proxy_unit_tests/test_auth_checks.py tests/proxy_unit_tests/test_user_api_key_auth.py, 20, 8) (push) Has been cancelled
Unit Tests: Proxy DB Operations / proxy-db (key-generation, tests/proxy_unit_tests/test_key_generate_prisma.py, 30, 0) (push) Has been cancelled
Unit Tests: Proxy DB Operations / proxy-db (remaining, tests/proxy_unit_tests --ignore=tests/proxy_unit_tests/test_key_generate_prisma.py --ignore=tests/proxy_unit_tests/test_auth_checks.py --ignore=tests/proxy_unit_tests/test_user_api_key_auth.py, 30, 8) (push) Has been cancelled
Unit Tests: Security / security (push) Has been cancelled
merge litellm_internal_staging
2026-04-17 19:01:08 +05:30
Sameer Kankute
d5c8e19970
Fix mypy error
Some checks failed
Unit Tests: Proxy DB Operations / proxy-db (auth-checks, tests/proxy_unit_tests/test_auth_checks.py tests/proxy_unit_tests/test_user_api_key_auth.py, 20, 8) (push) Has been cancelled
Unit Tests: Proxy DB Operations / proxy-db (key-generation, tests/proxy_unit_tests/test_key_generate_prisma.py, 30, 0) (push) Has been cancelled
Unit Tests: Proxy DB Operations / proxy-db (remaining, tests/proxy_unit_tests --ignore=tests/proxy_unit_tests/test_key_generate_prisma.py --ignore=tests/proxy_unit_tests/test_auth_checks.py --ignore=tests/proxy_unit_tests/test_user_api_key_auth.py, 30, 8) (push) Has been cancelled
Unit Tests: Security / security (push) Has been cancelled
2026-04-17 18:59:11 +05:30
Sameer Kankute
27877b4b06
Merge pull request #25945 from BerriAI/litellm_internal_staging
merge litellm_internal_staging
2026-04-17 18:48:03 +05:30
Sameer Kankute
2f4b7bcb81
Merge pull request #25944 from BerriAI/litellm_internal_staging
Some checks failed
Unit Tests: Proxy DB Operations / proxy-db (auth-checks, tests/proxy_unit_tests/test_auth_checks.py tests/proxy_unit_tests/test_user_api_key_auth.py, 20, 8) (push) Has been cancelled
Unit Tests: Proxy DB Operations / proxy-db (key-generation, tests/proxy_unit_tests/test_key_generate_prisma.py, 30, 0) (push) Has been cancelled
Unit Tests: Proxy DB Operations / proxy-db (remaining, tests/proxy_unit_tests --ignore=tests/proxy_unit_tests/test_key_generate_prisma.py --ignore=tests/proxy_unit_tests/test_auth_checks.py --ignore=tests/proxy_unit_tests/test_user_api_key_auth.py, 30, 8) (push) Has been cancelled
Unit Tests: Security / security (push) Has been cancelled
merge litellm_internal_staging
2026-04-17 18:41:59 +05:30
Sameer Kankute
b19951a0d4
Add litellm_metadata support 2026-04-17 18:32:33 +05:30
Sameer Kankute
96882e04e7
Merge pull request #25942 from BerriAI/litellm_internal_staging
Some checks failed
Unit Tests: Proxy DB Operations / proxy-db (auth-checks, tests/proxy_unit_tests/test_auth_checks.py tests/proxy_unit_tests/test_user_api_key_auth.py, 20, 8) (push) Has been cancelled
Unit Tests: Proxy DB Operations / proxy-db (key-generation, tests/proxy_unit_tests/test_key_generate_prisma.py, 30, 0) (push) Has been cancelled
Unit Tests: Proxy DB Operations / proxy-db (remaining, tests/proxy_unit_tests --ignore=tests/proxy_unit_tests/test_key_generate_prisma.py --ignore=tests/proxy_unit_tests/test_auth_checks.py --ignore=tests/proxy_unit_tests/test_user_api_key_auth.py, 30, 8) (push) Has been cancelled
Unit Tests: Security / security (push) Has been cancelled
merge litellm_internal_staging
2026-04-17 18:18:12 +05:30
Sameer Kankute
76c69bb933
fix(proxy): avoid duplicate reasoning capability lookup
Compute supports_reasoning once per non-wildcard health-check resolution path and update the stale default-max-tokens test docstring.

Made-with: Cursor
2026-04-17 12:49:31 +05:30
Sameer Kankute
d86c6a5b2f
fix(proxy): prioritize reasoning health check token defaults
Apply reasoning-first precedence for background health-check max tokens, parse reasoning env as optional, and raise non-wildcard fallback max_tokens from 1 to 5 for better reliability.

Made-with: Cursor
2026-04-17 12:36:58 +05:30
Sameer Kankute
d881a48220
fix(anthropic): strip Gemini thought suffix from streaming tool_use id
Gemini tool call ids embed thought signatures as call_*__thought__*; the
Anthropic /v1/messages SSE adapter now exposes a clean id and moves the
signature to provider_specific_fields.signature for round-trip.

Fixes #25836.

Made-with: Cursor
2026-04-17 11:29:20 +05:30
harish-berri
95824ddea6 removing pydantic base model __repr__, __repr_str__ and __repr_args__ function calls from the hotpath and replacing them with lightweight python native dataclasses.
TODO: Override pydantic __repr__ class in all pydantic objects and compare performance.

Improves CPU time perf by 2X in the hotpath
2026-04-17 05:12:51 +00:00
Sameer Kankute
52fde57df7
feat(docs): align fenced code padding on blog and doc pages
- Set --ifm-pre-padding to 1.25rem for consistent code block inset
- Restore horizontal padding for line-numbered Docusaurus blocks
- Scope pre/code resets via article .markdown so blog chip styles
  no longer strip CodeBlock inner padding on Prism fences

Made-with: Cursor
2026-04-17 10:04:03 +05:30
Yuneng Jiang
bcb2ea63f1
fix: add explicit admin bypass to agent access checks for consistency 2026-04-16 21:12:09 -07:00
Stefano Romanò
f69b9d6564
Add capability to override default GitHub Copilot authentication endp… (#25915)
* Add capability to override default GitHub Copilot authentication endpoints

This feature adds support for GitHub Enterprise subsriptions with custom domain/data ownership (which use a different URL compared to standard accounts)

* Update documentation with new parameters

* Move access token URL and Client ID retrieval outside for loop

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

* Fix spurious comment from Greptile review

* Align api_base retrieval behavior across chat and embedding transformations

* Add missing GitHub Copilot client ID parameter in docs

* Update website documentation with newer options for GitHub Enterprise Copilot

* Fix default value for Copilot client ID in docs

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-04-16 21:04:38 -07:00
michelligabriele
cd92b04476
fix(ocr): add missing Mistral OCR params to allowlist (#25858) 2026-04-16 21:00:16 -07:00
Sameer Kankute
3ef362289b
Add support for grok-4.20-0309-reasoning model 2026-04-17 08:49:59 +05:30
shivam
a84c27674f
refactor(azure-ocr): move urllib.parse.quote to module imports
Remove inline import in get_complete_url; quote is stdlib with no circular
import risk per project style.

Made-with: Cursor
2026-04-16 19:28:32 -07:00
shivam
089ca5fc0f
fix(azure-ocr): reject mixed bool+int in pages list validation
Use any() instead of all() for bool check so lists like [True, 1, 2]
raise ValueError; bool is a subclass of int so all(int) alone was insufficient.

Made-with: Cursor
2026-04-16 19:27:14 -07:00
shivam
b6d5728134
add support for pages param 2026-04-16 19:07:02 -07:00
yuneng-jiang
850fe595ac
Merge pull request #25924 from BerriAI/litellm_internal_staging
Some checks failed
Read Version from pyproject.toml / read-version (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
Unit Tests: Security / security (push) Has been cancelled
GitHub Actions Security Analysis / zizmor (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
CodSpeed Benchmarks / benchmarks (push) Has been cancelled
Helm unit test / unit-test (push) Has been cancelled
Unit Tests: Proxy DB Operations / proxy-db (auth-checks, tests/proxy_unit_tests/test_auth_checks.py tests/proxy_unit_tests/test_user_api_key_auth.py, 20, 8) (push) Has been cancelled
Unit Tests: Proxy DB Operations / proxy-db (key-generation, tests/proxy_unit_tests/test_key_generate_prisma.py, 30, 0) (push) Has been cancelled
Unit Tests: Proxy DB Operations / proxy-db (remaining, tests/proxy_unit_tests --ignore=tests/proxy_unit_tests/test_key_generate_prisma.py --ignore=tests/proxy_unit_tests/test_auth_checks.py --ignore=tests/proxy_unit_tests/test_user_api_key_auth.py, 30, 8) (push) Has been cancelled
[Infra] Promote Internal Staging to main
2026-04-16 18:21:51 -07:00
yuneng-jiang
bf7b7f7f60
Merge pull request #25872 from BerriAI/yj_bump_apr16_2
Some checks are pending
Unit Tests: Proxy DB Operations / proxy-db (key-generation, tests/proxy_unit_tests/test_key_generate_prisma.py, 30, 0) (push) Waiting to run
Unit Tests: Proxy DB Operations / proxy-db (auth-checks, tests/proxy_unit_tests/test_auth_checks.py tests/proxy_unit_tests/test_user_api_key_auth.py, 20, 8) (push) Waiting to run
Unit Tests: Proxy DB Operations / proxy-db (remaining, tests/proxy_unit_tests --ignore=tests/proxy_unit_tests/test_key_generate_prisma.py --ignore=tests/proxy_unit_tests/test_auth_checks.py --ignore=tests/proxy_unit_tests/test_user_api_key_auth.py, 30, 8) (push) Waiting to run
Unit Tests: Security / security (push) Waiting to run
bump: version 1.83.8 → 1.83.9
2026-04-16 17:56:44 -07:00
yuneng-jiang
f07aadc3f9
Merge pull request #25873 from BerriAI/yj_extras_bump_apr16
bump: proxy extras version 0.4.65 → 0.4.66
2026-04-16 17:56:33 -07:00
yuneng-jiang
724926fba9
Merge pull request #25920 from BerriAI/litellm_/amazing-almeida
[Test] Mock Bedrock Moonshot tests + [Fix] TogetherAIConfig recursion
2026-04-16 17:55:58 -07:00
user
e3b55794ce
fix(proxy): close /organization member_delete + role-escalation gaps
Audit-B #7 and #8.

1. /organization/member_delete was not in org_admin_only_routes, so it
   fell through to management_routes/self_managed_routes and let any
   caller that reached the route delete arbitrary org memberships
   without the organization_role_based_access_check that member_add
   and member_update trigger. Adding it to org_admin_only_routes
   applies the same ORG_ADMIN-of-target-org gate.

2. /organization/member_update had no validation that the target user
   was not a global PROXY_ADMIN. An org-admin of any org could alter
   a PROXY_ADMIN user's per-org role. Reject this unless the caller
   is PROXY_ADMIN.
2026-04-17 00:44:24 +00:00
Yuneng Jiang
00bac08e01
[Test] Mock remaining live Bedrock Moonshot tests
Extends the prior moonshot mocking to cover every inherited
BaseLLMChatTest test that still made a live AWS Bedrock call. Adds
request-body assertions for each override.

New overrides:

- test_content_list_handling: verifies the outgoing body round-trips
  user content in list-of-text form; asserts response.choices[0].
  message.content parses back from the canned response.
- test_pydantic_model_input: verifies a pydantic Message input does
  not raise and produces a parseable response.
- test_response_format_type_text_with_tool_calls_no_tool_choice:
  verifies tools are forwarded and response_format + drop_params do
  not break the call.
- test_streaming: verifies stream=True routes to the
  invoke-with-response-stream endpoint. Bedrock invoke streaming is
  intercepted at the make_sync_call import site rather than via the
  caller-supplied client, because CustomStreamWrapper.fetch_sync_stream
  invokes the stored make_call partial with
  client=litellm.module_level_client, overriding any client passed by
  the caller.

Extracts a shared _make_moonshot_response helper and a
_invoke_with_mocked_post harness so all the sync mocks share one
canned response body.

After this change TestBedrockMoonshotInvoke runs 23 passed, 29
skipped, 0 live-callers, all in under 1s locally.
2026-04-16 17:43:43 -07:00
user
c7c3df2b02
fix(proxy): extend /key/update admin check to non-budget fields
Audit-B #2. _check_key_admin_access was gated on max_budget/spend
changes only, which meant a non-admin caller could blanket-rewrite
any OTHER field on any key (key_alias, models, tpm_limit, rpm_limit,
metadata, tags, allowed_routes, guardrails, blocked, duration,
permissions, auto_rotate, access_group_ids, object_permission, …)
as long as they avoided budget/spend. Example attack:

  POST /key/update {
    key: sk-victim-in-org-B,
    models: [],
    blocked: true,
    organization_id: org-A,
  }

The caller is org-admin of org-A, which satisfies the route gate;
the handler then wipes models and blocks the victim's key.

Policy after this fix:
- PROXY_ADMIN: always allowed.
- Key OWNER (matching user_id): allowed for non-budget fields;
  budget/spend changes still require team/org admin.
- Everyone else: must pass _check_key_admin_access (PROXY_ADMIN /
  key-owner / team-admin / org-admin of the key).

Regression test confirms a non-owner INTERNAL_USER cannot rewrite
key_alias/blocked on someone else's key; existing test covers the
owner-can-update-alias case; existing test covers
internal-user-cannot-modify-max-budget.
2026-04-17 00:41:00 +00:00
user
662d05531d
fix(proxy): close three more org-boundary escape paths
Continuation of Veria E3NpkuAd / Audit-B hardening. All three are the
same anti-pattern PR #25904 already addressed for _user_is_org_admin
and /user/delete: route-level gate trusts a caller-supplied scope
field, handler operates on a different scope.

1. /user/update no longer silently creates a user when the target
   email doesn't exist. Pre-fix, an org admin could supply a fresh
   email + caller-chosen budget/models/metadata; the INSERT path
   created the user with no org attachment, bypassing /user/new's
   org/team authorization. Now require PROXY_ADMIN for the create
   branch; return 404 otherwise. Also fixes /user/bulk_update because
   it dispatches through the same _update_single_user_helper.

2. /team/bulk_member_add with all_users=true restricted to PROXY_ADMIN.
   The flag pulls every user in the database into the target team,
   ignoring org scope — any team admin could use it to capture every
   user across every org into their team.

3. /team/update now verifies destination-org admin rights. When the
   request carries an organization_id that differs from the team's
   current org, an org admin of the caller's current org could
   previously relocate the team into any other org (draining their
   resources, or capturing a team they once administered). Require
   PROXY_ADMIN or org-admin of the DESTINATION org for the relocation.

Regression tests for #1 and #3; #2 covered by the existing bulk_add
suite after the gate addition.
2026-04-17 00:36:28 +00:00
Yuneng Jiang
cdb29946eb
fix: align agent endpoint and routing permission checks with existing pattern 2026-04-16 17:22:28 -07:00
Yuneng Jiang
95e1babf67
[Fix] TogetherAIConfig.get_supported_openai_params recursion
TogetherAIConfig.get_supported_openai_params called get_model_info(),
whose first line calls litellm.get_supported_openai_params() — which for
together_ai routes straight back into this method. The recursion only
terminated when Python's recursion limit was hit or when
_get_model_info_helper raised "not mapped" at the deepest level. Either
way the try/except caught it, so the bug stayed silent — but the cycle
ran ~332 deep every time, emitting hundreds of DEBUG log lines per
call. Surfaced as "infinite loop" in CI when the success_handler thread
emitted that log spam against an already-closed stderr during test
teardown.

Replace the get_model_info() call with supports_function_calling(),
which uses _get_model_info_helper directly and does not call
get_supported_openai_params. Measured drop from 332 to 2
_get_model_info_helper calls per first uncached lookup.

Also swap the test model from Qwen/Qwen3.5-9B (not in model_cost map)
back to a mapped serverless model, Qwen/Qwen2.5-7B-Instruct-Turbo. The
mapping gap is what made the recursion's tail end raise up into the
success handler during teardown in the first place.
2026-04-16 17:20:58 -07:00
user
132063289f
fix(proxy): strip root-level data['tags'] alongside metadata tags
Greptile P2. The admin-inject gate only removed tags from data['metadata']
and data['litellm_metadata'];  and the
policy engine read  directly, so a caller without
allow_client_tags could still drive tag-based policy decisions by moving
tags to the body root. Also strip the root key in the same branch.
2026-04-17 00:20:52 +00:00
user
8c0668f105
perf: batch target membership lookup in delete_user to avoid N+1
Greptile P1 on the /user/delete fix. Per CLAUDE.md 'No N+1 queries',
move the find_many inside the per-user loop to a single batched
fetch with {'user_id': {'in': data.user_ids}} before the loop, then
distribute to a per-user set in memory.
2026-04-17 00:17:57 +00:00
harish-berri
69f2bc1d41 amortize label context call, by reducing number of label_factory calls, reduces CPU time by ~5% 2026-04-17 00:16:37 +00:00
user
467166fdd7
fix(proxy): enforce per-target org authorization on /user/delete
Veria admin-queue finding E3NpkuAd, Audit-B #1. The route-level gate
accepts this call when the caller is PROXY_ADMIN or ORG_ADMIN of any
org named in request_data["organization_id"]/["organizations"]. The
handler processes data.user_ids without cross-checking whether those
users belong to the caller's administered orgs, so an org-admin of
org-A could delete users in org-B via:
  {"user_ids": ["victim_in_org_B"], "organization_id": "org-A"}

Add per-target authorization: org-admins may only delete users whose
entire org membership is within their admin scope; targets with any
org outside scope (or no org at all) require PROXY_ADMIN.

Regression test confirms an ORG_ADMIN call fails with 403 and no
cascade delete_many runs.
2026-04-17 00:11:00 +00:00
user
b4e98d190a
fix(proxy): close 6 more metadata/tag variant bypasses
Post-merge audit found 6 adjacent variants of the VERIA-28 class. All
fixed here with regression tests:

1. Strip widened from 3 named keys to the full user_api_key_* prefix.
   The proxy writes a dozen user_api_key_* fields (user_id, alias,
   spend, team_id, request_route, end_user_id, …) into
   data[_metadata_variable_name]; the 3-key strip left the rest
   exploitable for identity/spend forgery in audit logs and guardrails.

2. proxy_server_request['body'] snapshot moved to AFTER the strip.
   Was captured at line ~990 before the strip ran, so
   standard_logging_object, lago, and spend_tracking readers saw the
   attacker-forged payload even though the live data dict was clean.

3. get_tags_from_request_body (auth-time) now coerces JSON-string
   metadata via safe_json_loads. Previously crashed with
   AttributeError on string metadata (DoS; potential RBAC bypass if
   a caller swallowed the exception).

4. get_end_user_id_from_request_body coerces JSON-string
   metadata/litellm_metadata. Previously isinstance(dict) guard
   caused end-user budget attribution to be silently skipped when
   the caller sent metadata as a JSON string.

5. Four hand-rolled 'if data.get("metadata") is None: data["metadata"] = {}'
   blocks in proxy_server.py (7160, 7341, 7590, 11375) now guard on
   isinstance(dict). They crashed with TypeError when metadata was a
   JSON string (DoS).

6. _get_admin_metadata defensively guards with isinstance(dict);
   previously AttributeError'd on any leaked string metadata.

Also hoists the inline safe_json_loads import in _guardrail_modification_check
to module level per CLAUDE.md style.
2026-04-17 00:08:40 +00:00
Yuneng Jiang
e1da27dc0a
Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_/amazing-almeida
# Conflicts:
#	tests/test_litellm/llms/bedrock/messages/invoke_transformations/test_anthropic_claude3_transformation.py
2026-04-16 16:54:36 -07:00
Yuneng Jiang
35a186a133
[Test] Mock live Bedrock Moonshot tests in llm_translation
Three tests inherited by TestBedrockMoonshotInvoke from BaseLLMChatTest
make live AWS Bedrock completion calls: test_developer_role_translation,
test_message_with_name, and test_completion_cost. These have been
crashing llm_translation_testing CI workers (reported as "failed on
setup with worker 'gwN' crashed").

Replace each with a mocked override that intercepts the outgoing
request via HTTPHandler.post / AsyncHTTPHandler.post patching:

- test_developer_role_translation asserts the outgoing body maps the
  developer role to system (LiteLLM's translation for non-OpenAI
  providers).
- test_message_with_name asserts the outgoing body preserves the user
  message.
- test_completion_cost returns a canned moonshot-shaped response body
  with usage and asserts response_cost > 0 against the local model
  cost map.

Follows the existing HTTPHandler + patch.object(client, "post") pattern
used in test_bedrock_gpt_oss.py and test_bedrock_completion.py. No
network traffic; the three tests now complete in ~0.3s.
2026-04-16 16:51:49 -07:00
yuneng-jiang
1cd3ea809a
Merge pull request #25917 from BerriAI/litellm_xpass_header_restriction
[Fix] Tighten api_key value check in credential validation
2026-04-16 16:39:05 -07:00
user
76aa97f77b
fix(proxy): close three variant metadata/tag injection paths
Close three variant bypasses adjacent to VERIA-28 found during post-fix
variant audit:

1. _guardrail_modification_check had the same isinstance(dict) bypass
   Veria-AI just flagged on the pre-call strip. A caller sending
   `{"metadata": "{…}"}` as a JSON-encoded string (multipart/form-data
   or extra_body) skipped the guard, got parsed to dict downstream, and
   reached guardrail logic with bypass flags intact. Coerce strings via
   safe_json_loads before evaluating.

2. The allow_client_tags strip only covered body metadata.tags and
   litellm_metadata.tags — caller-supplied tags arriving via the
   x-litellm-tags header or root-level data["tags"] bypassed it. Gate
   add_request_tag_to_metadata's result on the same flag.

3. requester_metadata was deepcopied BEFORE the strip, so attacker
   injections (user_api_key_metadata shadows, disallowed tags,
   _pipeline_managed_guardrails) persisted in the snapshot. The PANW
   guardrail (and any future consumer) trusting requester_metadata
   would see forged values. Move the deepcopy to after the strip.

Regression tests added for each.
2026-04-16 23:35:26 +00:00
user
dc8e03b91f
fix(proxy): expand _guardrail_modification_check to cover all bypass keys
Per VERIA-28's secondary recommendation. The existing check only gated
metadata.guardrails. User-supplied values for disable_global_guardrails
(plural and the original singular typo variant) and opted_out_global_guardrails
are already silently ignored by _get_admin_metadata at read time, but the
silent-ignore makes diagnosis confusing and relies on one specific read
site catching them.

Reject at auth time with a 403 when any of:
- guardrails list (existing)
- disable_global_guardrails (new)
- disable_global_guardrail (new — historical singular-key variant)
- opted_out_global_guardrails (new)

are present in metadata, litellm_metadata, or at the request root, and the
caller's team lacks can_modify_guardrails. Defense in depth: the strip at
the pre-call layer still runs; this check fails loudly one layer earlier
so operators see an explicit 403 rather than a silent-ignore.
2026-04-16 23:14:05 +00:00
Yuneng Jiang
f8f356fac3
test: add parametrized tests for api_key value handling in credential check 2026-04-16 16:08:47 -07:00
Yuneng Jiang
2ea3fafb68
fix: tighten api_key value check in credential validation 2026-04-16 16:01:07 -07:00