Split the monolithic LiteLLM proxy into independently scalable Kubernetes components to allow separate horizontal scaling of the LLM data plane and management API surfaces - Add DatabaseURLSettings pydantic-settings model that assembles DATABASE_URL (and optional DATABASE_URL_READ_REPLICA) from discrete DATABASE_* env vars before Prisma initializes, supporting both IAM token auth (minting short-lived RDS tokens) and password auth; replaces the CLI-only path that componentized entrypoints bypass - Add gateway component (port 4000) that trims the proxy route table to the LLM data-plane surface (chat, embeddings, completions, audio, realtime, provider passthroughs, health/metrics) via an allowlist applied inside the lifespan context so plugin-registered routes are captured - Add backend component (port 4001) that exposes the management/admin surface (keys, users, teams, orgs, spend analytics, model management, SSO, audit logs) with a complementary allowlist - Add ui component — Next.js static export served by nginx (port 3000) with RSC payload routing, asset prefix aliasing, and SPA fallback for dashboard routes - Add migrations component with dedicated Dockerfile that runs prisma migrate deploy via a Helm pre-install/pre-upgrade Job, eliminating per-pod schema contention on the Prisma advisory lock - Add Helm chart (helm/litellm) with separate Deployments, Services, HPAs, and ConfigMap for each component; shared _helpers.tpl emits DATABASE_*, IAM_TOKEN_DB_AUTH, REDIS_*, and DISABLE_SCHEMA_UPDATE env vars from chart values; ingress template routes traffic to the correct component by path prefix - Add comprehensive tests for DatabaseURLSettings covering IAM auth, password auth, read replica fallbacks, operator-pinned URL preservation, and percent-encoding; add coverage test asserting gateway + backend allowlist union equals the full proxy route set - Add pydantic-settings>=2.14.1 as a proxy extra dependency and update liccheck allowlist Co-authored-by: Yassin Kortam <yassinkortam@g.ucla.edu>
136 lines
3.0 KiB
Python
136 lines
3.0 KiB
Python
"""Path allowlist for the UI backend (control plane) component.
|
|
|
|
The backend exposes management/admin endpoints consumed by the UI: keys, users,
|
|
teams, orgs, customers, budgets, tags, workflows, model management, spend &
|
|
analytics, settings (router/cache/cost-tracking/fallbacks), SSO/onboarding,
|
|
audit logs, debug, enterprise admin, and UI bootstrap helpers (logo, favicon,
|
|
.well-known config).
|
|
|
|
Anything LLM data-plane is dropped — those run on the gateway component.
|
|
"""
|
|
|
|
BACKEND_PATH_PREFIXES: tuple[str, ...] = (
|
|
# Identity / access
|
|
"/key/",
|
|
"/v2/key/",
|
|
"/user/",
|
|
"/v2/user/",
|
|
"/team/",
|
|
"/v2/team/",
|
|
"/organization/",
|
|
"/customer/",
|
|
"/end_user/",
|
|
"/sso/",
|
|
"/login",
|
|
"/v2/login",
|
|
"/v3/login",
|
|
"/logout",
|
|
"/token",
|
|
"/onboarding/",
|
|
"/audit",
|
|
"/oauth/",
|
|
"/invitation/",
|
|
"/jwt/",
|
|
# Models & routing config
|
|
"/model/",
|
|
"/v1/model/info",
|
|
"/v2/model/",
|
|
"/model_group",
|
|
"/model_access_group/",
|
|
"/model_hub/",
|
|
"/v1/access_group",
|
|
"/access_group/",
|
|
"/router/",
|
|
"/router_settings",
|
|
"/adaptive_router/",
|
|
"/fallback",
|
|
"/fallbacks",
|
|
"/cache_settings",
|
|
"/cost_tracking",
|
|
"/cost/",
|
|
"/credentials",
|
|
"/credential",
|
|
"/provider/budgets",
|
|
# Tools / agents (registry & policy admin)
|
|
"/v1/tool/",
|
|
"/v1/agents",
|
|
# Guardrails admin
|
|
"/v2/guardrails/",
|
|
# MCP server admin + BYOK OAuth flow (UI-initiated) + dynamic per-server endpoints
|
|
"/v1/mcp/",
|
|
"/test/",
|
|
"/{mcp_server_name}/",
|
|
# Budgets / tags / workflows / memory mgmt
|
|
"/budget/",
|
|
"/tag/",
|
|
"/workflow/",
|
|
"/v1/workflows/",
|
|
"/project/",
|
|
"/memory/",
|
|
"/mcp/",
|
|
# Spend / analytics
|
|
"/spend/",
|
|
"/analytics/",
|
|
"/global/",
|
|
"/user_agent",
|
|
"/usage/",
|
|
"/daily/",
|
|
# CloudZero cost-export admin (init / settings / export / dry-run / delete)
|
|
"/cloudzero/",
|
|
# Caching admin
|
|
"/cache/",
|
|
"/caching/",
|
|
# Callbacks / hooks
|
|
"/active/callbacks",
|
|
"/callbacks",
|
|
"/team_callback",
|
|
# Alerting / email / IP allowlist
|
|
"/alerting/",
|
|
"/email/",
|
|
"/add/allowed_ip",
|
|
"/delete/allowed_ip",
|
|
"/get/",
|
|
# Enterprise admin
|
|
"/enterprise/",
|
|
# Debug / config / profiling
|
|
"/debug/",
|
|
"/config/",
|
|
"/memory-usage-in-mem-cache",
|
|
"/otel-spans",
|
|
"/lazy/",
|
|
"/in_product_nudges",
|
|
# Admin reload / schedule
|
|
"/reload/",
|
|
"/schedule/",
|
|
"/settings",
|
|
"/update/",
|
|
"/upload/",
|
|
# Dev / admin utilities
|
|
"/utils/",
|
|
# UI bootstrap helpers (assets the dashboard fetches)
|
|
"/get_logo_url",
|
|
"/get_image",
|
|
"/get_favicon",
|
|
"/.well-known/",
|
|
"/litellm/.well-known/",
|
|
"/ui_discovery/",
|
|
"/ui-config",
|
|
"/sso_settings",
|
|
"/public/",
|
|
"/robots.txt",
|
|
# Health (k8s probes)
|
|
"/health",
|
|
)
|
|
|
|
BACKEND_EXACT_PATHS: frozenset[str] = frozenset(
|
|
{
|
|
"/",
|
|
"/routes",
|
|
"/openapi.json",
|
|
"/docs",
|
|
"/docs/oauth2-redirect",
|
|
"/redoc",
|
|
"/fallback/login",
|
|
}
|
|
)
|