From 1d35b7543a6853f5e76ecb7e8b57080290f20187 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Tue, 21 May 2024 17:39:37 -0700 Subject: [PATCH 1/5] UI - create keys limited to specific routes --- .../src/components/create_key_button.tsx | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/ui/litellm-dashboard/src/components/create_key_button.tsx b/ui/litellm-dashboard/src/components/create_key_button.tsx index 0e158778f..35ab99782 100644 --- a/ui/litellm-dashboard/src/components/create_key_button.tsx +++ b/ui/litellm-dashboard/src/components/create_key_button.tsx @@ -319,7 +319,21 @@ const CreateKey: React.FC = ({ > - + + + + + + Date: Tue, 21 May 2024 18:04:17 -0700 Subject: [PATCH 2/5] feat - create keys with permissions --- litellm/proxy/_types.py | 1 + litellm/proxy/proxy_server.py | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/litellm/proxy/_types.py b/litellm/proxy/_types.py index 63d82e709..a6640e4d3 100644 --- a/litellm/proxy/_types.py +++ b/litellm/proxy/_types.py @@ -157,6 +157,7 @@ class LiteLLMRoutes(enum.Enum): "/global/spend/end_users", "/global/spend/models", "/global/predict/spend/logs", + "/global/spend/report", ] public_routes: List = [ diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index 08c2fee07..cd9251942 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -1211,6 +1211,13 @@ async def user_api_key_auth( _has_user_setup_sso() and route in LiteLLMRoutes.sso_only_routes.value ): + pass + elif ( + route in LiteLLMRoutes.global_spend_tracking_routes.value + and getattr(valid_token, "permissions", None) is not None + and "get_spend_routes" in getattr(valid_token, "permissions", None) + ): + pass else: user_role = "unknown" @@ -2967,7 +2974,7 @@ async def generate_key_helper_fn( organization_id: Optional[str] = None, table_name: Optional[Literal["key", "user"]] = None, ): - global prisma_client, custom_db_client, user_api_key_cache, litellm_proxy_admin_name + global prisma_client, custom_db_client, user_api_key_cache, litellm_proxy_admin_name, premium_user if prisma_client is None and custom_db_client is None: raise Exception( @@ -3062,6 +3069,14 @@ async def generate_key_helper_fn( if isinstance(saved_token["metadata"], str): saved_token["metadata"] = json.loads(saved_token["metadata"]) if isinstance(saved_token["permissions"], str): + if ( + "get_spend_routes" in saved_token["permissions"] + and premium_user != True + ): + raise Exception( + "get_spend_routes permission is only available for LiteLLM Enterprise users" + ) + saved_token["permissions"] = json.loads(saved_token["permissions"]) if isinstance(saved_token["model_max_budget"], str): saved_token["model_max_budget"] = json.loads( From 7cbdf02a9b56884be6905b01ac3ebc154c45b1a9 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Tue, 21 May 2024 18:06:56 -0700 Subject: [PATCH 3/5] ui - set permissions on keys --- .../src/components/create_key_button.tsx | 25 ++++++++++++++++--- .../src/components/view_key_table.tsx | 12 +++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/ui/litellm-dashboard/src/components/create_key_button.tsx b/ui/litellm-dashboard/src/components/create_key_button.tsx index 35ab99782..2dda169c4 100644 --- a/ui/litellm-dashboard/src/components/create_key_button.tsx +++ b/ui/litellm-dashboard/src/components/create_key_button.tsx @@ -106,6 +106,26 @@ const CreateKey: React.FC = ({ ); } + if (formValues?.permissions != null) { + /* + existing permissions = ["get_spend_logs"] + make this a dict like + { + "get_spend_logs": true + } + */ + + let permissionsForAPI: Record = {}; + + for (let i = 0; i < formValues?.permissions?.length; i++) { + let permissionName: string = formValues?.permissions[i]; + permissionsForAPI[permissionName] = true; + } + formValues.permissions = permissionsForAPI; + + } + + message.info("Making API Call"); setIsModalVisible(true); const response = await keyCreateCall(accessToken, userID, formValues); @@ -194,8 +214,7 @@ const CreateKey: React.FC = ({ + diff --git a/ui/litellm-dashboard/src/components/view_key_table.tsx b/ui/litellm-dashboard/src/components/view_key_table.tsx index 8cab60c1a..3fccf528c 100644 --- a/ui/litellm-dashboard/src/components/view_key_table.tsx +++ b/ui/litellm-dashboard/src/components/view_key_table.tsx @@ -68,6 +68,7 @@ interface ItemData { team_id: string; metadata: any; expires: any; + permissions: Record | null; // Add any other properties that exist in the item data } @@ -597,6 +598,17 @@ const ViewKeyTable: React.FC = ({ {selectedToken.key_alias ? selectedToken.key_alias : selectedToken.key_name} Token ID {selectedToken.token} + { + selectedToken.permissions != null ? ( +
+ Permissions +
{JSON.stringify(selectedToken.permissions)}
+
+ ) : ( + <> + ) + } + Metadata
{JSON.stringify(selectedToken.metadata)} 
From 67b85d9dda33ab685e3cda2208406111d3f55de5 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Tue, 21 May 2024 18:39:25 -0700 Subject: [PATCH 4/5] undo ui changes --- .../src/components/create_key_button.tsx | 36 ++----------------- .../src/components/view_key_table.tsx | 14 +------- 2 files changed, 3 insertions(+), 47 deletions(-) diff --git a/ui/litellm-dashboard/src/components/create_key_button.tsx b/ui/litellm-dashboard/src/components/create_key_button.tsx index 2dda169c4..83e8d9264 100644 --- a/ui/litellm-dashboard/src/components/create_key_button.tsx +++ b/ui/litellm-dashboard/src/components/create_key_button.tsx @@ -106,26 +106,6 @@ const CreateKey: React.FC = ({ ); } - if (formValues?.permissions != null) { - /* - existing permissions = ["get_spend_logs"] - make this a dict like - { - "get_spend_logs": true - } - */ - - let permissionsForAPI: Record = {}; - - for (let i = 0; i < formValues?.permissions?.length; i++) { - let permissionName: string = formValues?.permissions[i]; - permissionsForAPI[permissionName] = true; - } - formValues.permissions = permissionsForAPI; - - } - - message.info("Making API Call"); setIsModalVisible(true); const response = await keyCreateCall(accessToken, userID, formValues); @@ -214,7 +194,8 @@ const CreateKey: React.FC = ({ - Spend Reporting Routes (/global/spend/report, etc) - LLM routes (/chat, /completions, /embeddings) - - - | null; // Add any other properties that exist in the item data } @@ -597,18 +596,7 @@ const ViewKeyTable: React.FC = ({ Token Name {selectedToken.key_alias ? selectedToken.key_alias : selectedToken.key_name} Token ID - {selectedToken.token} - { - selectedToken.permissions != null ? ( -
- Permissions -
{JSON.stringify(selectedToken.permissions)}
-
- ) : ( - <> - ) - } - + {selectedToken.token} Metadata
{JSON.stringify(selectedToken.metadata)} 
From b513569a95722fd42ea4aee0126b1c2edde057a2 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Tue, 21 May 2024 18:53:26 -0700 Subject: [PATCH 5/5] docs - invite team members to access /spend routes --- docs/my-website/docs/enterprise.md | 1 + docs/my-website/docs/proxy/cost_tracking.md | 30 +++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/docs/my-website/docs/enterprise.md b/docs/my-website/docs/enterprise.md index 382ba8b28..793ce339c 100644 --- a/docs/my-website/docs/enterprise.md +++ b/docs/my-website/docs/enterprise.md @@ -15,6 +15,7 @@ This covers: - ✅ **Custom SLAs** - ✅ [**Secure UI access with Single Sign-On**](../docs/proxy/ui.md#setup-ssoauth-for-ui) - ✅ [**JWT-Auth**](../docs/proxy/token_auth.md) +- ✅ [**Invite Team Members to access `/spend` Routes**](../docs/proxy/cost_tracking#allowing-non-proxy-admins-to-access-spend-endpoints) ## [COMING SOON] AWS Marketplace Support diff --git a/docs/my-website/docs/proxy/cost_tracking.md b/docs/my-website/docs/proxy/cost_tracking.md index 2aaf8116e..7405fd123 100644 --- a/docs/my-website/docs/proxy/cost_tracking.md +++ b/docs/my-website/docs/proxy/cost_tracking.md @@ -125,6 +125,36 @@ Output from script +## Allowing Non-Proxy Admins to access `/spend` endpoints + +Use this when you want non-proxy admins to access `/spend` endpoints + +:::info + +Schedule a [meeting with us to get your Enterprise License](https://calendly.com/d/4mp-gd3-k5k/litellm-1-1-onboarding-chat) + +::: + +### Create Key +Create Key with with `permissions={"get_spend_routes": true}` +```shell +curl --location 'http://0.0.0.0:4000/key/generate' \ + --header 'Authorization: Bearer sk-1234' \ + --header 'Content-Type: application/json' \ + --data '{ + "permissions": {"get_spend_routes": true} + }' +``` + +### Use generated key on `/spend` endpoints + +Access spend Routes with newly generate keys +```shell +curl -X GET 'http://localhost:4000/global/spend/report?start_date=2024-04-01&end_date=2024-06-30' \ + -H 'Authorization: Bearer sk-H16BKvrSNConSsBYLGc_7A' +``` + + ## Reset Team, API Key Spend - MASTER KEY ONLY