refactor(agents): exhaust the agent access match and drop routine comments

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
yassin 2026-09-17 20:34:06 +00:00
parent 3a86567c9d
commit 89330cdac6
3 changed files with 5 additions and 17 deletions

View file

@ -193,9 +193,6 @@ def _agent_capped_servers(
agent_servers: Sequence[str],
agent_access_group_servers: frozenset[str] | None,
) -> tuple[str, ...] | None:
"""Servers left once the agent's object_permission and attached access groups both cap the
key/team result, or None when the agent restricts nothing. An attached group set naming no
server is an empty ceiling, not an absent one, so it denies every server."""
if not agent_servers and agent_access_group_servers is None:
return None
return tuple(

View file

@ -8,7 +8,7 @@ Follows the same pattern as MCP permission handling.
import asyncio
from collections.abc import Awaitable, Callable, Sequence
from dataclasses import dataclass
from typing import Final, TypeAlias
from typing import Final, TypeAlias, assert_never
from litellm._logging import verbose_logger
from litellm.proxy._experimental.mcp_server.ui_session_utils import build_effective_auth_contexts
@ -67,14 +67,7 @@ class AgentRequestHandler:
user_api_key_auth: UserAPIKeyAuth | None = None,
resolve_ceiling: CeilingResolver = resolve_agent_access_group_ceiling,
) -> AgentAccess:
"""
Resolve the agents the given user/key may reach.
``UnrestrictedAgentAccess`` is only returned when neither the key nor its team
carries any grant and the agent behind the key has no access groups attached.
Grants that intersect to nothing stay restricted, so narrowing a caller can
never widen what it reaches.
"""
"""Agents the key may reach: key and team grants intersected with the agent's access group ceiling."""
key_team_access: Final = await AgentRequestHandler._resolve_key_team_agent_access(user_api_key_auth)
agent_ceiling: Final = await AgentRequestHandler._agent_access_group_ceiling(user_api_key_auth, resolve_ceiling)
if agent_ceiling is None:
@ -84,6 +77,8 @@ class AgentRequestHandler:
return RestrictedAgentAccess(agent_ceiling)
case RestrictedAgentAccess(key_team_ids):
return RestrictedAgentAccess(key_team_ids & agent_ceiling)
case _:
assert_never(key_team_access)
@staticmethod
async def _resolve_key_team_agent_access(
@ -111,7 +106,6 @@ class AgentRequestHandler:
user_api_key_auth: UserAPIKeyAuth | None,
resolve_ceiling: CeilingResolver,
) -> frozenset[str] | None:
"""Stable IDs of the agents the calling agent's attached access groups allow; None when none attached."""
if user_api_key_auth is None or not user_api_key_auth.agent_id:
return None
ceiling: Final = await resolve_ceiling(user_api_key_auth.agent_id)

View file

@ -1007,7 +1007,6 @@ async def common_checks(
code=status.HTTP_400_BAD_REQUEST,
)
# 2.4 If the agent behind the key has access groups attached, they cap the models it can call
await _check_agent_access_group_model_access(model=_model, valid_token=valid_token, llm_router=llm_router)
## 2.1 If user can call model (if personal key)
@ -4205,9 +4204,7 @@ async def _check_agent_access_group_model_access(
llm_router: Router | None,
resolve_ceiling: CeilingResolver = resolve_agent_access_group_ceiling,
) -> Literal[True]:
"""Raises when the key's agent has access groups attached and none of them names the model.
Attached groups that name no model deny every model; ``_can_object_call_model`` would read
an empty allowlist as unrestricted."""
"""Attached groups naming no model deny every model, unlike the empty allowlist ``_can_object_call_model`` allows."""
if not model or valid_token is None or not valid_token.agent_id:
return True
ceiling: Final = await resolve_ceiling(valid_token.agent_id)