LiteLLM, la pasarela de código abierto que muchos equipos usan para centralizar sus claves de OpenAI, Anthropic o Google, distribuyó el 21 de octubre de 2026 una versión 1.107.0 con un stealer de credenciales y un backdoor, tanto en PyPI como en las imágenes Docker etiquetadas como latest. El paquete estuvo disponible 104 minutos y Wiz vio al atacante validar credenciales de AWS robadas cuatro horas y media después, así que quien instaló esa versión debe dar por perdidos todos los secretos del equipo.
Qué ha pasado con LiteLLM 1.107.0
El 21 de octubre a las 11:39 UTC (13:39 en la España peninsular), el flujo de publicación de LiteLLM subió a PyPI los siete wheels de la versión 1.107.0 y, siete minutos después, las imágenes de contenedor a Docker Hub y GHCR, con las etiquetas v1.107.0, latest, main-latest y main-stable apuntando a la compilación envenenada. El escáner de Socket marcó los wheels a las 11:46 UTC y a lo largo de la tarde llegaron los análisis de Wiz, StepSecurity, SafeDep, Aikido, JFrog y Upwind. PyPI retiró el paquete a las 13:23 UTC, GHCR dejó de servir las etiquetas a las 13:51 y Docker Hub las repuntó a imágenes limpias a las 14:20. La captura de Socket muestra la alerta tal como la vio su escáner: un cargador de arranque instalado en site-packages que se ejecuta en cualquier proceso de Python sin que nadie importe el paquete.

JFrog Security fue de los primeros en avisar en X: «Avoid this version and investigate environments where it was installed or executed» (evita esta versión e investiga los entornos donde se instaló o ejecutó). El mismo día, LiteLLM publicó un informe de incidente firmado por Krrish Dholakia (CEO), Ishaan Jaffer (CTO), Oliver Jensen (director de seguridad) y Nate Armstrong (ingeniero principal de Rust). En la actualización de las 20:30 UTC el equipo reconstruye la cadena: «The attacker had to compromise multiple independent security controls to be successful» (el atacante tuvo que comprometer varios controles de seguridad independientes para tener éxito). La compilación salió de un repositorio falso, Berri-AI/litellm, con un guion que lo diferencia del legítimo BerriAI/litellm, y la publicación la aprobaron credenciales robadas a tres desarrolladores. El tag v1.107.0 del repositorio oficial no contiene los ficheros maliciosos.
El diagrama resume la cadena tal como la describe LiteLLM. El origen que la empresa sospecha, sin confirmarlo todavía, está en su propio producto: un despliegue interno de LiteLLM expuesto a Internet, con una cuenta de usuario que nadie había creado, cuyos logs guardaban tokens OAuth de GitHub CLI. La empresa explica que Claude Code puede incrustar ese token en el cuerpo de una respuesta y que, si el proxy registra los cuerpos de las respuestas, el token acaba en los logs. Con uno de esos tokens, que pertenecía a uno de los dos propietarios de la organización en GitHub, el atacante desactivó la protección de rama, forzó el cambio en el flujo de publicación y lo apuntó al repositorio falso.

