From abef1efd0642cb572a8c5d622c1609c2cdc5e8e0 Mon Sep 17 00:00:00 2001 From: ryan-crabbe-berri Date: Mon, 17 Aug 2026 09:52:56 -0700 Subject: [PATCH] fix(proxy): rebase follow-ups for audit alias denormalization Re-dates the audit migrations after upstream's latest, qualifies the new StandardAuditLogPayload keys with ReadOnly per LIT012, marks the three lookup catches with reasoned BLE001 suppressions since audit enrichment must never break the management call, regenerates the dashboard schema.d.ts for the new response fields and object_team param, and ratchets the type-discipline budget --- .../migration.sql | 0 .../migration.sql | 0 .../migration.sql | 0 .../migration.sql | 0 litellm/proxy/management_helpers/audit_logs.py | 6 +++--- litellm/types/utils.py | 12 ++++++------ type-discipline-budget.json | 2 +- ui/litellm-dashboard/src/lib/http/schema.d.ts | 15 ++++++++++++++- 8 files changed, 24 insertions(+), 11 deletions(-) rename litellm-proxy-extras/litellm_proxy_extras/migrations/{20260805120000_denormalize_audit_log_aliases => 20260817120000_denormalize_audit_log_aliases}/migration.sql (100%) rename litellm-proxy-extras/litellm_proxy_extras/migrations/{20260805120001_audit_log_object_lookup_index => 20260817120001_audit_log_object_lookup_index}/migration.sql (100%) rename litellm-proxy-extras/litellm_proxy_extras/migrations/{20260805120002_audit_log_object_team_id_index => 20260817120002_audit_log_object_team_id_index}/migration.sql (100%) rename litellm-proxy-extras/litellm_proxy_extras/migrations/{20260805120003_audit_log_updated_at_index => 20260817120003_audit_log_updated_at_index}/migration.sql (100%) diff --git a/litellm-proxy-extras/litellm_proxy_extras/migrations/20260805120000_denormalize_audit_log_aliases/migration.sql b/litellm-proxy-extras/litellm_proxy_extras/migrations/20260817120000_denormalize_audit_log_aliases/migration.sql similarity index 100% rename from litellm-proxy-extras/litellm_proxy_extras/migrations/20260805120000_denormalize_audit_log_aliases/migration.sql rename to litellm-proxy-extras/litellm_proxy_extras/migrations/20260817120000_denormalize_audit_log_aliases/migration.sql diff --git a/litellm-proxy-extras/litellm_proxy_extras/migrations/20260805120001_audit_log_object_lookup_index/migration.sql b/litellm-proxy-extras/litellm_proxy_extras/migrations/20260817120001_audit_log_object_lookup_index/migration.sql similarity index 100% rename from litellm-proxy-extras/litellm_proxy_extras/migrations/20260805120001_audit_log_object_lookup_index/migration.sql rename to litellm-proxy-extras/litellm_proxy_extras/migrations/20260817120001_audit_log_object_lookup_index/migration.sql diff --git a/litellm-proxy-extras/litellm_proxy_extras/migrations/20260805120002_audit_log_object_team_id_index/migration.sql b/litellm-proxy-extras/litellm_proxy_extras/migrations/20260817120002_audit_log_object_team_id_index/migration.sql similarity index 100% rename from litellm-proxy-extras/litellm_proxy_extras/migrations/20260805120002_audit_log_object_team_id_index/migration.sql rename to litellm-proxy-extras/litellm_proxy_extras/migrations/20260817120002_audit_log_object_team_id_index/migration.sql diff --git a/litellm-proxy-extras/litellm_proxy_extras/migrations/20260805120003_audit_log_updated_at_index/migration.sql b/litellm-proxy-extras/litellm_proxy_extras/migrations/20260817120003_audit_log_updated_at_index/migration.sql similarity index 100% rename from litellm-proxy-extras/litellm_proxy_extras/migrations/20260805120003_audit_log_updated_at_index/migration.sql rename to litellm-proxy-extras/litellm_proxy_extras/migrations/20260817120003_audit_log_updated_at_index/migration.sql diff --git a/litellm/proxy/management_helpers/audit_logs.py b/litellm/proxy/management_helpers/audit_logs.py index 2c51d989020..65fa88359e1 100644 --- a/litellm/proxy/management_helpers/audit_logs.py +++ b/litellm/proxy/management_helpers/audit_logs.py @@ -211,7 +211,7 @@ def _derive_object_alias(table_name: str, updated: _AuditBlobAliasFields, before async def _lookup_team_alias(prisma_client: "PrismaClient", team_id: str) -> str | None: try: row: Final = await prisma_client.db.litellm_teamtable.find_unique(where={"team_id": team_id}) - except Exception as e: + except Exception as e: # noqa: BLE001 # audit enrichment must never break the management call verbose_proxy_logger.debug("audit log team alias lookup failed: %s", e) return None alias: Final = None if row is None else row.team_alias @@ -221,7 +221,7 @@ async def _lookup_team_alias(prisma_client: "PrismaClient", team_id: str) -> str async def _lookup_user_email(prisma_client: "PrismaClient", user_id: str) -> str | None: try: row: Final = await prisma_client.db.litellm_usertable.find_unique(where={"user_id": user_id}) - except Exception as e: + except Exception as e: # noqa: BLE001 # audit enrichment must never break the management call verbose_proxy_logger.debug("audit log user email lookup failed: %s", e) return None email: Final = None if row is None else row.user_email @@ -236,7 +236,7 @@ class _ActorKey(NamedTuple): async def _lookup_actor_key(prisma_client: "PrismaClient", token: str) -> _ActorKey: try: row: Final = await prisma_client.db.litellm_verificationtoken.find_unique(where={"token": token}) - except Exception as e: + except Exception as e: # noqa: BLE001 # audit enrichment must never break the management call verbose_proxy_logger.debug("audit log key lookup failed: %s", e) return _ActorKey(key_alias=None, user_id=None) alias: Final = None if row is None else row.key_alias diff --git a/litellm/types/utils.py b/litellm/types/utils.py index 75669f1fe8e..69098716620 100644 --- a/litellm/types/utils.py +++ b/litellm/types/utils.py @@ -39,7 +39,7 @@ from pydantic import ( field_serializer, field_validator, ) -from typing_extensions import Required, TypedDict +from typing_extensions import ReadOnly, Required, TypedDict from litellm._logging import verbose_logger from litellm._uuid import uuid @@ -3127,11 +3127,11 @@ class StandardAuditLogPayload(TypedDict): object_id: str before_value: str | None updated_values: str | None - object_alias: str | None - object_team_id: str | None - object_team_alias: str | None - changed_by_user_email: str | None - changed_by_key_alias: str | None + object_alias: ReadOnly[str | None] + object_team_id: ReadOnly[str | None] + object_team_alias: ReadOnly[str | None] + changed_by_user_email: ReadOnly[str | None] + changed_by_key_alias: ReadOnly[str | None] class StandardLoggingPayload(TypedDict): diff --git a/type-discipline-budget.json b/type-discipline-budget.json index 8e55b1533ea..97c6bdac9b2 100644 --- a/type-discipline-budget.json +++ b/type-discipline-budget.json @@ -30,7 +30,7 @@ "limit": 16715 }, "LIT011": { - "limit": 5593 + "limit": 5591 }, "LIT012": { "limit": 4519 diff --git a/ui/litellm-dashboard/src/lib/http/schema.d.ts b/ui/litellm-dashboard/src/lib/http/schema.d.ts index cf37709c377..2fbee15d638 100644 --- a/ui/litellm-dashboard/src/lib/http/schema.d.ts +++ b/ui/litellm-dashboard/src/lib/http/schema.d.ts @@ -720,7 +720,8 @@ export interface paths { * Returns a paginated response of audit logs matching the specified filters. * * Note: object_team_id and object_key_hash use Prisma JSON path filtering, - * which requires PostgreSQL. + * which requires PostgreSQL. object_team filters on the denormalized + * object_team_id and object_team_alias columns instead. */ get: operations["get_audit_logs_audit_get"]; put?: never; @@ -21493,10 +21494,20 @@ export interface components { changed_by: string; /** Changed By Api Key */ changed_by_api_key: string; + /** Changed By Key Alias */ + changed_by_key_alias?: string | null; + /** Changed By User Email */ + changed_by_user_email?: string | null; /** Id */ id: string; + /** Object Alias */ + object_alias?: string | null; /** Object Id */ object_id: string; + /** Object Team Alias */ + object_team_alias?: string | null; + /** Object Team Id */ + object_team_id?: string | null; /** Table Name */ table_name: string; /** @@ -37222,6 +37233,8 @@ export interface operations { end_date?: string | null; /** @description Filter by team_id present in before_value or updated_values JSON (PostgreSQL only) */ object_team_id?: string | null; + /** @description Filter by team: matches the row's object_team_id exactly or rows whose object_team_alias contains this value */ + object_team?: string | null; /** @description Filter by token (key hash) present in before_value or updated_values JSON (PostgreSQL only) */ object_key_hash?: string | null; /** @description Column to sort by (e.g. 'updated_at', 'action', 'table_name') */