Codex login sin navegador o por SSH: 3 vías y cuál elegir
En un servidor sin navegador (headless), Codex entra con codex login --device-auth; si no está activado, con un túnel SSH al puerto 1455 o copiando auth.json.
En esta página

En una máquina sin navegador, la forma de iniciar sesión en Codex CLI con tu cuenta de ChatGPT es el código de dispositivo: ejecutas codex login --device-auth en el servidor, abres la dirección que imprime en cualquier otro equipo e introduces un código de un solo uso. Si ese método no está activado en tu cuenta o en tu espacio de trabajo, quedan dos alternativas documentadas: reenviar por SSH el puerto al que Codex espera la respuesta, o iniciar sesión en un equipo con navegador y copiar el archivo de credenciales auth.json.
Cuál te corresponde depende de cuatro cosas que ya sabes de tu situación:
| Tu situación | Vía | Qué necesitas | Límite que debes conocer |
|---|---|---|---|
| Tienes otro dispositivo con navegador y puedes cambiar un ajuste de seguridad de ChatGPT | codex login --device-auth | Activar antes el inicio de sesión con código de dispositivo | El código caduca a los 15 minutos; en un espacio de trabajo decide el administrador |
| Entras al servidor por SSH desde un equipo con navegador | ssh -L 1455:127.1:1455 user@remote y codex login normal | Poder reenviar puertos | El puerto es fijo: 1455, o 1457 si el primero está ocupado |
| No puedes ni lo uno ni lo otro (contenedor, máquina aislada) | Copiar ~/.codex/auth.json desde otra máquina | Que las credenciales estén guardadas en archivo | Un archivo por máquina; volver a iniciar sesión en el origen puede invalidar la copia |
| No hay nadie ante la terminal: CI, tareas programadas | Clave de API o token de acceso | Una clave de la plataforma o un espacio de trabajo gestionado | La clave se factura por uso, fuera de tu plan de ChatGPT |

Los datos corresponden a Codex CLI 0.160.0, publicada el 1 de octubre de 2026, y proceden de la documentación de autenticación de OpenAI, del código fuente de la etiqueta rust-v0.160.0 y de una prueba hecha el 2 de octubre de 2026 en una máquina Linux desechable: Ubuntu 24.04, glibc 2.39, OpenSSH 9.6p1 y Codex CLI 0.160.0.
Qué se ejecutó de verdad en esa prueba:
- La forma corta
127.1se resuelve a la dirección IPv4 de bucle local. - Un reenvío SSH real con ese destino lleva el tráfico hasta un servicio que escucha solo en IPv4.
- Con
codex loginen marcha, ese mismo reenvío alcanza el servidor de devolución de llamada de Codex: una petición sin parámetros a/auth/callbacka través del túnel recibió400 Bad Requestcon el textoState mismatch, la respuesta con la que Codex rechaza una llamada que no viene de una autorización. - Con el puerto 1455 ocupado,
codex loginanunció el 1457. codex login --device-authimprimió el aviso de código de dispositivo, con su caducidad de 15 minutos.
Qué no se hizo: no se completó ningún inicio de sesión por ninguna de las vías, así que nada de lo anterior demuestra que un inicio de sesión termine bien; solo que las piezas previas se comportan como se describe. Tampoco se vio ninguna pantalla del navegador posterior a la autorización. Copiar auth.json a una segunda máquina, la renovación de tokens y la revocación no se ejercitaron: lo que se dice de ellas viene de la documentación y del código. Los sistemas con musl, como Alpine, quedaron sin comprobar. Y los dos extremos del túnel estaban en la misma máquina, no en dos equipos separados por una red.
Por qué codex login se queda a medias en un servidor sin navegador
El inicio de sesión normal necesita que el navegador y la CLI estén en la misma máquina. Al ejecutar codex login, Codex levanta un pequeño servidor web en la dirección de bucle local de esa máquina, puerto 1455, e intenta abrir un navegador. Tras autenticarte, la página de OpenAI redirige el navegador a ese puerto y, como dice la documentación, «el navegador devuelve tus credenciales a Codex».
En un servidor remoto ese último salto no llega. Abres en tu portátil la dirección que imprimió la CLI, inicias sesión, y el navegador intenta conectar con el puerto 1455 de tu propio portátil, donde no hay nada escuchando. El servidor sigue esperando una respuesta que nunca recibe. La documentación menciona un segundo caso con el mismo resultado: una configuración de red local que bloquea esa devolución de llamada, algo que OpenAI ha señalado en varios hilos sobre WSL con cortafuegos o VPN.
La propia CLI avisa de la salida. En la prueba en Linux, codex login imprimió Starting local login server on seguido del nombre de host de bucle local y el puerto 1455, y a continuación If your browser did not open, navigate to this URL to authenticate: con una dirección de auth.openai.com. Según el código de la 0.160.0, el mensaje se cierra con esta línea: On a remote or headless machine? Use codex login --device-auth instead.
Esto es lo que ofrece hoy el comando, tomado de codex login --help en la 0.160.0:
| Opción | Texto de la ayuda | Para qué sirve aquí |
|---|---|---|
--device-auth | Sin descripción | Inicio de sesión con código de dispositivo |
--with-api-key | «Read the API key from stdin» | Clave de API, sin navegador |
--with-access-token | «Read the access token from stdin» | Token de acceso de un espacio de trabajo |
status (subcomando) | «Show login status» | Comprobar el resultado |
No hay ninguna opción para elegir el puerto ni un --no-browser. Ese flag se propuso en un issue de GitHub en diciembre de 2025 y no existe en la 0.160.0. Tampoco vale ya --api-key: la CLI responde que no está soportado y que hay que pasar la clave por la entrada estándar.
codex login --device-auth: código de dispositivo desde otro equipo
Es la vía que la documentación de OpenAI pide preferir en entornos remotos o sin interfaz gráfica, y la única que no exige tocar la red: nada tiene que volver al servidor, porque es la CLI la que consulta a OpenAI hasta que autorizas. La documentación habla solo de «tu navegador»; por cómo funciona el flujo, puede ser el del portátil o el del móvil. OpenAI la etiqueta como beta.
Los pasos documentados son tres:
- Activa el inicio de sesión con código de dispositivo en los ajustes de seguridad de ChatGPT si la cuenta es personal, o en los permisos del espacio de trabajo si eres administrador.
- En el servidor, ejecuta el comando (o elige «Sign in with Device Code» en la pantalla de bienvenida de
codex):
codex login --device-auth- Abre el enlace en un navegador, inicia sesión e introduce el código de un solo uso.
Hasta el paso 2 hay salida observada en la 0.160.0; el paso 3 no se llegó a hacer. La terminal muestra esto, con un código distinto en cada ejecución:
Follow these steps to sign in with ChatGPT using device code authorization:
1. Open this link in your browser and sign in to your account
https://auth.openai.com/codex/device
2. Enter this one-time code (expires in 15 minutes)
(aquí aparece tu código)
Continue only if you started this login in Codex. If a website or another person gave you this code, cancel.Tómate en serio la última línea: quien introduce ese código autoriza a la máquina que lo generó.
Dónde está el ajuste es la parte menos documentada. Un miembro de OpenAI indicó en el issue #2798 las dos ubicaciones: chatgpt.com/#settings/Security para cuentas personales y chatgpt.com/admin/permissions para administradores. El nombre exacto del interruptor no figura en la documentación; usuarios lo citan como «Enable Codex Device Code Authorization» dentro de Seguridad. Tampoco está publicado en qué planes aparece ni si viene activado, así que búscalo en esa sección antes de ejecutar el comando.
Tres límites que conviene saber de antemano:
- Caducidad. Si no introduces el código en 15 minutos, la CLI termina, según el código fuente, con
device auth timed out after 15 minutes. Vuelve a ejecutar el comando y usa el código nuevo. - Espacios de trabajo. Si el administrador tiene desactivado el método, los miembros no pueden usarlo. Usuarios han citado el mensaje «Please contact your workspace admin to enable device code authentication» (issue #9253). En ese caso pasa al túnel o a la copia del archivo.
- Verificación de la cuenta. El código de dispositivo cambia dónde se abre el navegador, no lo que la cuenta tiene que superar: en issues que siguen abiertos, usuarios cuentan que la petición de verificación telefónica aparece igual por esta vía.
Si sigues una guía anterior a finales de 2025 y no menciona este flag, es por antigüedad: --device-auth llegó a la versión estable 0.44.0 el 3 de octubre de 2025 y la beta pública se anunció el 8 de diciembre de ese año.
Túnel SSH al puerto 1455 (o al 1457) para usar el login normal
Si entras al servidor por SSH desde un equipo con navegador, puedes hacer que el puerto 1455 de tu equipo lleve al puerto 1455 del servidor. Así el navegador encuentra el servidor de Codex donde lo busca, que es lo que le falta al flujo normal para poder cerrarse. Desde tu equipo local:
ssh -L 1455:127.1:1455 user@remoteDentro de esa misma sesión SSH, ejecuta codex login y abre en tu equipo local la dirección que imprime.

Una nota sobre la forma del comando. La documentación de OpenAI escribe el destino del reenvío con el nombre de host de bucle local; aquí aparece como 127.1, la forma abreviada estándar de la dirección IPv4 de bucle local, que apunta al mismo sitio. Hay un motivo para preferir la forma IPv4: desde la 0.158.0, del 28 de septiembre de 2026, Codex escucha solo en la dirección IPv4 de bucle local, y hay sistemas donde el nombre de host se resuelve primero a IPv6. El destino del reenvío lo resuelve el servidor, no tu equipo, así que lo que importa es cómo se comporta allí. En Ubuntu 24.04 con glibc 2.39 y OpenSSH 9.6p1 se observó lo siguiente: getent ahosts 127.1 devuelve la dirección IPv4 de bucle local, y un reenvío ssh -L con ese destino llegó al servidor de devolución de llamada de un codex login en marcha. La petición de prueba a /auth/callback, sin parámetros, obtuvo a través del túnel la misma respuesta que en directo: 400 Bad Request y State mismatch. Eso muestra que el túnel entrega la petición a Codex; no es un inicio de sesión completado, que no se hizo, y el túnel unía dos puertos de una misma máquina, no dos equipos. En sistemas con musl, como Alpine, la forma abreviada está sin comprobar: si tu servidor no la acepta, usa el comando tal como figura en la documentación enlazada arriba.
El puerto no se elige. En el código de la 0.160.0 está fijado en 1455 y no hay flag ni clave de configuración que lo cambie; mcp_oauth_callback_port afecta solo al OAuth de los servidores MCP. Lo que sí existe desde la 0.128.0, del 30 de abril de 2026, es una reserva automática: si el 1455 está ocupado en el servidor, Codex usa el 1457. No es solo lectura del código: con el 1455 ocupado por otro proceso, codex login anunció el 1457 en su línea Starting local login server on. La documentación todavía no lo menciona.
De ahí sale una consecuencia práctica, que es una deducción y no algo que diga OpenAI: si Codex arrancó en el 1457 y tu túnel solo cubre el 1455, la respuesta del navegador no llega. Mira el puerto que aparece en esa línea y reenvía ese. Otra posibilidad es abrir los dos desde el principio; es una sugerencia que no figura en la documentación y este comando no se ha ejecutado:
ssh -L 1455:127.1:1455 -L 1457:127.1:1457 user@remoteSolo cuando ambos puertos están ocupados la CLI falla con Port … is already in use. El mensaje se refiere a los puertos del servidor, así que lo primero que conviene mirar es si queda allí un codex login anterior sin cerrar.
Sobre los reenvíos automáticos de VS Code Remote-SSH o JetBrains Gateway no hay indicaciones de OpenAI. Cuando la devolución de llamada falla en WSL o en sesiones Remote-SSH, la respuesta de OpenAI en los issues ha sido atribuirlo a la red local y recomendar el código de dispositivo.
Copiar auth.json desde otra máquina: un archivo, una sola máquina
Cuando no puedes activar el código de dispositivo ni reenviar puertos, la documentación propone iniciar sesión donde sí hay navegador y llevar el resultado al servidor. Lo que se copia es la caché de credenciales, el archivo ~/.codex/auth.json:
- En el equipo con navegador, ejecuta
codex loginy completa el inicio de sesión. - Comprueba que existe
~/.codex/auth.json. - Cópialo a la misma ruta del servidor.
Los comandos de la documentación:
ssh user@remote 'mkdir -p ~/.codex'
scp ~/.codex/auth.json user@remote:~/.codex/auth.jsonSin scp, en una sola línea:
ssh user@remote 'mkdir -p ~/.codex && cat > ~/.codex/auth.json' < ~/.codex/auth.jsonPara un contenedor Docker:
CONTAINER_HOME=$(docker exec MY_CONTAINER printenv HOME)
docker exec MY_CONTAINER mkdir -p "$CONTAINER_HOME/.codex"
docker cp ~/.codex/auth.json MY_CONTAINER:"$CONTAINER_HOME/.codex/auth.json"El archivo contiene los tokens de acceso y de renovación de tu cuenta. OpenAI pide tratarlo como una contraseña: no subirlo a un repositorio, no pegarlo en una incidencia ni compartirlo por chat. Codex lo crea con permisos 0600 en Unix; después de copiarlo conviene dejarlo igual con chmod 600 ~/.codex/auth.json en el destino, un paso que no está en la documentación.
Cuándo no existe el archivo que hay que copiar
El método solo sirve si las credenciales se guardan en archivo. Lo decide la clave cli_auth_credentials_store de config.toml: file las escribe en auth.json, keyring usa el almacén de credenciales del sistema operativo, auto usa el almacén si está disponible y ephemeral las mantiene solo en memoria. En el código de la 0.160.0 el valor por defecto es file en todos los sistemas, aunque la documentación no declara ninguno y un administrador puede imponer otro. Si en el paso 2 no encuentras el archivo, mira esa clave. Y si has definido CODEX_HOME, el archivo está en ese directorio, que además tiene que existir de antemano en el servidor.
Qué le pasa a la copia si vuelves a iniciar sesión en el origen
La copia puede dejar de valer, y por dos caminos distintos.
El primero es la revocación. Desde mediados de junio de 2026 (PR #27674), cada codex login revoca y borra las credenciales que ya había en esa máquina antes de empezar, y codex logout también las revoca. La consecuencia para el servidor es una deducción sin probar, no una afirmación de OpenAI: si después de copiar el archivo vuelves a ejecutar codex login o codex logout en el portátil, lo revocado es justo lo que copiaste. En el servidor aparecería entonces: Your access token could not be refreshed because your refresh token was revoked. Please log out and sign in again.
El segundo es la rotación. Codex renueva los tokens durante el uso y reescribe el archivo: según la guía de CI/CD, cuando la última renovación tiene más de unos 8 días o cuando recibe un 401. Si dos máquinas comparten el mismo archivo, la primera que renueva deja a la otra con un token de renovación ya gastado. Por eso la guía es tajante: un auth.json por máquina o por flujo de trabajo en serie, nunca el mismo en varias máquinas ni en trabajos simultáneos. Un miembro de OpenAI precisó en el issue #10332 que un token de renovación admite reutilización durante una ventana limitada, del orden de una hora, y luego queda invalidado para siempre. Eso explica que dos servidores parezcan funcionar un rato con el mismo archivo y después uno se caiga.
La regla práctica: un inicio de sesión por servidor. Si necesitas tres servidores, repite el proceso tres veces, y deja el portátil sin tocar hasta haber terminado con cada uno, o usa en él otra vía.
CI y automatización: clave de API o token de acceso, no ChatGPT
Si no hay una persona que pueda abrir un navegador, la pregunta ya no es cómo iniciar sesión con ChatGPT sino con qué credencial debe funcionar el proceso. OpenAI recomienda la clave de API para los flujos programados como CI/CD:
printenv OPENAI_API_KEY | codex login --with-api-keyNo es una manera de usar tu plan de ChatGPT sin navegador: cambia quién paga. Con clave, el uso se factura a las tarifas estándar de la API en lugar de consumir los créditos incluidos en el plan, las funciones que dependen del espacio de trabajo de ChatGPT quedan limitadas o no disponibles, y Codex en la nube exige el inicio de sesión con ChatGPT. La comparación completa está en Codex con API key o suscripción ChatGPT: qué ruta usar.
Para ejecuciones no interactivas hay un detalle que evita perder tiempo. codex exec reutiliza por defecto la sesión guardada de la CLI, y la documentación del modo no interactivo indica que acepta además CODEX_API_KEY, igual que codex review y el SDK de TypeScript. La variable OPENAI_API_KEY suelta en el entorno no figura como credencial de codex exec, y el codex interactivo no lee CODEX_API_KEY.
En espacios de trabajo gestionados existe una tercera credencial, el token de acceso de Codex, pensado para automatizaciones de confianza:
printenv CODEX_ACCESS_TOKEN | codex login --with-access-tokenSe crea en chatgpt.com/admin/access-tokens cuando un propietario del espacio ha habilitado el permiso, con una caducidad de 7, 30, 60 o 90 días. Las páginas de OpenAI no coinciden sobre quién puede usarlo: la de autenticación habla de espacios ChatGPT Enterprise y la de tokens de acceso dice que se admite en Business y Enterprise.
Mantener en CI una sesión de cuenta de ChatGPT es posible, pero OpenAI lo presenta como caso avanzado: sembrar auth.json solo cuando falta, dejar que Codex lo renueve durante las ejecuciones, conservar el archivo renovado para el trabajo siguiente y no hacerlo nunca en repositorios públicos.
codex login status y qué hacer ante cada mensaje
Sea cual sea la vía, la comprobación es la misma y se hace en el servidor:
codex login statusCon una sesión de ChatGPT, el código de la 0.160.0 imprime Logged in using ChatGPT, y la documentación indica que el comando termina con código 0 cuando hay credenciales. Sin ellas, en la 0.160.0 la salida es Not logged in con código de salida 1, lo que permite usarlo como condición en un script. Si quieres ver qué pasó durante el intento, cada codex login escribe un registro en ~/.codex/log/codex-login.log.
| Lo que ves | Qué significa | Qué hacer |
|---|---|---|
Not logged in después de copiar el archivo | Codex no encuentra credenciales en su directorio | Revisa que el archivo esté en el ~/.codex del usuario que ejecuta Codex, o en el directorio de CODEX_HOME |
device auth timed out after 15 minutes | El código caducó sin usarse | Ejecuta de nuevo codex login --device-auth |
| La página pide activar «device code authorization» en los ajustes de seguridad (mensaje citado por usuarios) | El método está apagado en tu cuenta | Actívalo en Seguridad y repite el comando |
| «Please contact your workspace admin…» (mensaje citado por usuarios) | El espacio de trabajo lo tiene desactivado | Pídeselo al administrador o usa el túnel o la copia |
device code login is not enabled for this Codex server | El servidor de autenticación al que apunta la CLI no ofrece el método | Usa el flujo con navegador o revisa la URL del servidor configurada |
| El navegador no conecta tras autorizar | El túnel no cubre el puerto que usó Codex | Reenvía el puerto que imprimió la CLI: 1455 o 1457 |
Port … is already in use | 1455 y 1457 ocupados | Cierra en el servidor el codex login anterior que los retiene |
…refresh token was revoked | Se inició o cerró sesión en la máquina de origen | Inicia sesión de nuevo para este servidor |
…refresh token was already used | El mismo archivo se usa en más de una máquina | Un inicio de sesión por máquina |
ChatGPT login is disabled. Use API key login instead. | El administrador ha fijado forced_login_method | Usa el método permitido |
Dos casos más tienen su propia página. Si el inicio de sesión termina con un 403 en el intercambio de token, sigue Error 403 en el intercambio de token de Codex: inicio de sesión, proxy, región y caché. Si codex login status dice que hay sesión y las peticiones devuelven 401, la causa está en otro sitio: Codex 401 Incorrect API key provided: solución según el origen.
Detrás de un proxy corporativo que inspecciona TLS, el fallo suele ser de certificados y afecta a cualquier vía. La documentación indica exportar la raíz de la empresa antes de iniciar sesión:
export CODEX_CA_CERTIFICATE=/path/to/corporate-root-ca.pemSi esa variable no está definida, Codex recurre a SSL_CERT_FILE.
Dudas sobre varios servidores, WSL y versiones
¿Puedo usar el mismo inicio de sesión de Codex en dos servidores?
La misma cuenta sí; el mismo auth.json no. La guía de CI/CD de OpenAI pide un archivo por máquina, porque la primera que renueva el token deja inservible la copia de la otra. Haz un inicio de sesión independiente en cada servidor, con código de dispositivo o con túnel.
¿Qué pasa en el servidor si vuelvo a ejecutar codex login en mi portátil?
Si el servidor funciona con un auth.json copiado desde ese portátil, es probable que deje de funcionar: desde junio de 2026 cada codex login revoca primero las credenciales que había en la máquina, que son las mismas que copiaste. Es una deducción a partir del código, sin probar, no un comportamiento descrito por OpenAI. Si el servidor inició sesión por su cuenta con código de dispositivo o túnel, tiene credenciales propias y lo que hagas en el portátil no las toca.
¿Sirve esto para WSL?
Sí. WSL entra en el mismo caso cuando el navegador de Windows no alcanza la devolución de llamada dentro de la distribución. La recomendación de OpenAI en los issues cerrados sobre WSL es el código de dispositivo.
¿Tengo que actualizar Codex antes de intentarlo?
Para el código de dispositivo basta la 0.44.0 o posterior. El puerto de reserva 1457 existe desde la 0.128.0 y la escucha solo en IPv4 desde la 0.158.0, así que con una versión antigua el túnel se comporta de otra manera. Comprueba la tuya con codex --version; si aún no tienes la CLI en el servidor, empieza por Cómo instalar y configurar Codex CLI en Windows, macOS y Linux.