Es el segundo compromiso de LiteLLM en siete meses y llega en la misma semana en que una cuenta de GitHub robada sirvió para sustituir los binarios de OVHcloud CLI por una compilación con un stealer. El patrón se repite: el canal de confianza del fabricante entrega el malware y la limpieza del lado del proveedor no toca los equipos que ya lo descargaron.
Cómo funcionan el stealer y el backdoor de LiteLLM
Dato | Valor |
|---|---|
Producto | LiteLLM (paquete litellm en PyPI e imágenes litellm, litellm-database y litellm-non_root en Docker Hub y GHCR) |
CVE | Sin CVE asignado. Es un paquete manipulado, no una vulnerabilidad del código |
Versiones afectadas | 1.107.0 en PyPI (siete wheels, de 11:39 a 13:23 UTC del 21 de octubre de 2026) y las etiquetas v1.107.0, latest, main-latest y main-stable en Docker Hub (de 11:46 a 14:20 UTC) y GHCR (de 11:46 a 13:51 UTC) |
Versiones corregidas | Ninguna nueva. LiteLLM pide fijar 1.106.2 o cualquier versión explícita anterior. StepSecurity comprobó que 1.107.0rc1, 1.107.0rc2 y las ramas 1.106.x a 1.103.x están limpias |
Explotación activa | Sí. Wiz observó al atacante validar credenciales de AWS robadas entre las 16:20 y las 17:01 UTC del 21 de octubre. No figura en el catálogo KEV de CISA porque no hay CVE |
Digest de la imagen comprometida | sha256:1bbcb1443bc962e45f5aad53fe3d2c30600e0379715fb6c664cdd3ac126c339e |
Gravedad | Crítica. Socket, JFrog (XRAY-955589) y Aikido la clasifican como malware conocido |
La carga no está en el código fuente. Según Wiz, el atacante hizo diez commits en el repositorio falso entre las 08:56 y las 10:46 UTC con la dirección ckdi82fkoos@proton.me, y los nueve primeros iban firmados por GitHub. Dos de ellos explican el truco: el commit 783c43b añade a las 09:48 la línea data = "cook" en la sección de Maturin de pyproject.toml, lo que empaqueta una carpeta cook/ dentro de cada wheel, y el commit 20535d8 añade a las 10:46 la instrucción COPY cook ./cook a los Dockerfiles. El tarball de código fuente lleva la línea alterada pero no la carpeta, de modo que quien compiló desde el tag oficial no recibió la carga.
Los wheels dejan tres ficheros en la raíz de site-packages. El primero, cook.pth, tiene 12 bytes y una sola línea, import cook, que Python procesa en cada arranque del intérprete. El segundo, cook.py, es el stealer, ofuscado en una línea que descomprime unos 61 KB de código en base64 y zlib y lo pasa a exec. El tercero, sitecustomize.py, es el backdoor, y Python también lo ejecuta al arrancar. StepSecurity lo resume en una frase: nadie tiene que importar litellm. Cualquier proceso de Python en ese entorno, incluido pip, vuelve a lanzar la carga, y por eso todos los laboratorios coinciden en que la limpieza no puede empezar con pip uninstall.
El stealer se identifica como privcollect y organiza la recolección en módulos. La captura de JFrog muestra la lista decodificada: contraseñas de navegador, claves SSH, credenciales de nube y de contenedores, secretos de CI/CD, herramientas de desarrollo con IA, variables de entorno, la base de datos de LiteLLM, metadatos de instancia, claves GPG y claves privadas TLS. Wiz cuenta 16 módulos en total.

Sobre el terreno, Socket detalla lo que eso significa. En nube y despliegue: AWS, Azure, Google Cloud, Kubernetes, Docker, GitHub CLI, Vault, Terraform, Packer, configuración de CI y secretos montados en contenedores. En cuentas de desarrollador: credenciales de Git, configuración de npm y PyPI, .netrc, ficheros .env, claves SSH, GPG y TLS. En herramientas de IA: el auth.json de Codex, el .credentials.json de Claude, el oauth_creds.json de Gemini, el mcp.json de Cursor y la configuración de Copilot, Windsurf, Kiro, Zed, Continue, OpenCode y Hugging Face. En el puesto de trabajo: bases de datos de inicios de sesión, cookies e historial de Chromium y Firefox, historiales de shell y datos de red. En tiempo de ejecución: todas las variables de entorno no vacías, el entorno de cualquier otro proceso legible en Linux a través de /proc, las credenciales de instancia y tarea de AWS, los tokens de cuenta de servicio de Google Cloud y los metadatos de Azure. El módulo de nube valida cada clave de AWS con una llamada a GetCallerIdentity antes de enviarla.
El módulo db_litellm es el que convierte un proxy en el premio gordo. Si la variable DATABASE_URL está definida, un proceso hijo de Prisma consulta dos tablas de la base de datos del proxy con un límite de 500 filas: LiteLLM_CredentialsTable, donde se guardan los nombres y valores de las credenciales de cada proveedor, y LiteLLM_ProxyModelTable, con los modelos configurados y sus parámetros. La captura de JFrog reproduce las dos consultas.

