Merge pull request #3772 from BerriAI/litellm_create_keys_with_permissions

[Feat] Proxy - Create Keys that can only access `/spend` routes on Admin UI
This commit is contained in:
Ishaan Jaff 2024-05-21 18:53:49 -07:00 committed by GitHub
commit e0cf055be6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 51 additions and 3 deletions

View file

@ -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

View file

@ -125,6 +125,36 @@ Output from script
</Tabs>
## 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

View file

@ -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 = [

View file

@ -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(

View file

@ -319,7 +319,8 @@ const CreateKey: React.FC<CreateKeyProps> = ({
>
<TextInput placeholder="" />
</Form.Item>
<Form.Item label="Metadata" name="metadata">
<Form.Item label="Metadata" name="metadata" className="mt-8">
<Input.TextArea
rows={4}
placeholder="Enter metadata as JSON"

View file

@ -596,7 +596,7 @@ const ViewKeyTable: React.FC<ViewKeyTableProps> = ({
<Title>Token Name</Title>
<Text className="my-1">{selectedToken.key_alias ? selectedToken.key_alias : selectedToken.key_name}</Text>
<Title>Token ID</Title>
<Text className="my-1 text-[12px]">{selectedToken.token}</Text>
<Text className="my-1 text-[12px]">{selectedToken.token}</Text>
<Title>Metadata</Title>
<Text className="my-1"><pre>{JSON.stringify(selectedToken.metadata)} </pre></Text>
</Card>