Skip to content

fix(proxy): enforce organization boundaries in admin operations#25829

Closed
stuxf wants to merge 2 commits intoBerriAI:litellm_yj_apr15from
stuxf:fix/org-boundary-enforcement
Closed

fix(proxy): enforce organization boundaries in admin operations#25829
stuxf wants to merge 2 commits intoBerriAI:litellm_yj_apr15from
stuxf:fix/org-boundary-enforcement

Conversation

@stuxf
Copy link
Copy Markdown
Collaborator

@stuxf stuxf commented Apr 16, 2026

Relevant issues

Fixes inconsistent organization boundary checks in team listing and user creation flows.

Pre-Submission checklist

  • I have Added testing in the tests/test_litellm/ directory, Adding at least 1 test is a hard requirement - see details
  • My PR passes all unit tests on make test-unit
  • My PR's scope is as isolated as possible, it only solves 1 specific problem
  • I have requested a Greptile review by commenting @greptileai and received a Confidence Score of at least 4/5 before requesting a maintainer review

Type

🐛 Bug Fix

Changes

1. Validate org admin role against all requested organizations

_user_is_org_admin() previously returned True if the caller was admin of any one of the listed organizations. Now validates against all of them — an org admin of org-A cannot perform operations targeting org-B.

2. Scope team list queries to caller's organizations

_build_team_list_where_conditions() previously dropped the organization filter when a user_id parameter was provided, returning teams across all organizations. Now always applies the org filter for org admins.

_authorize_and_filter_teams() (legacy path) previously fetched teams outside the caller's orgs if the target user was a member. Now only returns teams within the caller's permitted organizations.

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 16, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
litellm Ready Ready Preview, Comment Apr 16, 2026 2:08am

Request Review

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 16, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 16, 2026

Greptile Summary

This PR fixes two related security issues in the proxy's organization boundary enforcement: (1) _user_is_org_admin() changed from any() to all(), preventing a cross-org privilege escalation where an org-A admin could gain access by including org-A alongside org-B in a multi-org request; (2) _build_team_list_where_conditions() and _authorize_and_filter_teams() now always apply the org-scope filter even when a user_id is also provided, preventing an org admin from seeing teams outside their permitted orgs via the user_id filter. The fixes are accompanied by regression tests covering both the escalation case and the multi-org legitimate admin case.

Confidence Score: 5/5

Safe to merge — both security fixes are logically correct, well-tested, and limited in scope.

All findings are P2 or lower. The two core behavioral changes (all() in org admin check, always-on org filter in team listing) are correct and close real privilege-escalation paths. The regression tests added cover the exact scenarios the old code mishandled. Remaining diff is Black reformatting with no logic impact.

No files require special attention.

Important Files Changed

Filename Overview
litellm/proxy/auth/auth_checks_organization.py Changed _user_is_org_admin from any()-based loop to an all() set-membership check; correctly guards the empty-list vacuous-truth case that already existed. No issues.
litellm/proxy/management_endpoints/team_endpoints.py Removed the not user_id guard in _build_team_list_where_conditions so org-scope filter is always applied; removed cross-org member-team fetch in legacy _authorize_and_filter_teams. Remaining diffs are Black-only reformatting.
tests/test_litellm/proxy/auth/test_route_checks.py Adds test_org_admin_cannot_escalate_to_other_org and test_org_admin_of_multiple_orgs_can_operate_on_both regression tests; remaining changes are Black reformatting of existing tests.
tests/test_litellm/proxy/management_endpoints/test_team_endpoints.py Updates test_list_team_v2_org_admin_with_user_id_returns_user_teams assertion to expect both team_id and organization_id filters in the DB query, correctly reflecting the new behaviour. Remaining changes are Black reformatting.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Org admin calls /team/list or admin op] --> B{request includes\norganization_id / organizations?}
    B -- No --> C[return False\n no orgs to act on]
    B -- Yes --> D[Build admin_org_ids set\nfrom caller memberships]
    D --> E{all candidate org IDs\n in admin_org_ids?}
    E -- No --> F[Access Denied\ncross-org escalation blocked]
    E -- Yes --> G[Build team list query]
    G --> H{user_id filter\nprovided?}
    H -- No --> I[WHERE organization_id IN admin_orgs\nReturn all org teams]
    H -- Yes --> J[WHERE organization_id IN admin_orgs\nAND team_id IN user_teams\nReturns only org-scoped user teams]
    J --> K[Result scoped to\ncaller's orgs only]
    I --> K
Loading

Reviews (2): Last reviewed commit: "test: add regression tests for cross-org..." | Re-trigger Greptile

Comment thread litellm/proxy/auth/auth_checks_organization.py
Validate org admin role against all requested organizations instead
of returning on first match. Scope team list queries to the caller's
permitted organizations when filtering by user_id.
Verify that an org admin of org-A cannot operate on org-B, and that
an admin of both orgs can operate on both.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants