forked from phoenix/litellm-mirror
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:
commit
e0cf055be6
6 changed files with 51 additions and 3 deletions
|
@ -15,6 +15,7 @@ This covers:
|
||||||
- ✅ **Custom SLAs**
|
- ✅ **Custom SLAs**
|
||||||
- ✅ [**Secure UI access with Single Sign-On**](../docs/proxy/ui.md#setup-ssoauth-for-ui)
|
- ✅ [**Secure UI access with Single Sign-On**](../docs/proxy/ui.md#setup-ssoauth-for-ui)
|
||||||
- ✅ [**JWT-Auth**](../docs/proxy/token_auth.md)
|
- ✅ [**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
|
## [COMING SOON] AWS Marketplace Support
|
||||||
|
|
|
@ -125,6 +125,36 @@ Output from script
|
||||||
|
|
||||||
</Tabs>
|
</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
|
## Reset Team, API Key Spend - MASTER KEY ONLY
|
||||||
|
|
||||||
|
|
|
@ -157,6 +157,7 @@ class LiteLLMRoutes(enum.Enum):
|
||||||
"/global/spend/end_users",
|
"/global/spend/end_users",
|
||||||
"/global/spend/models",
|
"/global/spend/models",
|
||||||
"/global/predict/spend/logs",
|
"/global/predict/spend/logs",
|
||||||
|
"/global/spend/report",
|
||||||
]
|
]
|
||||||
|
|
||||||
public_routes: List = [
|
public_routes: List = [
|
||||||
|
|
|
@ -1211,6 +1211,13 @@ async def user_api_key_auth(
|
||||||
_has_user_setup_sso()
|
_has_user_setup_sso()
|
||||||
and route in LiteLLMRoutes.sso_only_routes.value
|
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
|
pass
|
||||||
else:
|
else:
|
||||||
user_role = "unknown"
|
user_role = "unknown"
|
||||||
|
@ -2967,7 +2974,7 @@ async def generate_key_helper_fn(
|
||||||
organization_id: Optional[str] = None,
|
organization_id: Optional[str] = None,
|
||||||
table_name: Optional[Literal["key", "user"]] = 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:
|
if prisma_client is None and custom_db_client is None:
|
||||||
raise Exception(
|
raise Exception(
|
||||||
|
@ -3062,6 +3069,14 @@ async def generate_key_helper_fn(
|
||||||
if isinstance(saved_token["metadata"], str):
|
if isinstance(saved_token["metadata"], str):
|
||||||
saved_token["metadata"] = json.loads(saved_token["metadata"])
|
saved_token["metadata"] = json.loads(saved_token["metadata"])
|
||||||
if isinstance(saved_token["permissions"], str):
|
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"])
|
saved_token["permissions"] = json.loads(saved_token["permissions"])
|
||||||
if isinstance(saved_token["model_max_budget"], str):
|
if isinstance(saved_token["model_max_budget"], str):
|
||||||
saved_token["model_max_budget"] = json.loads(
|
saved_token["model_max_budget"] = json.loads(
|
||||||
|
|
|
@ -319,7 +319,8 @@ const CreateKey: React.FC<CreateKeyProps> = ({
|
||||||
>
|
>
|
||||||
<TextInput placeholder="" />
|
<TextInput placeholder="" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="Metadata" name="metadata">
|
|
||||||
|
<Form.Item label="Metadata" name="metadata" className="mt-8">
|
||||||
<Input.TextArea
|
<Input.TextArea
|
||||||
rows={4}
|
rows={4}
|
||||||
placeholder="Enter metadata as JSON"
|
placeholder="Enter metadata as JSON"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue