-
-
Notifications
You must be signed in to change notification settings - Fork 4.9k
Description
What happened?
When creating a team under an organization that has restricted models, leaving the model list empty allows the team to have "all proxy models" access, bypassing the organization's model restrictions.
Current Behavior
- Organization is created with restricted models:
["gpt-4", "gpt-3.5-turbo"] - Team is created under that organization with
models: [](empty list) or models not specified - Team is created successfully with no validation error
- The team effectively has access to all proxy models (empty list = all models)
- This exceeds the parent organization's model restrictions
Expected Behavior
When creating/updating a team under an organization with restricted models:
- Empty or unspecified model list should be rejected with an error message indicating that models must be explicitly specified
all-proxy-modelsshould be rejected since it would give access beyond the org's restrictions- A new
all-org-modelsspecial value should be supported to allow teams to inherit the organization's model list (similar to howall-team-modelsworks for keys)
This is consistent with how keys work under teams - the UI doesn't allow an empty model list, users must select "All Team Models" or specific models.
Root Cause
In _check_org_team_limits() (litellm/proxy/management_endpoints/team_endpoints.py), the model validation logic is:
if data.models is not None and len(org_table.models) > 0:
for m in data.models:
if m not in org_table.models:
raise HTTPException(...)This validation:
- Skips entirely if
data.modelsisNone - Iterates 0 times if
data.modelsis[](empty list) - Only validates explicit models against the org's allowed list
- No explicit check for
all-proxy-models: If an organization has["all-proxy-models"]in its model list, a team requestingall-proxy-modelswould pass validation (since the string is in the org's list). However,all-proxy-modelsshould always be rejected for org-scoped teams because it creates a direct binding to all proxy models rather than inheriting from the organization. If the org's model list is later changed to be more restrictive, the team would still have access to all models.
The correct validation exists in validate_team_org_change() (used for team updates changing org), but is not applied during team creation.
Steps to Reproduce
-
Create an organization with restricted models:
curl -X POST 'http://localhost:4000/organization/new' \ -H 'Authorization: Bearer sk-...' \ -H 'Content-Type: application/json' \ -d '{"organization_alias": "test-org", "models": ["gpt-4", "gpt-3.5-turbo"]}'
-
Create a team under that organization with empty models:
curl -X POST 'http://localhost:4000/team/new' \ -H 'Authorization: Bearer sk-...' \ -H 'Content-Type: application/json' \ -d '{"team_alias": "test-team", "organization_id": "<org-id>", "models": []}'
-
Observe: Team is created successfully (should fail with validation error)
Proposed Fix
In _check_org_team_limits(), add validation to reject empty/unspecified models when org has restrictions:
if len(org_table.models) > 0:
# Check for empty/unspecified models
if data.models is None or len(data.models) == 0:
raise HTTPException(
status_code=400,
detail={
"error": f"Team must specify models when organization has restricted models. Use 'all-org-models' to inherit organization's models, or select specific models from: {org_table.models}"
},
)
# Check for all-proxy-models (not allowed for org-scoped teams)
if SpecialModelNames.all_proxy_models.value in data.models:
raise HTTPException(
status_code=400,
detail={
"error": "Cannot use 'all-proxy-models' for org-scoped teams. Use 'all-org-models' to inherit organization's models."
},
)
# Allow all-org-models special value
if "all-org-models" not in data.models:
# Validate explicit models against org's allowed list
for m in data.models:
if m not in org_table.models:
raise HTTPException(...)Additionally:
- Add
all_org_models = "all-org-models"toSpecialModelNamesenum - Add runtime resolution of
all-org-modelsto org's models inmodel_checks.py
Relevant log output
Are you a ML Ops Team?
No