Todo lo recogido se serializa en JSON, se cifra con una clave AES-256-CBC aleatoria que a su vez se envuelve con una clave pública RSA-4096 (OAEP con SHA-256) y se empaqueta en un tar.gz con tres ficheros, hdr.json, data.bin y key.bin. El paquete sale por HTTP sin cifrar, en un POST a www.litellm[.]dev/healthcheck, con una cabecera X-Token fija y un agente de usuario que imita a Internet Explorer 7. El dominio imita al del proyecto, cuya documentación vive en litellm.ai. Según StepSecurity, litellm.dev se registró el 13 de octubre a las 00:45 UTC y la cuenta de GitHub letters9813, que aloja el punto muerto del backdoor, se creó seis horas después. El 18 de octubre se creó el repositorio pythonclient-test y el 20 se vació el fichero domain.txt tras unas pruebas con los valores localhost:18909 y test.test.com:18909. Hubo ocho días de preparación. El stealer hace hasta cuatro intentos de envío con 120 segundos de espera y solo escribe el marcador /tmp/.pc_once_72129118c59f5636c0bb cuando el servidor responde con un 200, de modo que la ausencia del marcador no prueba nada.
El backdoor de sitecustomize.py toma un bloqueo exclusivo sobre /tmp/remote_code_loader.lock, hace un doble fork, se desvincula de la terminal con setsid y se queda en segundo plano. Cada 3.600 segundos lee un dominio del fichero domain.txt del repositorio de GitHub, lo resuelve, ejecuta una copia embebida de privcollect que, a diferencia de la de cook.py, recoge y envía en cada ciclo, y descarga por HTTP la ruta /codepy de ese dominio para pasarla a exec. Socket lo deja claro: «There is no signature or content-hash verification» (no hay verificación de firma ni de hash del contenido). El fragmento de JFrog muestra la lógica con el dominio vacío y con el dominio poblado.

En Windows el backdoor falla en silencio, porque depende de fcntl y de os.fork, pero el stealer de cook.py sí se ejecuta. En el momento del análisis el fichero domain.txt estaba vacío, así que el canal de segunda fase nunca llegó a activarse, y GitHub retiró el repositorio hacia las 13:30 UTC. Wiz describe la combinación de un fichero .pth con sitecustomize.py como el primer caso documentado en la naturaleza y señala rasgos de código escrito con ayuda de un modelo de lenguaje, como nombres de variables muy largos, bloques try/except genéricos y un módulo exec_py que nunca se usa.
Lo que sí se activó fue el uso de las credenciales. Wiz observó entre las 16:20 y las 17:01 UTC, unas cuatro horas y media después de la exfiltración, conexiones desde 168.100.8[.]57 y 165.227.201[.]8 que validaban credenciales de rol de instancia de AWS procedentes de runners de CI y de nodos de Kubernetes comprometidos. La secuencia era siempre la misma, sts:GetCallerIdentity seguida de bedrock:ListFoundationModels y de una llamada ListModels, el patrón de quien busca capacidad de inferencia ajena para revenderla, lo que el sector llama LLMjacking. En algunos entornos el atacante enumeró también roles, usuarios y claves de acceso de IAM.
Socket relaciona la cadena con las técnicas T1195.001 (compromiso de dependencias de software), T1546.018 (hooks de arranque de Python), T1027.013, T1140, T1552.001, T1552.004, T1552.005, T1555.003 y T1105 de MITRE ATT&CK. Los indicadores que publican LiteLLM, Wiz, Socket y StepSecurity son estos:
Indicador | Valor |
|---|---|
Ficheros en site-packages | cook.pth, cook.py y sitecustomize.py |
SHA-256 de cook.pth | 7f191632e7320705d154b85204f1ae546b543acbd7e8861229b76f5042b92bdb (Linux y macOS), 84dc8c82c0a4a4a62552ef826b49fcc86d1a5c4a5d0f2c06665723f93d129d7d (Windows) |
SHA-256 de cook.py | 9dd0a3926f96a37eb86cf1ee2310d9be93139cc4ebef3ef9e2efe9531390be25 (Linux y macOS), 03ac2a8b752605d1d7710979c17ff18b03dd978203ba23ba97fd8ce3d6f897ea (Windows) |
SHA-256 de sitecustomize.py | 34bef04fe88ac9d0aae0475630b1738681d15b94f233ac8aa46eacf5968305fa (Linux y macOS), b6122440d0d9cb1eb1ade9933f49214da8c31288de7710c076c2680dfa528465 (Windows) |
Exfiltración | http://www.litellm[.]dev/healthcheck con cabecera X-Token: XWiA8gZNa7NcX2XRoAEb |
Punto muerto del backdoor | raw.githubusercontent[.]com/letters9813/pythonclient-test/main/domain.txt |
Segunda fase | http://{dominio}/codepy |
Marcador y bloqueo | /tmp/.pc_once_72129118c59f5636c0bb, /tmp/remote_code_loader.lock, directorios /tmp/.pc_sq_* y /tmp/.pc_e_* |
Variable de entorno | PRIVCOLLECT_ACTIVE=1 |
Repositorio y commits | github.com/Berri-AI/litellm, commit 20535d8fa11f786a6c24df7488a0e449ed5f09ad y commit del flujo 9cf97e935aeaf791b9c8db224a2bb3ee156134ce |
IP del atacante | 168.100.8[.]57 y 165.227.201[.]8 |
Huella de la clave RSA-4096 | a898fd08ad220fed52488906eb45d196f332b972ad5d85214e7726545ecc4218 |
A quién afecta la versión comprometida de LiteLLM
A quien instalase litellm con pip sin fijar versión entre las 11:39 y las 13:23 UTC del 21 de octubre, y a quien arrancase un contenedor con las etiquetas v1.107.0, latest, main-latest o main-stable entre las 11:46 y las 14:20 UTC, tanto desde Docker Hub como desde GHCR. LiteLLM es explícito con el criterio: si Python llegó a arrancar en ese entorno, el entorno está comprometido. Los clientes de la edición Enterprise que descargan desde el registro privado de LiteLLM no se vieron afectados.
La base instalada es grande. El paquete acumula 22,8 millones de descargas en los últimos siete días y 92,2 millones en el último mes, según las estadísticas de PyPI consultadas el 22 de octubre. Wiz vio credenciales de runners de CI y de nodos de Kubernetes en manos del atacante, el perfil de una instalación automatizada que repite pip install sin versión fijada cada vez que arranca un job. En un equipo de desarrollo el daño se mide por lo que guarda el disco, desde las claves SSH hasta las sesiones de Claude Code, Codex o Cursor. En un servidor con el proxy de LiteLLM conectado a una base de datos, el daño es la lista completa de claves de proveedor que el proxy custodiaba para toda la organización, hasta 500 por consulta.
En Windows el stealer funciona y el backdoor no. En Linux y macOS funcionan los dos. En el momento de escribir esta noticia, a mediodía del 22 de octubre, ni INCIBE-CERT ni el CCN-CERT han publicado aviso sobre el incidente, y ninguna fuente da cifras de afectados por país. El riesgo en España es el mismo que en cualquier otro sitio donde un equipo haya montado un proxy de LiteLLM para repartir el acceso a varios modelos, una práctica frecuente en empresas que han empezado a controlar el uso de asistentes de IA a través de una pasarela única.
Qué hacer si instalaste litellm 1.107.0
Estas comprobaciones, tomadas de StepSecurity y de LiteLLM, buscan los ficheros, el marcador y el proceso del backdoor sin arrancar Python, que es la condición que todos los laboratorios ponen por delante.
# Ficheros de la carga en cualquier site-packages (no uses pip ni python para esto)
find / -name cook.pth -path "*site-packages*" 2>/dev/null
find / -name sitecustomize.py -path "*site-packages*" -newermt "2026-10-21" 2>/dev/null
# Marcador de exfiltración y bloqueo del backdoor
ls -la /tmp/.pc_once_72129118c59f5636c0bb /tmp/remote_code_loader.lock 2>/dev/null
lsof /tmp/remote_code_loader.lock 2>/dev/null
# Versión fijada en el código y en las imágenes
grep -rniE "litellm[=<>~! ]*1\.107\.0" requirements*.txt pyproject.toml poetry.lock uv.lock Pipfile.lock 2>/dev/null
docker exec <contenedor> ls -la /app/.venv/lib/python3.13/site-packages/cook.pth- Localiza dónde entró la versión. Revisa ficheros de bloqueo, cachés de pip, logs de construcción y digests de las imágenes en ejecución. Si un contenedor corre el índice sha256:1bbcb144…, está afectado aunque la etiqueta ya apunte a otra imagen.
- Aísla cada equipo, runner o contenedor donde Python haya arrancado con 1.107.0, conserva las evidencias y mata el proceso que mantiene abierto /tmp/remote_code_loader.lock. No ejecutes pip ni python antes de ese paso, porque volverían a lanzar la carga.
- Borra cook.pth, cook.py y sitecustomize.py de cada site-packages afectado, junto con sus .pyc en __pycache__ y los directorios .pc_sq_* y .pc_e_* del temporal. Desinstalar el paquete no elimina esos ficheros. Reconstruye los entornos virtuales y las imágenes desde cero con la versión fijada a litellm==1.106.2 o a la imagen v1.106.2 por digest.
- Da la exfiltración por hecha si el equipo tenía salida a Internet y rota desde un equipo limpio todo lo que el stealer busca: el rol IAM de la instancia o tarea, cada clave de proveedor guardada en la base de datos del proxy, las claves maestra y virtuales de LiteLLM, la contraseña de DATABASE_URL, los secretos de las variables de entorno, las claves SSH y GPG, las sesiones de navegador, los tokens de GitHub CLI, npm y PyPI y las credenciales de Claude Code, Codex, Gemini CLI, Cursor y el resto de asistentes.
- Busca en CloudTrail llamadas GetCallerIdentity desde el rol de la instancia en torno a la hora de instalación y, después, cualquier uso del rol desde fuera de tu infraestructura, en especial ListFoundationModels de Bedrock y enumeraciones de IAM desde 168.100.8[.]57 y 165.227.201[.]8.
- Bloquea litellm[.]dev en el proxy y el DNS y crea una alerta para cualquier petición a una ruta /codepy y a la ruta del fichero domain.txt en raw.githubusercontent.com. Bloquea la ruta, no el dominio de GitHub entero. Una petición a /codepy significa que el atacante ejecutó código en ese equipo.
- Si administras un proxy de LiteLLM, comprueba que no registra los cuerpos de las respuestas en texto claro, revisa las cuentas de usuario del panel en busca de nombres que nadie creó y asegúrate de que no está expuesto a Internet sin autenticación. Es el camino de entrada que la propia LiteLLM sospecha en su caso.
- Si confirmas el robo de credenciales, notifícalo a INCIBE-CERT si eres empresa o particular y al CCN-CERT si perteneces al sector público. Si entre los datos exfiltrados hay datos personales, la brecha debe comunicarse a la AEPD en 72 horas.
Lo que no cuenta el informe de LiteLLM y el precedente de marzo
Lo primero que llama la atención es que el endurecimiento de marzo funcionó y no bastó. LiteLLM movió las publicaciones a un repositorio privado, las ató a la publicación de confianza (Trusted Publishers) desde GitHub, hizo inmutables las etiquetas de Docker y empezó a firmar las imágenes. Todo eso sigue en pie, y precisamente por eso los artefactos envenenados salieron firmados. La firma certifica que el flujo autorizado produjo el paquete, no que el flujo leyera el código correcto, y el atacante no atacó la firma, atacó la definición del flujo y le cambió el repositorio de origen. StepSecurity lo escribe así: «The controls that failed were the ones guarding the workflow definition» (los controles que fallaron fueron los que protegían la definición del flujo). Quien firme sus paquetes debería preguntarse hoy quién puede editar el YAML que los produce y qué hace falta para forzar un cambio en esa rama.
Lo segundo es la ironía de la causa raíz. La hipótesis de LiteLLM es que un despliegue interno de su propio proxy, el producto cuya función es custodiar claves de API, estaba expuesto a Internet y guardaba en sus logs los tokens OAuth de GitHub CLI que Claude Code había incluido en alguna respuesta. Un gateway de modelos de lenguaje ve pasar todo lo que los asistentes de código reciben y devuelven, y eso incluye secretos que el usuario nunca pensó en registrar. Para quien administra uno de estos proxies, la lección es que los logs del gateway son un almacén de credenciales y hay que tratarlos como tal, con la misma lógica de mínimo privilegio que aplicaríamos a la identidad y el control de accesos en la nube.
El informe deja preguntas sin respuesta. No dice cómo quedó público el despliegue interno ni cuál es la vulnerabilidad recién parcheada por la que sospecha que entró el atacante, aunque menciona que distribuye a sus clientes Enterprise una versión embargada que corrige un fallo cuya divulgación está prevista para el 27 de octubre. Tampoco explica cómo acabaron tres cuentas de desarrollador en manos del atacante a partir de unos logs, ni cuánto tiempo estuvo esa cuenta desconocida en el panel. Mientras tanto, y según el comentario de Oliver Jensen en la incidencia de GitHub que recoge The Hacker News, la empresa ha retirado de su organización de GitHub a todos los usuarios salvo a uno que no estaba afectado y ha roto los enlaces de confianza entre los registros públicos y esa organización. El borrado de los registros de ejecución del flujo con la tercera credencial, a las 11:53 UTC, es un detalle que habla de alguien que conocía el proceso y sabía qué evidencia destruir.
Cabe esperar que las credenciales robadas sigan dando guerra durante semanas. El primer uso que vio Wiz fue de LLMjacking, es decir, comprobar qué modelos de Bedrock puede invocar cada rol, y ese es el negocio inmediato. El resto del botín, claves SSH, tokens de CI, cookies de sesión y la lista de proveedores de los proxies, sirve para intrusiones que nadie relacionará a primera vista con un paquete de Python, igual que ya advertíamos con el backdoor de Rank Math PRO.
LiteLLM ya pasó por esto el 24 de marzo de 2026. Según su informe de entonces, las versiones 1.82.7 y 1.82.8 se publicaron en PyPI a las 10:39 UTC y PyPI las puso en cuarentena unos 40 minutos después. La empresa atribuyó el acceso a la dependencia Trivy que usaba en su flujo de análisis de seguridad, un compromiso que The Hacker News enmarca en la cadena de ataques de TeamPCP, y el payload exfiltraba variables de entorno, claves SSH, credenciales de nube y tokens de Kubernetes a models.litellm.cloud, otro dominio que imitaba al proyecto. CloudSEK estimó entonces, según recoge The Register, que el incidente pudo exponer a más de 2.500 organizaciones y 434.000 pipelines de CI/CD. LiteLLM contrató a Mandiant para el análisis forense, auditó las versiones de la 1.78.0 a la 1.82.6 y publicó la 1.83.0 limpia el 30 de marzo.
Sobre si el atacante es el mismo, los laboratorios piden cautela. JFrog es tajante: «No evidence currently links it to TeamPCP or the earlier access path» (ninguna prueba vincula por ahora este caso con TeamPCP o con la vía de acceso anterior). Socket añade que las claves públicas RSA de los dos incidentes son distintas y que también difieren la exfiltración y el backdoor, aunque no descarta al mismo operador con otras herramientas ni que alguna credencial robada en marzo haya tenido un papel ahora.
El caso cierra una semana en la que la cadena de suministro ha sido el hilo común. Un addon nativo de npm que inyecta shellcode al hacer require, unas actualizaciones de AOMEI Backupper con un backdoor y los binarios sustituidos de OVHcloud CLI cuentan la misma historia que LiteLLM con distintos protagonistas. En todos ellos el registro o el servidor del fabricante entregó el código, y en todos la víctima tiene que rotar secretos en lugar de parchear. Quien gestione claves de API de modelos de lenguaje para toda una organización encontrará en nuestra guía para proteger las APIs el marco para decidir qué credenciales puede permitirse guardar un gateway y cuáles no.
Preguntas frecuentes sobre el ataque a LiteLLM
¿Basta con desinstalar litellm 1.107.0 para limpiar el equipo?
No. Los tres ficheros de la carga se copian en la raíz de site-packages, fuera de la carpeta del paquete, y pip uninstall no los borra. Peor aún, ejecutar pip arranca Python y vuelve a lanzar el stealer y el backdoor. Hay que borrar cook.pth, cook.py, sitecustomize.py y sus .pyc desde la shell, matar el proceso del bloqueo y reconstruir el entorno desde cero.
¿Estoy afectado si uso LiteLLM en Windows?
Sí, en parte. El backdoor de sitecustomize.py necesita fcntl y os.fork, que no existen en Windows, y falla sin hacer nada. El stealer de cook.py sí se ejecuta y recoge credenciales de navegador, nube y herramientas de IA. Los hashes de los ficheros en Windows son distintos de los de Linux y macOS y están en la tabla de indicadores.
¿Qué pasa con las claves de proveedor guardadas en mi proxy de LiteLLM?
Si el proxy arrancó con 1.107.0 y tenía DATABASE_URL definida, el stealer consultó las tablas LiteLLM_CredentialsTable y LiteLLM_ProxyModelTable y se llevó hasta 500 credenciales de proveedor con sus valores. Hay que rotar en OpenAI, Anthropic, Google, AWS y el resto de proveedores cada clave que estuviera en esa tabla, además de la clave maestra y las claves virtuales del propio proxy y la contraseña de la base de datos.
¿Cómo sé si pip instaló la 1.107.0 en un pipeline que no fija versiones?
Busca en los logs de los jobs ejecutados entre las 11:39 y las 13:23 UTC del 21 de octubre la línea de instalación de litellm y la versión resuelta. Si el runner es efímero, revisa también las cachés de pip que comparten los jobs y los artefactos o imágenes que se construyeron en ese intervalo, porque pueden llevar los tres ficheros dentro.



No hay comentarios todavía