Coverage for .venv/lib/python3.13/site-packages/litellm/proxy/common_utils/rbac_utils.py: 32%

25 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-10 12:01 +0000

1""" 

2RBAC utility helpers for feature-level access control. 

3 

4These helpers are used by agent and vector store endpoints to enforce 

5proxy-admin-configurable toggles that restrict access for internal users. 

6""" 

7 

8from typing import Final, Literal 

9 

10from fastapi import HTTPException 

11 

12from litellm.proxy._types import LitellmUserRoles, UserAPIKeyAuth 

13 

14FeatureName = Literal["agents", "vector_stores"] 

15 

16 

17async def check_feature_access_for_user( 

18 user_api_key_dict: UserAPIKeyAuth, 

19 feature_name: FeatureName, 

20) -> None: 

21 """ 

22 Raise HTTP 403 if the user's role is blocked from accessing the given feature 

23 by the UI settings stored in general_settings. 

24 

25 Args: 

26 user_api_key_dict: The authenticated user. 

27 feature_name: Either "agents" or "vector_stores". 

28 """ 

29 # Proxy admins (and view-only admins) are never blocked. 

30 if user_api_key_dict.user_role in ( 30 ↛ 38line 30 didn't jump to line 38 because the condition on line 30 was always true

31 LitellmUserRoles.PROXY_ADMIN, 

32 LitellmUserRoles.PROXY_ADMIN_VIEW_ONLY, 

33 LitellmUserRoles.PROXY_ADMIN.value, 

34 LitellmUserRoles.PROXY_ADMIN_VIEW_ONLY.value, 

35 ): 

36 return 

37 

38 from litellm.proxy.proxy_server import ( 

39 general_settings, 

40 prisma_client, 

41 user_api_key_cache, 

42 ) 

43 

44 disable_flag: Final = f"disable_{feature_name}_for_internal_users" 

45 allow_team_admins_flag: Final = f"allow_{feature_name}_for_team_admins" 

46 

47 if not general_settings.get(disable_flag, False): 

48 # Feature is not disabled — allow all authenticated users. 

49 return 

50 

51 # Feature is disabled. Check if team/org admins are exempted. 

52 if general_settings.get(allow_team_admins_flag, False): 

53 from litellm.proxy.management_endpoints.common_utils import ( 

54 _user_has_admin_privileges, 

55 ) 

56 

57 is_admin: Final = await _user_has_admin_privileges( 

58 user_api_key_dict=user_api_key_dict, 

59 prisma_client=prisma_client, 

60 user_api_key_cache=user_api_key_cache, 

61 ) 

62 if is_admin: 

63 return 

64 

65 raise HTTPException( 

66 status_code=403, 

67 detail={"error": f"Access to {feature_name} is disabled for your role. Contact your proxy admin."}, 

68 ) 

69 

70 

71async def check_org_admin_can_generate_keys( 

72 user_api_key_dict: UserAPIKeyAuth, 

73) -> None: 

74 """ 

75 Raise HTTP 403 if the caller is an org admin and key generation is 

76 disabled for org admins via UI settings. 

77 

78 Only blocks the ORG_ADMIN role — proxy admins and all other roles are 

79 unaffected, so those paths continue to be gated by their existing auth 

80 checks. 

81 """ 

82 if user_api_key_dict.user_role not in ( 82 ↛ 88line 82 didn't jump to line 88 because the condition on line 82 was always true

83 LitellmUserRoles.ORG_ADMIN, 

84 LitellmUserRoles.ORG_ADMIN.value, 

85 ): 

86 return 

87 

88 from litellm.proxy.proxy_server import general_settings 

89 

90 if not general_settings.get("disable_key_generate_for_org_admin", False): 

91 return 

92 

93 raise HTTPException( 

94 status_code=403, 

95 detail={"error": "key generation is disabled for org admins. Contact your proxy admin."}, 

96 )