mirror of
https://github.com/BerriAI/litellm.git
synced 2025-04-26 03:04:13 +00:00
Litellm dev 01 13 2025 p2 (#7758)
All checks were successful
Read Version from pyproject.toml / read-version (push) Successful in 12s
All checks were successful
Read Version from pyproject.toml / read-version (push) Successful in 12s
* fix(factory.py): fix bedrock document url check Make check more generic - if starts with 'text' or 'application' assume it's a document and let it go through Fixes https://github.com/BerriAI/litellm/issues/7746 * feat(key_management_endpoints.py): support writing new key alias to aws secret manager - on key rotation adds rotation endpoint to aws key management hook - allows for rotated litellm virtual keys with new key alias to be written to it * feat(key_management_event_hooks.py): support rotating keys and updating secret manager * refactor(base_secret_manager.py): support rotate secret at the base level since it's just an abstraction function, it's easy to implement at the base manager level * style: cleanup unused imports
This commit is contained in:
parent
7b27cfb0ae
commit
35919d9fec
9 changed files with 209 additions and 54 deletions
|
@ -10,12 +10,14 @@ import litellm
|
|||
from litellm._logging import verbose_proxy_logger
|
||||
from litellm.proxy._types import (
|
||||
GenerateKeyRequest,
|
||||
GenerateKeyResponse,
|
||||
KeyRequest,
|
||||
LiteLLM_AuditLogs,
|
||||
LiteLLM_VerificationToken,
|
||||
LitellmTableNames,
|
||||
ProxyErrorTypes,
|
||||
ProxyException,
|
||||
RegenerateKeyRequest,
|
||||
UpdateKeyRequest,
|
||||
UserAPIKeyAuth,
|
||||
WebhookEvent,
|
||||
|
@ -30,7 +32,7 @@ class KeyManagementEventHooks:
|
|||
@staticmethod
|
||||
async def async_key_generated_hook(
|
||||
data: GenerateKeyRequest,
|
||||
response: dict,
|
||||
response: GenerateKeyResponse,
|
||||
user_api_key_dict: UserAPIKeyAuth,
|
||||
litellm_changed_by: Optional[str] = None,
|
||||
):
|
||||
|
@ -48,11 +50,13 @@ class KeyManagementEventHooks:
|
|||
from litellm.proxy.proxy_server import litellm_proxy_admin_name
|
||||
|
||||
if data.send_invite_email is True:
|
||||
await KeyManagementEventHooks._send_key_created_email(response)
|
||||
await KeyManagementEventHooks._send_key_created_email(
|
||||
response.model_dump(exclude_none=True)
|
||||
)
|
||||
|
||||
# Enterprise Feature - Audit Logging. Enable with litellm.store_audit_logs = True
|
||||
if litellm.store_audit_logs is True:
|
||||
_updated_values = json.dumps(response, default=str)
|
||||
_updated_values = response.model_dump_json(exclude_none=True)
|
||||
asyncio.create_task(
|
||||
create_audit_log_for_update(
|
||||
request_data=LiteLLM_AuditLogs(
|
||||
|
@ -63,7 +67,7 @@ class KeyManagementEventHooks:
|
|||
or litellm_proxy_admin_name,
|
||||
changed_by_api_key=user_api_key_dict.api_key,
|
||||
table_name=LitellmTableNames.KEY_TABLE_NAME,
|
||||
object_id=response.get("token_id", ""),
|
||||
object_id=response.token_id or "",
|
||||
action="created",
|
||||
updated_values=_updated_values,
|
||||
before_value=None,
|
||||
|
@ -72,8 +76,8 @@ class KeyManagementEventHooks:
|
|||
)
|
||||
# store the generated key in the secret manager
|
||||
await KeyManagementEventHooks._store_virtual_key_in_secret_manager(
|
||||
secret_name=data.key_alias or f"virtual-key-{uuid.uuid4()}",
|
||||
secret_token=response.get("token", ""),
|
||||
secret_name=data.key_alias or f"virtual-key-{response.token_id}",
|
||||
secret_token=response.key,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
|
@ -119,7 +123,25 @@ class KeyManagementEventHooks:
|
|||
)
|
||||
)
|
||||
)
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
async def async_key_rotated_hook(
|
||||
data: Optional[RegenerateKeyRequest],
|
||||
existing_key_row: Any,
|
||||
response: GenerateKeyResponse,
|
||||
user_api_key_dict: UserAPIKeyAuth,
|
||||
litellm_changed_by: Optional[str] = None,
|
||||
):
|
||||
# store the generated key in the secret manager
|
||||
if data is not None and response.token_id is not None:
|
||||
initial_secret_name = (
|
||||
existing_key_row.key_alias or f"virtual-key-{existing_key_row.token}"
|
||||
)
|
||||
await KeyManagementEventHooks._rotate_virtual_key_in_secret_manager(
|
||||
current_secret_name=initial_secret_name,
|
||||
new_secret_name=data.key_alias or f"virtual-key-{response.token_id}",
|
||||
new_secret_value=response.key,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
async def async_key_deleted_hook(
|
||||
|
@ -207,6 +229,35 @@ class KeyManagementEventHooks:
|
|||
secret_value=secret_token,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
async def _rotate_virtual_key_in_secret_manager(
|
||||
current_secret_name: str, new_secret_name: str, new_secret_value: str
|
||||
):
|
||||
"""
|
||||
Update a virtual key in the secret manager
|
||||
|
||||
Args:
|
||||
secret_name: Name of the virtual key
|
||||
secret_token: Value of the virtual key (example: sk-1234)
|
||||
"""
|
||||
if litellm._key_management_settings is not None:
|
||||
if litellm._key_management_settings.store_virtual_keys is True:
|
||||
from litellm.secret_managers.base_secret_manager import (
|
||||
BaseSecretManager,
|
||||
)
|
||||
|
||||
# store the key in the secret manager
|
||||
if isinstance(litellm.secret_manager_client, BaseSecretManager):
|
||||
await litellm.secret_manager_client.async_rotate_secret(
|
||||
current_secret_name=KeyManagementEventHooks._get_secret_name(
|
||||
current_secret_name
|
||||
),
|
||||
new_secret_name=KeyManagementEventHooks._get_secret_name(
|
||||
new_secret_name
|
||||
),
|
||||
new_secret_value=new_secret_value,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _get_secret_name(secret_name: str) -> str:
|
||||
if litellm._key_management_settings.prefix_for_stored_virtual_keys.endswith(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue