docs(litellm): document deployment and Codex auth
This commit is contained in:
+407
-51
@@ -1,105 +1,461 @@
|
||||
# LiteLLM
|
||||
|
||||
LiteLLM es la pasarela central de modelos del repositorio. Ofrece una API compatible con OpenAI a aplicaciones como Open WebUI, n8n y Paperless AI, mientras mantiene las credenciales reales de los proveedores en un único servicio.
|
||||
LiteLLM es la pasarela central de modelos del repositorio. Expone una API
|
||||
compatible con OpenAI a consumidores como Open WebUI, n8n y Paperless AI y
|
||||
centraliza las credenciales de los proveedores.
|
||||
|
||||
## Qué despliega
|
||||
Este servicio se administra directamente con Docker Compose. No depende de
|
||||
Portainer y no debe desplegarse usando `stack.env`.
|
||||
|
||||
- `litellm`: proxy, catálogo de modelos y proveedor personalizado de Codex.
|
||||
- `litellm-db`: PostgreSQL para configuración y estado persistente de LiteLLM.
|
||||
- `config.yaml`: alias públicos y proveedor asociado a cada modelo.
|
||||
- `codex_provider.py`: adaptación entre la API de LiteLLM y la API Responses de Codex.
|
||||
## Arquitectura
|
||||
|
||||
Esta separación evita configurar una credencial de OpenAI o Codex distinta en cada consumidor. Las aplicaciones sólo conocen la URL de LiteLLM, una clave de acceso de LiteLLM y el alias del modelo.
|
||||
```text
|
||||
Open WebUI / n8n / Paperless AI / clientes externos
|
||||
|
|
||||
| API OpenAI-compatible
|
||||
| LITELLM_MASTER_KEY
|
||||
v
|
||||
LiteLLM :4000
|
||||
| |
|
||||
| +----> DeepSeek API
|
||||
|
|
||||
+----> codex_provider.py
|
||||
| |
|
||||
| +----> Codex backend API
|
||||
| +----> auth.json de Codex
|
||||
|
|
||||
+----> PostgreSQL 16
|
||||
```
|
||||
|
||||
## Redes y exposición
|
||||
Los consumidores nunca reciben una credencial de DeepSeek ni los tokens de
|
||||
Codex. Sólo conocen la URL de LiteLLM, una clave de LiteLLM y un alias de
|
||||
modelo.
|
||||
|
||||
LiteLLM pertenece a su red interna `litellm` y a la red externa `proxy`. PostgreSQL sólo está en la red interna. Los consumidores conectados a `proxy` pueden usar:
|
||||
## Contenido de la carpeta
|
||||
|
||||
| Archivo | Función |
|
||||
| --- | --- |
|
||||
| `docker-compose.yml` | Define LiteLLM, PostgreSQL, redes y montajes. |
|
||||
| `.env` | Configuración real local. Contiene secretos y no está versionado. |
|
||||
| `stack.env` | Plantilla histórica versionada. No usar para desplegar. |
|
||||
| `config.yaml` | Catálogo declarativo de modelos y registro del proveedor Codex. |
|
||||
| `codex_provider.py` | Adaptador entre LiteLLM y la API Responses usada por Codex. |
|
||||
| `README.md` | Arquitectura, operación, seguridad y diagnóstico. |
|
||||
|
||||
## Servicios y persistencia
|
||||
|
||||
### `litellm`
|
||||
|
||||
- Imagen fijada mediante digest de `ghcr.io/berriai/litellm`.
|
||||
- Arranca con `--config /app/config.yaml`.
|
||||
- Escucha en el puerto interno `4000`; no publica un puerto directamente en
|
||||
el host.
|
||||
- Está unido a la red interna `litellm` y a la red externa `proxy`.
|
||||
- Guarda configuración y estado en PostgreSQL porque
|
||||
`STORE_MODEL_IN_DB=True`.
|
||||
- Reinicia con la política `unless-stopped`.
|
||||
|
||||
Montajes:
|
||||
|
||||
```text
|
||||
./config.yaml -> /app/config.yaml (solo lectura)
|
||||
./codex_provider.py -> /app/codex_provider.py (solo lectura)
|
||||
/home/felidae/.codex/auth.json -> /root/.codex/auth.json (lectura/escritura)
|
||||
```
|
||||
|
||||
El montaje de `auth.json` es deliberadamente escribible porque el proveedor
|
||||
renueva el token y persiste la sesión actualizada. Esto también significa que
|
||||
el contenedor tiene acceso al refresh token de la cuenta de ChatGPT.
|
||||
|
||||
### `litellm-db`
|
||||
|
||||
- Usa PostgreSQL 16.
|
||||
- Sólo pertenece a la red interna `litellm`.
|
||||
- No publica `5432` en el host ni se une a `proxy`.
|
||||
- Persiste sus datos desde `LITELLM_DB_DATA_PATH`.
|
||||
- Se resuelve dentro de la red como `litellm-db`.
|
||||
|
||||
`depends_on` establece el orden de arranque, pero no espera a que PostgreSQL
|
||||
esté listo. Actualmente ninguno de los dos servicios tiene un `healthcheck`
|
||||
de Docker.
|
||||
|
||||
## Variables de entorno
|
||||
|
||||
El `.env` local debe definir:
|
||||
|
||||
| Variable | Función |
|
||||
| --- | --- |
|
||||
| `LITELLM_MASTER_KEY` | Autentica a los clientes de la API de LiteLLM. |
|
||||
| `LITELLM_SALT_KEY` | Cifra datos sensibles guardados por LiteLLM; debe permanecer estable. |
|
||||
| `DEEPSEEK_API_KEY` | Credencial usada por los alias `thsllm-*`. |
|
||||
| `POSTGRES_USER` | Usuario de PostgreSQL. |
|
||||
| `POSTGRES_PASSWORD` | Contraseña de PostgreSQL. |
|
||||
| `POSTGRES_DB` | Base de datos de LiteLLM. |
|
||||
| `LITELLM_DB_DATA_PATH` | Ruta persistente del host para PostgreSQL. |
|
||||
| `LITELLM_DOMAIN` | Dominio público documentado para el servicio. |
|
||||
|
||||
No imprimas el contenido de `.env` durante verificaciones. Comprueba sólo que
|
||||
las variables existen:
|
||||
|
||||
```bash
|
||||
awk -F= '/^[A-Za-z_][A-Za-z0-9_]*=/{print $1}' .env
|
||||
```
|
||||
|
||||
`stack.env` contiene valores de plantilla. Aunque permanece en el repositorio
|
||||
por compatibilidad histórica, el despliegue soportado usa exclusivamente
|
||||
`.env` mediante `--env-file .env`.
|
||||
|
||||
## Redes y exposición con Traefik
|
||||
|
||||
Los contenedores conectados a `proxy` pueden acceder por DNS interno a:
|
||||
|
||||
```text
|
||||
http://litellm:4000/v1
|
||||
```
|
||||
|
||||
El acceso público y la interfaz se enrutan mediante la configuración dinámica de Traefik en `/opt/traefik/dynamic/litellm.yml`. La API debe exigir `LITELLM_MASTER_KEY`; la protección SSO de la interfaz no sustituye esa clave.
|
||||
El dominio público es:
|
||||
|
||||
## Configuración
|
||||
```text
|
||||
https://llm.sherlockhomeless.net
|
||||
```
|
||||
|
||||
El `.env` local debe definir, como mínimo:
|
||||
El enrutamiento vive fuera de esta carpeta, en
|
||||
`/opt/traefik/dynamic/litellm.yml`:
|
||||
|
||||
| Variable | Función | Motivo |
|
||||
| --- | --- | --- |
|
||||
| `LITELLM_MASTER_KEY` | Autentica a los consumidores de la API | Impide usar los modelos sólo por alcanzar la red |
|
||||
| `LITELLM_SALT_KEY` | Cifra datos sensibles almacenados por LiteLLM | Debe permanecer estable tras el primer arranque |
|
||||
| `POSTGRES_USER`, `POSTGRES_PASSWORD`, `POSTGRES_DB` | Base de datos interna | No se exponen fuera de la red `litellm` |
|
||||
| `LITELLM_DB_DATA_PATH` | Persistencia de PostgreSQL | Permite recrear contenedores sin perder estado |
|
||||
| `DEEPSEEK_API_KEY` | Acceso directo a DeepSeek | Sólo se necesita para los alias `thsllm-*` |
|
||||
- El router `litellm-ui` protege la interfaz mediante Authentik y CrowdSec.
|
||||
- El router `litellm-api` expone `/v1`, `/health`, `/key` y `/model` sin
|
||||
Authentik y aplica el middleware de CrowdSec.
|
||||
- La API depende de la validación de `LITELLM_MASTER_KEY` realizada por
|
||||
LiteLLM. Authentik no sustituye esa clave.
|
||||
|
||||
`config.yaml` publica alias estables. Los consumidores deben pedir el alias, no el identificador interno del proveedor. Así se puede cambiar el backend sin reconfigurar cada aplicación.
|
||||
Las rutas administrativas `/key` y `/model` forman parte de la superficie
|
||||
pública. Antes de ampliar el uso del servicio conviene confirmar qué
|
||||
operaciones permite cada versión de LiteLLM y restringirlas en Traefik si no
|
||||
son necesarias.
|
||||
|
||||
## Catálogo de modelos
|
||||
|
||||
### Declarado en `config.yaml`
|
||||
|
||||
Codex mediante el proveedor personalizado:
|
||||
|
||||
- `gpt-5.6-sol`
|
||||
- `gpt-5.5`
|
||||
- `gpt-5.3-codex`
|
||||
- `gpt-5.4-mini`
|
||||
- `gpt-5.2`
|
||||
|
||||
DeepSeek mediante su API:
|
||||
|
||||
- `thsllm-chat`
|
||||
- `thsllm-reasoner`
|
||||
- `thsllm-v4-pro`
|
||||
|
||||
Los nombres `thsllm-*` evitan exponer el proveedor real en los consumidores y
|
||||
permiten cambiar el backend manteniendo un alias estable.
|
||||
|
||||
Para los modelos Codex se usa internamente el prefijo `cx-`. Esto evita que
|
||||
LiteLLM los clasifique como modelos OpenAI nativos. `codex_provider.py` vuelve
|
||||
a convertir `cx-*` en `gpt-*` antes de enviar la petición.
|
||||
|
||||
### Catálogo efectivo
|
||||
|
||||
LiteLLM puede conservar modelos en PostgreSQL. Por eso `config.yaml` no es
|
||||
necesariamente la única fuente de verdad cuando `STORE_MODEL_IN_DB=True`.
|
||||
|
||||
En la revisión del 16 de agosto de 2026, `/v1/models` devolvía además:
|
||||
|
||||
- `thsllm-flash`
|
||||
- `thsllm-pro`
|
||||
|
||||
Esos alias no aparecen en el YAML actual y proceden previsiblemente del estado
|
||||
persistido en la base de datos. Antes de eliminar o renombrar modelos, revisa
|
||||
tanto `config.yaml` como el catálogo efectivo de LiteLLM.
|
||||
|
||||
## Autenticación de Codex
|
||||
|
||||
El Compose monta:
|
||||
### Estado y almacenamiento
|
||||
|
||||
La integración usa una sesión de ChatGPT creada por Codex CLI, no una API key
|
||||
de OpenAI Platform. El archivo del host es:
|
||||
|
||||
```text
|
||||
/home/felidae/.codex/auth.json -> /root/.codex/auth.json
|
||||
/home/felidae/.codex/auth.json
|
||||
```
|
||||
|
||||
La variable `CODEX_AUTH_FILE` apunta a la ruta interior. El montaje es de lectura y escritura porque `codex_provider.py` renueva el access token mediante el refresh token y guarda el resultado en el mismo archivo.
|
||||
|
||||
Flujo:
|
||||
|
||||
1. El usuario inicia sesión con Codex en el host y genera `~/.codex/auth.json`.
|
||||
2. Docker monta ese archivo únicamente dentro de LiteLLM.
|
||||
3. El proveedor lee `access_token`, `refresh_token` y `account_id`.
|
||||
4. Si el JWT vence en menos de 60 segundos, solicita un token nuevo y actualiza el archivo montado.
|
||||
5. LiteLLM envía la petición a Codex y devuelve una respuesta compatible con OpenAI al consumidor.
|
||||
|
||||
El archivo contiene credenciales reutilizables. No debe copiarse al repositorio, incluirse en imágenes, logs, backups sin cifrar ni montarse en Paperless, n8n u Open WebUI. `.gitignore` excluye `.codex`, pero conviene comprobar antes de cada commit:
|
||||
Codex CLI informa del método activo con:
|
||||
|
||||
```bash
|
||||
git status --ignored --short | grep codex
|
||||
codex login status
|
||||
```
|
||||
|
||||
El usuario que ejecuta Docker debe poder leer y escribir el archivo. Si el host o usuario cambia, actualiza la ruta del volumen en `docker-compose.yml`; una ruta inexistente puede terminar creada como directorio y provocar errores de autenticación.
|
||||
El archivo contiene material reutilizable, incluidos access token, refresh
|
||||
token y el identificador de cuenta. Debe tratarse como una contraseña:
|
||||
|
||||
## Modelos Codex
|
||||
- No añadirlo al repositorio.
|
||||
- No copiarlo a imágenes Docker.
|
||||
- No mostrarlo en logs, incidencias o documentación.
|
||||
- No incluirlo en backups sin cifrar.
|
||||
- No montarlo en Open WebUI, n8n, Paperless ni otros consumidores.
|
||||
- Mantener permisos `0600` en el host.
|
||||
|
||||
Los alias `gpt-*` configurados con `custom_llm_provider: codex` pasan por `codex_provider.py`. Internamente se usa el prefijo `cx-` para evitar colisiones con los modelos OpenAI nativos de LiteLLM; el proveedor vuelve a convertirlo antes de llamar a Codex.
|
||||
La documentación oficial de OpenAI describe `~/.codex/auth.json` como una de
|
||||
las ubicaciones de caché de credenciales de Codex y advierte que contiene
|
||||
tokens de acceso. También recomienda autenticación mediante API key para la
|
||||
automatización general. Referencia:
|
||||
[OpenAI Docs: Authentication](https://learn.chatgpt.com/docs/auth).
|
||||
|
||||
El proveedor admite llamadas síncronas, asíncronas y streaming. Codex responde siempre mediante streaming; para una llamada no streaming, el proveedor agrega los fragmentos antes de responder.
|
||||
### Flujo de una petición
|
||||
|
||||
## Configurar consumidores
|
||||
1. Un cliente llama a LiteLLM con `LITELLM_MASTER_KEY` y un alias.
|
||||
2. LiteLLM valida la clave y selecciona `custom_llm_provider: codex`.
|
||||
3. El proveedor lee `CODEX_AUTH_FILE`, configurado como
|
||||
`/root/.codex/auth.json`.
|
||||
4. Decodifica localmente el JWT para conocer su expiración.
|
||||
5. Si el access token vence en menos de 60 segundos, usa el refresh token
|
||||
contra `https://auth.openai.com/oauth/token`.
|
||||
6. Guarda los tokens renovados en el mismo archivo montado.
|
||||
7. Envía la petición a `https://chatgpt.com/backend-api/codex/responses` con el
|
||||
access token y el identificador de cuenta.
|
||||
8. Convierte el flujo SSE recibido en una respuesta compatible con LiteLLM.
|
||||
|
||||
Un consumidor compatible con OpenAI necesita:
|
||||
La renovación observada estaba operativa durante la revisión del 16 de agosto
|
||||
de 2026. No se documentan aquí fechas de expiración, identificadores ni valores
|
||||
de tokens.
|
||||
|
||||
### Implicaciones
|
||||
|
||||
Este diseño convierte indirectamente la sesión de ChatGPT del usuario
|
||||
`felidae` en el backend de un proxy compartido. Cualquier consumidor que posea
|
||||
`LITELLM_MASTER_KEY` puede utilizar esa cuenta y sus límites a través de los
|
||||
alias Codex.
|
||||
|
||||
Además, el endpoint `chatgpt.com/backend-api/codex/responses`, el `client_id`
|
||||
embebido y las cabeceras de compatibilidad son detalles internos y pueden
|
||||
cambiar sin mantener compatibilidad con este proveedor. Esta ruta no debe
|
||||
confundirse con una integración basada en la API pública de OpenAI Platform.
|
||||
|
||||
Para un servicio multiusuario o una automatización crítica, la opción más
|
||||
estable es evaluar la API pública de OpenAI con una API key dedicada y límites
|
||||
propios, manteniendo LiteLLM como pasarela.
|
||||
|
||||
## Comportamiento y límites de `codex_provider.py`
|
||||
|
||||
El proveedor implementa llamadas síncronas, asíncronas y streaming. El backend
|
||||
se consume siempre mediante streaming; en llamadas no streaming se agregan los
|
||||
fragmentos antes de devolver la respuesta.
|
||||
|
||||
La traducción actual sólo conserva principalmente:
|
||||
|
||||
- Mensajes de usuario y asistente.
|
||||
- Mensajes `system` y `developer`, unidos como `instructions`.
|
||||
- Nombre del modelo.
|
||||
- `reasoning_effort`, con valor predeterminado `medium`.
|
||||
- Texto generado y contadores básicos de tokens.
|
||||
|
||||
No es una implementación completa de Responses ni de Chat Completions. Entre
|
||||
otros, no reenvía explícitamente herramientas/function calling, límites de
|
||||
tokens, temperatura, formatos estructurados ni la mayoría de parámetros
|
||||
opcionales. El parser SSE sólo procesa deltas de texto y el evento final de
|
||||
uso. Un cliente puede ser compatible con la API de LiteLLM y aun así perder
|
||||
funciones al usar un alias Codex.
|
||||
|
||||
### Riesgo de concurrencia en la renovación
|
||||
|
||||
La renovación hace una lectura y una escritura directa de `auth.json`, sin
|
||||
bloqueo entre peticiones y sin reemplazo atómico. Dos solicitudes simultáneas
|
||||
cerca de la expiración podrían intentar rotar el mismo refresh token. Una
|
||||
interrupción mientras se escribe también podría dejar el JSON incompleto.
|
||||
|
||||
Si el servicio va a recibir concurrencia significativa, el proveedor debería:
|
||||
|
||||
1. Serializar la renovación mediante un lock.
|
||||
2. Escribir primero un archivo temporal con permisos restrictivos.
|
||||
3. Sincronizarlo y reemplazar `auth.json` atómicamente.
|
||||
4. Releer el archivo después de adquirir el lock por si otra petición ya lo
|
||||
renovó.
|
||||
5. Evitar que errores y cuerpos HTTP incluyan tokens en logs.
|
||||
|
||||
## Consumidores
|
||||
|
||||
Un cliente compatible con OpenAI necesita:
|
||||
|
||||
```text
|
||||
Base URL: http://litellm:4000/v1
|
||||
API key: valor de LITELLM_MASTER_KEY
|
||||
Model: gpt-5.6-sol
|
||||
Model: uno de los alias publicados
|
||||
```
|
||||
|
||||
Usa la URL interna cuando ambos contenedores compartan `proxy`. Usa la URL HTTPS sólo para clientes externos. Nunca uses el token de Codex como API key del consumidor.
|
||||
Usa la URL interna cuando ambos contenedores compartan `proxy`. Para clientes
|
||||
externos usa HTTPS. Nunca configures el token de Codex como API key de un
|
||||
consumidor.
|
||||
|
||||
Flujo de Paperless AI:
|
||||
|
||||
```text
|
||||
Paperless -> Paperless AI -> LiteLLM -> proveedor Codex -> Codex
|
||||
```
|
||||
|
||||
Open WebUI y n8n siguen el mismo patrón desde la red `proxy`.
|
||||
|
||||
## Despliegue
|
||||
|
||||
Desde esta carpeta:
|
||||
|
||||
```bash
|
||||
cd litellm
|
||||
docker compose --env-file .env config
|
||||
docker compose --env-file .env up -d
|
||||
docker compose --env-file .env ps
|
||||
```
|
||||
|
||||
## Verificación
|
||||
No usar:
|
||||
|
||||
```bash
|
||||
docker compose --env-file .env ps
|
||||
docker compose --env-file .env logs -f litellm
|
||||
curl -sS http://127.0.0.1:4000/v1/models \
|
||||
docker compose --env-file stack.env up -d
|
||||
```
|
||||
|
||||
Tras modificar `config.yaml` o `codex_provider.py`, recrea LiteLLM para evitar
|
||||
depender del estado importado por el proceso anterior:
|
||||
|
||||
```bash
|
||||
docker compose --env-file .env up -d --force-recreate litellm
|
||||
```
|
||||
|
||||
## Verificación segura
|
||||
|
||||
Validar la configuración sin mostrar secretos:
|
||||
|
||||
```bash
|
||||
docker compose --env-file .env config --quiet
|
||||
```
|
||||
|
||||
Comprobar contenedores:
|
||||
|
||||
```bash
|
||||
docker compose --env-file .env ps --all
|
||||
docker compose --env-file .env logs --tail 100 litellm
|
||||
docker compose --env-file .env exec litellm-db pg_isready
|
||||
```
|
||||
|
||||
Comprobar autenticación de Codex en el host:
|
||||
|
||||
```bash
|
||||
codex login status
|
||||
stat -c '%a %U:%G %n' /home/felidae/.codex/auth.json
|
||||
```
|
||||
|
||||
Consultar el catálogo desde dentro del contenedor sin imprimir la clave:
|
||||
|
||||
```bash
|
||||
docker compose --env-file .env exec litellm python -c '
|
||||
import json, os, urllib.request
|
||||
request = urllib.request.Request(
|
||||
"http://127.0.0.1:4000/v1/models",
|
||||
headers={"Authorization": "Bearer " + os.environ["LITELLM_MASTER_KEY"]},
|
||||
)
|
||||
with urllib.request.urlopen(request, timeout=15) as response:
|
||||
print([item["id"] for item in json.load(response)["data"]])
|
||||
'
|
||||
```
|
||||
|
||||
Consultar desde un cliente externo:
|
||||
|
||||
```bash
|
||||
curl -sS https://llm.sherlockhomeless.net/v1/models \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
Si no se publica el puerto en el host, ejecuta la prueba desde un contenedor unido a `proxy` o usa el dominio HTTPS.
|
||||
No uses `set -x` al trabajar con las claves.
|
||||
|
||||
Errores `401` que mencionen Codex suelen indicar que `auth.json` falta, no tiene permisos o ya no puede renovarse. Errores `401` devueltos antes de seleccionar modelo suelen indicar una `LITELLM_MASTER_KEY` incorrecta.
|
||||
## Diagnóstico
|
||||
|
||||
## Persistencia y copias de seguridad
|
||||
### `401` antes de seleccionar un modelo
|
||||
|
||||
Respalda la ruta `LITELLM_DB_DATA_PATH`. Trata `auth.json` como un secreto independiente: si se respalda, debe hacerse cifrado y con acceso restringido. No restaures simultáneamente versiones distintas del archivo desde varios hosts, porque la rotación del refresh token puede invalidar la copia anterior.
|
||||
Normalmente indica que el consumidor no envió la `LITELLM_MASTER_KEY`
|
||||
correcta. Revisa la clave del cliente y que no contenga espacios o saltos de
|
||||
línea.
|
||||
|
||||
### `401` o error de autenticación sólo en modelos Codex
|
||||
|
||||
Comprueba:
|
||||
|
||||
1. `codex login status` en el host.
|
||||
2. Que `/home/felidae/.codex/auth.json` exista y sea un archivo, no un
|
||||
directorio creado accidentalmente por Docker.
|
||||
3. Que tenga permisos `0600` y sea legible/escribible por el proceso esperado.
|
||||
4. Que el montaje aparezca en `docker inspect litellm`.
|
||||
5. Que el contenedor vea `CODEX_AUTH_FILE=/root/.codex/auth.json`.
|
||||
6. Los logs del contenedor, sin copiar tokens a una incidencia.
|
||||
|
||||
Si el refresh token fue revocado, ejecuta `codex login` de nuevo en el host y
|
||||
recrea el contenedor si fuera necesario.
|
||||
|
||||
### Los modelos del YAML no coinciden con `/v1/models`
|
||||
|
||||
Revisa el estado persistido en PostgreSQL. Con `STORE_MODEL_IN_DB=True`, los
|
||||
modelos guardados en la base de datos pueden ampliar o modificar el catálogo
|
||||
efectivo.
|
||||
|
||||
### PostgreSQL arranca después que LiteLLM
|
||||
|
||||
`depends_on` no verifica disponibilidad. Revisa `pg_isready` y los logs. Si el
|
||||
problema se repite, añade un healthcheck a PostgreSQL y una dependencia con
|
||||
condición de servicio saludable.
|
||||
|
||||
### Un cliente acepta texto pero fallan herramientas
|
||||
|
||||
El proveedor Codex personalizado no reenvía actualmente todas las propiedades
|
||||
de Chat Completions o Responses. Verifica el cuerpo construido en
|
||||
`_build_body()` antes de atribuir el fallo a LiteLLM o al modelo.
|
||||
|
||||
## Seguridad y endurecimiento recomendado
|
||||
|
||||
Prioridad alta:
|
||||
|
||||
1. Tratar `LITELLM_MASTER_KEY` como una credencial con acceso indirecto a todos
|
||||
los proveedores y rotarla si se comparte fuera de los consumidores
|
||||
autorizados.
|
||||
2. Restringir en Traefik `/key` y `/model` si no necesitan exposición pública.
|
||||
3. Cambiar los permisos de `.env` a `0600`.
|
||||
4. Añadir bloqueo y escritura atómica a la renovación de `auth.json`.
|
||||
5. Evaluar una API key dedicada de OpenAI para automatización o uso
|
||||
multiusuario.
|
||||
|
||||
Prioridad operativa:
|
||||
|
||||
1. Añadir healthchecks a LiteLLM y PostgreSQL.
|
||||
2. Documentar o eliminar de PostgreSQL los modelos que no estén en
|
||||
`config.yaml`.
|
||||
3. Probar explícitamente streaming, llamadas no streaming y errores de
|
||||
renovación tras cada actualización de la imagen.
|
||||
4. Revisar periódicamente que únicamente LiteLLM monte `auth.json`.
|
||||
|
||||
## Backups y recuperación
|
||||
|
||||
- Respaldar `LITELLM_DB_DATA_PATH` para conservar configuración y estado.
|
||||
- Mantener estable `LITELLM_SALT_KEY`; perderla puede impedir descifrar datos
|
||||
persistidos.
|
||||
- Si se respalda `auth.json`, hacerlo cifrado y con acceso muy restringido.
|
||||
- No restaurar simultáneamente copias distintas de `auth.json` desde varios
|
||||
hosts: la rotación del refresh token puede invalidar copias anteriores.
|
||||
- Después de una restauración, validar PostgreSQL, `/v1/models` y un alias de
|
||||
cada proveedor por separado.
|
||||
|
||||
## Estado observado el 16 de agosto de 2026
|
||||
|
||||
Esta sección es una fotografía, no una garantía permanente:
|
||||
|
||||
- Compose válido usando `.env`.
|
||||
- LiteLLM y PostgreSQL activos desde hacía 13 días.
|
||||
- LiteLLM versión `1.82.6`.
|
||||
- `/health/liveliness` respondía HTTP 200.
|
||||
- `/v1/models` respondía HTTP 200 y publicaba diez modelos.
|
||||
- PostgreSQL aceptaba conexiones.
|
||||
- Codex CLI indicaba una sesión de ChatGPT activa.
|
||||
- La renovación de `auth.json` había ocurrido correctamente.
|
||||
- `auth.json` tenía permisos `0600`.
|
||||
- `.env` tenía permisos `0664`, pendiente de endurecimiento.
|
||||
- No había healthchecks Docker configurados.
|
||||
|
||||
Repite las verificaciones de este documento antes de usar esta fotografía para
|
||||
una intervención futura.
|
||||
|
||||
Reference in New Issue
Block a user