Add litellm/, an operational tool skill for the LiteLLM AI gateway (proxy) and Python SDK, in the same vein as the vllm and llama-cpp engine skills. Contents: - SKILL.md: operating contract, operating loop, verification boundaries, and hard boundaries; concise core sections routing depth to references - README.md: human-facing install/use guide with required sections - references/: nine dated, source-indexed references (source index, quickstart + SDK, config & routing, keys/teams/budgets/spend, caching & guardrails, observability & logging, deployment, security & public hosting, troubleshooting), researched against litellm 1.97.0 (2026-08-22) including a live proxy probe of the health endpoints - scripts/litellm-health: read-only GET-only probe (liveliness, readiness, /v1/models, /model/info); stdlib-only Python 3.9+, --json, --help without a server - tests/test_litellm_health.py: 18 deterministic tests against a local stub HTTP server, including the observed-traffic GET-only contract - templates/proxy-config-record.md and proxy-deployment.md: fillable records; the config record is the rollback unit - evals/evals.json: schema_version 1, six output-quality cases Also regenerates tracked catalog artifacts (.claude-plugin/marketplace.json, .codex-plugin/plugin.json, llms.txt) and adds the root README catalog entry plus the skill-triggers.md index row. AI assistance: authored with AI assistance (Factory Droid) under human direction; facts verified against litellm 1.97.0 and official docs dated 2026-08-22. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
7.8 KiB
LiteLLM Security and Public-Facing Hosting
Last Updated: 2026-08-22 Sources: https://docs.litellm.ai/docs/proxy/security_best_practices , https://docs.litellm.ai/docs/proxy/public_routes , https://docs.litellm.ai/docs/proxy/master_key_rotations , https://docs.litellm.ai/blog/cve-2026-42208-litellm-proxy-sql-injection , https://docs.litellm.ai/blog/security-hardening-april-2026 , https://docs.litellm.ai/blog/security-update-march-2026
This reference covers hardening an internet-reachable proxy: the CVE floor, auth
model, route exposure, secrets and salt-key discipline, supply-chain posture,
privacy defaults, and abuse controls. Scope: LiteLLM-specific security; TLS
termination and network plumbing belong to traefik/kubernetes.
Version floor: >=1.83.7
Any internet-reachable proxy must run litellm >=1.83.7 (and Starlette >=1.0.1):
| Vuln | Type | Auth needed | Fixed |
|---|---|---|---|
| CVE-2026-42208 | Pre-auth SQL injection via crafted Authorization header; read/modify DB incl. keys | None (Critical, CISA KEV, actively exploited 2026) | v1.83.7 |
| CVE-2026-42203 | SSTI in /prompts/test → code exec in proxy process |
Valid key | v1.83.7 |
| CVE-2026-42271 | Command injection in MCP stdio test endpoints | Valid key (CISA KEV) | v1.83.7 |
| CVE-2026-48710 | Starlette host-header bypass; chained with 42271 → unauthenticated RCE | None | Starlette >=1.0.1 + litellm >=1.83.7 |
| CVE-2026-35030 | OIDC userinfo cache collision → session inheritance (only with enable_jwt_auth) |
None | v1.83.0 |
| CVE-2026-35029 | /config/update missing role check → any key could change runtime config |
Any key | v1.83.0 |
Two of these sat in CISA KEV during 2026 with exploitation observed within days of disclosure — a public proxy below the floor should be treated as compromised until patched and its provider keys rotated.
Supply-chain posture
- March 2026 incident: backdoored PyPI wheels
litellm==1.82.7and1.82.8(~40 minutes; credential stealer harvesting env vars, SSH keys, cloud/k8s creds). Official Docker-image users were unaffected. Clean builds resumed at v1.83.0 via a rebuilt CI pipeline. - Consequences for operators: pin exact versions or digests; prefer the cosign-signed
official images over unpinned pip installs; verify signatures in CI/admission;
never
pip install litellmunversioned on a shared host. - Images are cosign-signed since v1.83.0 with the pinned-commit public key shown in every release body.
Authentication model
- With Postgres connected, clients authenticate with virtual keys; without one, the
master key is the only credential. Health probes (
/health/liveliness,/health/readiness) are deliberately unauthenticated and low-detail. - Always set a strong random master key (
sk-+ 32+ random bytes). The quickstart'ssk-1234placeholder is fingerprinted by vulnerability scanners, and the login page advertises default credentials unless hidden — never ship it beyond throwaway local testing. - The Admin UI is effectively equivalent to holding the master key: restrict it to
admin networks, prefer SSO (EE beyond 5 users), or set
DISABLE_ADMIN_UI=Trueon API-only edges. - Key-management sharp edges: management-route power follows the key owner's
role (an admin-owned virtual key can manage the proxy);
custom_key_generatepolicy hooks do not run on updates unless paired withcustom_key_update. - Enterprise-only auth extras: SSO/SAML/SCIM beyond 5 users, JWT/OIDC auth, audit logs, IP allowlists.
Route exposure
Routes that must never be publicly exposed: /key/*, /user/*, /team/*,
/config/*, /model/*, /spend/*, /ui, /prompts/test, /mcp-rest/*. Each of
these maps to a real incident class above (config write = takeover; prompt-test SSTI;
MCP test command injection).
Route lockdown settings (public_routes, admin_only_routes, allowed_routes)
are Enterprise as of this refresh — do not present them as generally available.
The OSS path is enforcing at the reverse proxy: expose only the LLM route groups you
serve plus health probes, and deny management paths at the edge before they reach the
proxy. Terminate TLS at the LB/reverse proxy; never publish port 4000 raw.
Secrets, salt key, rotations
- Provider credentials live only as
os.environ/VARreferences in config or in a secret manager; nothing secret belongs inconfig.yamlor git. LITELLM_SALT_KEYencrypts DB-stored provider credentials. Set once, store in a secret manager, never rotate after adding models (stored data becomes unreadable).- Master-key rotation: if a salt key is set, rotate by changing the secret and restarting — not via the regenerate flow, which would re-encrypt stored credentials under a key the proxy then cannot use. Back up the DB before any rotation flow.
- Virtual keys are hashed in the DB (hashing survives master-key rotation); instant revocation is block/unblock; grace-period regeneration and scheduled rotation are Enterprise.
- Keep Postgres and Redis on private subnets with TLS and least-privilege roles —
DATABASE_URLgrants direct read/write to keys, budgets, and spend logs.
Data privacy defaults
- Self-hosting sends nothing to BerriAI; requests do flow to whichever providers are configured — residency comes from provider/region choice and guardrails.
store_prompts_in_spend_logsdefaults to false; spend logs carry metadata only. Enabling it stores full messages/responses per row. The Admin UI Spend Log toggle overrides config values at runtime — audit UI state on managed deployments.turn_off_message_logging: truekeeps content out of callbacks;redact_user_api_key_info: trueredacts identity hashes in traces;overwrite_user_with_key_hash: truestops caller-controlleduserfields from reaching providers.- Presidio PII masking (OSS) can mask emails/cards/SSNs pre-dispatch — see 04-caching-and-guardrails.md.
Abuse and cost control
Budgets and rate limits are abuse controls as much as finance tools — a stolen gateway key is stolen provider quota:
- Global budget as circuit breaker; per-key caps sized ~2x expected load with alerts
at 80%;
upperbound_key_generate_paramsso self-service cannot out-cap you; end-user budgets viamax_end_user_budget_id; rate limits on every public-facing key (admins exempt — test accordingly). - Budgets require Postgres and fail open without one (see 03-keys-teams-budgets-spend.md).
- Slack/email alerting covers budget crossings, DB failures, hanging requests, and outages; Prometheus deployment-state metrics catch cooldown cascades.
Hardening checklist (condensed)
- Pinned image/digest >=1.83.7, cosign verified, within the supported four-line window.
- Strong master key from a secret manager;
sk-1234nowhere; Admin UI restricted or disabled. - Scoped virtual keys per workload with expiry, budgets, rpm/tpm; block/unblock ready.
- Edge exposes only LLM routes + health probes; management paths denied at the proxy; TLS terminated up front.
- Postgres/Redis private, TLS, least privilege; DB pool bounded by instance math.
- Salt key set once; documented master-key rotation flow rehearsed; DB backups before migrations.
- Prompt-retention posture decided explicitly; message logging off where not needed.
- Budgets + rate limits + alerting live; deployment-state and spend dashboards wired.
Verification at the delivery boundary
- From outside the trust boundary: management routes return 403/404, health probes answer, and no endpoint echoes configuration details.
scripts/litellm-health --check readinessconfirms DB connectivity without leaking diagnostics; richer diagnostics stay behind auth.- A revoked (blocked) key fails immediately; a key over its tiny test budget is rejected with the documented error.