mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-05 08:07:05 +00:00
test(e2e): cover alias MCP grant persisting verbatim on key generate
A single-instance run cannot reproduce the two-region setup, but the regression is fully visible in one: the alias must survive to /key/info unrewritten, and the alias-granted key must still list the server's tools. The broken write path stored the resolved server id instead.
This commit is contained in:
parent
0d7035989c
commit
7a761ccf5a
3 changed files with 38 additions and 0 deletions
|
|
@ -15,6 +15,14 @@
|
|||
assertions: [access_group_scoped]
|
||||
source: "test_mcp_access_group_e2e.py"
|
||||
rationale: "A key granted an MCP access group sees the tagged server's tools; a key with a different group does not. Access-group-scoped tool selection at key creation"
|
||||
- id: mcp.list_tools.api_key.alias_grant_persists
|
||||
module: mcp
|
||||
tier: P1
|
||||
operation: list_tools
|
||||
auth_family: api_key
|
||||
assertions: [alias_grant_persists]
|
||||
source: "object_permission_utils.py validate_key_mcp_servers_against_team"
|
||||
rationale: "A key granted an MCP server by alias keeps the alias verbatim in its stored object_permission (shared-DB multi-region instances each resolve it to their local server id at read time) and still lists the server's tools"
|
||||
- id: mcp.list_tools.api_key.denied_without_permission
|
||||
module: mcp
|
||||
tier: P0
|
||||
|
|
|
|||
|
|
@ -30,6 +30,35 @@ def _key(client: McpClient, resources: ResourceManager, *, mcp_servers: list[str
|
|||
return key
|
||||
|
||||
|
||||
class TestMcpKeyGrantByAlias:
|
||||
@pytest.mark.covers("mcp.list_tools.api_key.alias_grant_persists")
|
||||
def test_alias_grant_persists_verbatim_and_lists_tools(
|
||||
self,
|
||||
client: McpClient,
|
||||
resources: ResourceManager,
|
||||
) -> None:
|
||||
"""A key granted an MCP server by its alias must store the alias, not the
|
||||
resolved server_id: in a shared-DB multi-region deployment each instance
|
||||
derives a different id for the same config server, so only the alias
|
||||
grants access on every region. The same key must still see the server's
|
||||
tools, proving the alias grant is honored at request time."""
|
||||
server_id = register_datadog_mcp(client, resources)
|
||||
client.await_registered(server_id)
|
||||
alias = next(row.alias for row in client.registered_servers() if row.server_id == server_id)
|
||||
assert alias, f"registered server {server_id} has no alias to grant by"
|
||||
|
||||
key = _key(client, resources, mcp_servers=[alias])
|
||||
|
||||
stored = client.proxy.key_info(key).object_permission
|
||||
assert stored is not None and stored.mcp_servers == [alias], (
|
||||
f"alias grant was rewritten before persisting (expected [{alias!r}]): "
|
||||
f"{stored.mcp_servers if stored else None}. A stored server_id is region-local "
|
||||
f"and breaks the grant on every other instance sharing this database"
|
||||
)
|
||||
|
||||
_ = client.await_tool(key, server_id, SEARCH_LOGS_TOOL)
|
||||
|
||||
|
||||
class TestMcpKeyWithoutAccessIsDenied:
|
||||
@pytest.mark.covers("mcp.list_tools.api_key.denied_without_permission")
|
||||
def test_list_tools_denied_without_permission(
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ class KeyInfo(BaseModel):
|
|||
budget_id: str | None = None
|
||||
litellm_budget_table: LiteLLMBudgetTable | None = None
|
||||
budget_limits: list[BudgetWindowState] | None = None
|
||||
object_permission: ObjectPermission | None = None
|
||||
|
||||
|
||||
class KeyInfoResponse(BaseModel):
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue