mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-08 03:08:45 +00:00
fix(security): restrict MCP semantic filter settings to proxy admins
Add an explicit PROXY_ADMIN check on PATCH /update/mcp_semantic_filter_settings and hide Semantic Filter and Network Settings tabs from non-admin users in the MCP Servers UI. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
b962ce9b09
commit
7292864c05
3 changed files with 44 additions and 8 deletions
|
|
@ -1160,6 +1160,12 @@ async def update_mcp_semantic_filter_settings(
|
|||
Update MCP semantic filter settings in database.
|
||||
Settings will be picked up by all pods within approximately 10 seconds via background polling.
|
||||
"""
|
||||
if user_api_key_dict.user_role != LitellmUserRoles.PROXY_ADMIN:
|
||||
raise HTTPException(
|
||||
status_code=403,
|
||||
detail="Only proxy admins can update MCP semantic filter settings.",
|
||||
)
|
||||
|
||||
result = await _update_litellm_setting(
|
||||
settings=settings,
|
||||
settings_key="mcp_semantic_tool_filter",
|
||||
|
|
|
|||
|
|
@ -2367,3 +2367,29 @@ def test_update_ui_settings_writes_audit_log(monkeypatch):
|
|||
assert after["disable_custom_api_keys"] is True
|
||||
finally:
|
||||
app.dependency_overrides.pop(user_api_key_auth, None)
|
||||
|
||||
|
||||
def test_update_mcp_semantic_filter_settings_requires_proxy_admin(monkeypatch):
|
||||
"""Non-admin callers must not mutate global MCP semantic filter settings."""
|
||||
from litellm.proxy._types import UserAPIKeyAuth
|
||||
from litellm.proxy.auth.user_api_key_auth import user_api_key_auth
|
||||
|
||||
monkeypatch.setattr("litellm.proxy.proxy_server.store_model_in_db", True)
|
||||
|
||||
async def _internal_user_auth():
|
||||
return UserAPIKeyAuth(
|
||||
user_id="internal-user-1",
|
||||
api_key="hashed-internal-key",
|
||||
user_role=LitellmUserRoles.INTERNAL_USER,
|
||||
)
|
||||
|
||||
app.dependency_overrides[user_api_key_auth] = _internal_user_auth
|
||||
try:
|
||||
resp = client.patch(
|
||||
"/update/mcp_semantic_filter_settings",
|
||||
json={"enabled": True, "top_k": 99, "similarity_threshold": 0.01},
|
||||
)
|
||||
assert resp.status_code == 403
|
||||
assert "proxy admin" in resp.json()["detail"].lower()
|
||||
finally:
|
||||
app.dependency_overrides.pop(user_api_key_auth, None)
|
||||
|
|
|
|||
|
|
@ -497,8 +497,8 @@ const MCPServers: React.FC<MCPServerProps> = ({ accessToken, userRole, userID })
|
|||
<Tab>All Servers</Tab>
|
||||
<Tab>Toolsets</Tab>
|
||||
<Tab>Connect</Tab>
|
||||
<Tab>Semantic Filter</Tab>
|
||||
<Tab>Network Settings</Tab>
|
||||
{isAdminRole(userRole) && <Tab>Semantic Filter</Tab>}
|
||||
{isAdminRole(userRole) && <Tab>Network Settings</Tab>}
|
||||
{isAdminRole(userRole) && (
|
||||
<Tab>
|
||||
<span className="flex items-center gap-2">
|
||||
|
|
@ -652,12 +652,16 @@ const MCPServers: React.FC<MCPServerProps> = ({ accessToken, userRole, userID })
|
|||
<TabPanel>
|
||||
<MCPConnect />
|
||||
</TabPanel>
|
||||
<TabPanel>
|
||||
<MCPSemanticFilterSettings accessToken={accessToken} />
|
||||
</TabPanel>
|
||||
<TabPanel>
|
||||
<MCPNetworkSettings accessToken={accessToken} />
|
||||
</TabPanel>
|
||||
{isAdminRole(userRole) && (
|
||||
<TabPanel>
|
||||
<MCPSemanticFilterSettings accessToken={accessToken} />
|
||||
</TabPanel>
|
||||
)}
|
||||
{isAdminRole(userRole) && (
|
||||
<TabPanel>
|
||||
<MCPNetworkSettings accessToken={accessToken} />
|
||||
</TabPanel>
|
||||
)}
|
||||
{isAdminRole(userRole) && (
|
||||
<TabPanel>
|
||||
<MCPSubmissionsTab accessToken={accessToken} />
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue