mirror of
https://github.com/BerriAI/litellm.git
synced 2025-04-26 11:14:04 +00:00
feat(internal_user_endpoints.py): emit audit log on /user/new
event
This commit is contained in:
parent
53f9df5506
commit
5cfae0e98a
4 changed files with 81 additions and 13 deletions
|
@ -5,13 +5,5 @@ model_list:
|
|||
aws_region_name: "us-east-1"
|
||||
litellm_credential_name: "azure"
|
||||
|
||||
credential_list:
|
||||
- credential_name: azure
|
||||
credential_values:
|
||||
api_key: os.environ/AZURE_API_KEY
|
||||
api_base: os.environ/AZURE_API_BASE
|
||||
credential_info:
|
||||
description: "Azure API Key and Base URL"
|
||||
type: "azure"
|
||||
required: true
|
||||
default: "azure"
|
||||
litellm_settings:
|
||||
store_audit_logs: true
|
||||
|
|
|
@ -1584,7 +1584,7 @@ class NewOrganizationResponse(LiteLLM_OrganizationTable):
|
|||
|
||||
class LiteLLM_UserTable(LiteLLMPydanticObjectBase):
|
||||
user_id: str
|
||||
max_budget: Optional[float]
|
||||
max_budget: Optional[float] = None
|
||||
spend: float = 0.0
|
||||
model_max_budget: Optional[Dict] = {}
|
||||
model_spend: Optional[Dict] = {}
|
||||
|
@ -1677,12 +1677,15 @@ class LiteLLM_ErrorLogs(LiteLLMPydanticObjectBase):
|
|||
endTime: Union[str, datetime, None]
|
||||
|
||||
|
||||
AUDIT_ACTIONS = Literal["created", "updated", "deleted", "blocked"]
|
||||
|
||||
|
||||
class LiteLLM_AuditLogs(LiteLLMPydanticObjectBase):
|
||||
id: str
|
||||
updated_at: datetime
|
||||
changed_by: Optional[Any] = None
|
||||
changed_by_api_key: Optional[str] = None
|
||||
action: Literal["created", "updated", "deleted", "blocked"]
|
||||
action: AUDIT_ACTIONS
|
||||
table_name: Literal[
|
||||
LitellmTableNames.TEAM_TABLE_NAME,
|
||||
LitellmTableNames.USER_TABLE_NAME,
|
||||
|
|
|
@ -53,8 +53,11 @@ def decrypt_value_helper(value: str):
|
|||
# if it's not str - do not decrypt it, return the value
|
||||
return value
|
||||
except Exception as e:
|
||||
import traceback
|
||||
|
||||
traceback.print_stack()
|
||||
verbose_proxy_logger.error(
|
||||
f"Error decrypting value, Did your master_key/salt key change recently? : {value}\nError: {str(e)}\nSet permanent salt key - https://docs.litellm.ai/docs/proxy/prod#5-set-litellm-salt-key"
|
||||
f"Error decrypting value, Did your master_key/salt key change recently? \nError: {str(e)}\nSet permanent salt key - https://docs.litellm.ai/docs/proxy/prod#5-set-litellm-salt-key"
|
||||
)
|
||||
# [Non-Blocking Exception. - this should not block decrypting other values]
|
||||
pass
|
||||
|
|
|
@ -29,12 +29,53 @@ from litellm.proxy.management_endpoints.key_management_endpoints import (
|
|||
generate_key_helper_fn,
|
||||
prepare_metadata_fields,
|
||||
)
|
||||
from litellm.proxy.management_helpers.audit_logs import create_audit_log_for_update
|
||||
from litellm.proxy.management_helpers.utils import management_endpoint_wrapper
|
||||
from litellm.proxy.utils import handle_exception_on_proxy
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
async def create_internal_user_audit_log(
|
||||
user_id: str,
|
||||
action: AUDIT_ACTIONS,
|
||||
litellm_changed_by: Optional[str],
|
||||
user_api_key_dict: UserAPIKeyAuth,
|
||||
litellm_proxy_admin_name: Optional[str],
|
||||
before_value: Optional[str] = None,
|
||||
after_value: Optional[str] = None,
|
||||
):
|
||||
"""
|
||||
Create an audit log for an internal user.
|
||||
|
||||
Parameters:
|
||||
- user_id: str - The id of the user to create the audit log for.
|
||||
- action: AUDIT_ACTIONS - The action to create the audit log for.
|
||||
- user_row: LiteLLM_UserTable - The user row to create the audit log for.
|
||||
- litellm_changed_by: Optional[str] - The user id of the user who is changing the user.
|
||||
- user_api_key_dict: UserAPIKeyAuth - The user api key dictionary.
|
||||
- litellm_proxy_admin_name: Optional[str] - The name of the proxy admin.
|
||||
"""
|
||||
if not litellm.store_audit_logs:
|
||||
return
|
||||
|
||||
await create_audit_log_for_update(
|
||||
request_data=LiteLLM_AuditLogs(
|
||||
id=str(uuid.uuid4()),
|
||||
updated_at=datetime.now(timezone.utc),
|
||||
changed_by=litellm_changed_by
|
||||
or user_api_key_dict.user_id
|
||||
or litellm_proxy_admin_name,
|
||||
changed_by_api_key=user_api_key_dict.api_key,
|
||||
table_name=LitellmTableNames.USER_TABLE_NAME,
|
||||
object_id=user_id,
|
||||
action=action,
|
||||
updated_values=after_value,
|
||||
before_value=before_value,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def _update_internal_new_user_params(data_json: dict, data: NewUserRequest) -> dict:
|
||||
if "user_id" in data_json and data_json["user_id"] is None:
|
||||
data_json["user_id"] = str(uuid.uuid4())
|
||||
|
@ -169,6 +210,7 @@ async def new_user(
|
|||
try:
|
||||
from litellm.proxy.proxy_server import (
|
||||
general_settings,
|
||||
litellm_proxy_admin_name,
|
||||
prisma_client,
|
||||
proxy_logging_obj,
|
||||
)
|
||||
|
@ -254,6 +296,34 @@ async def new_user(
|
|||
)
|
||||
)
|
||||
|
||||
try:
|
||||
if prisma_client is None:
|
||||
raise Exception(CommonProxyErrors.db_not_connected_error.value)
|
||||
user_row: BaseModel = await prisma_client.db.litellm_usertable.find_first(
|
||||
where={"user_id": response["user_id"]}
|
||||
)
|
||||
|
||||
user_row_litellm_typed = LiteLLM_UserTable(
|
||||
**user_row.model_dump(exclude_none=True)
|
||||
)
|
||||
asyncio.create_task(
|
||||
create_internal_user_audit_log(
|
||||
user_id=user_row_litellm_typed.user_id,
|
||||
action="created",
|
||||
litellm_changed_by=user_api_key_dict.user_id,
|
||||
user_api_key_dict=user_api_key_dict,
|
||||
litellm_proxy_admin_name=litellm_proxy_admin_name,
|
||||
before_value=None,
|
||||
after_value=user_row_litellm_typed.model_dump_json(
|
||||
exclude_none=True
|
||||
),
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
verbose_proxy_logger.warning(
|
||||
"Unable to create audit log for user on `/user/new` - {}".format(str(e))
|
||||
)
|
||||
|
||||
return NewUserResponse(
|
||||
key=response.get("token", ""),
|
||||
expires=response.get("expires", None),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue