Cómo hacer bien la autenticación en la CLI: la guía completa de los 4 métodos
Los 4 métodos de autenticación en CLI que importan, cómo los implementan GitHub, AWS y herramientas de IA, y los errores de seguridad que querrás evitar.
Los 4 métodos de autenticación en CLI que importan, cómo los implementan GitHub, AWS y herramientas de IA, y los errores de seguridad que querrás evitar.
Cada CLI para desarrolladores incluye login como su primer comando. Y cada una resuelve la autenticación de manera diferente.
GitHub te muestra un código y abre tu navegador para verificarlo. AWS abre el navegador para un SSO basado en PKCE. Stripe te pide confirmar un código de emparejamiento en el panel. Las herramientas de IA más nuevas (Claude Code, OpenAI Codex CLI, Cursor) también eligieron cada una su propio enfoque.
Si estás creando una CLI, la autenticación será de las primeras cosas que tendrás que definir. Si eliges el método incorrecto, lo notarás: usuarios frustrados, auditorías de seguridad, o ambos. Y con la reciente ola de agentes de codificación de IA que llaman a herramientas CLI de forma programática, el riesgo aumenta: ya no solo autenticas a un humano. Podrías estar entregando credenciales a un proceso autónomo.
Aquí están los cuatro métodos de autenticación que importan, cómo los implementan las herramientas más grandes y los errores que debes evitar.
Antes de entrar en detalles, aquí va una comparación rápida:
| Método | Mejor para | Seguridad | ¿Requiere navegador? |
|---|---|---|---|
| OAuth Device Code Flow | Entornos sin cabeza, SSH | Alta | No (en la misma máquina) |
| OAuth basado en navegador (redirect a localhost) | Desarrollo local | Máxima | Sí |
| Claves API / PATs | Automatización, CI/CD, prototipado rápido | Moderada | No |
| Credenciales de cliente | De máquina a máquina, servicios | Alta | No |
Cada uno tiene pros y contras. Esto es lo que tienes que saber de cada uno.
Este es el que tu CLI te muestra un código como ABCD-1234 y una URL, y luego te pide abrir esa URL en cualquier dispositivo e ingresar el código.
Quién lo usa: GitHub CLI (por defecto), Azure CLI (vía --use-device-code), Vercel CLI (recientemente cambió a esto como predeterminado), OpenAI Codex CLI (como opción beta)
cli loginclient_id y los permisos solicitadosdevice_code (identificador interno), un user_code (el código corto que ingresas), y un verification_uri (dónde ir)Su mayor ventaja: funciona en todos lados. ¿SSH a un servidor remoto? Funciona. ¿Ejecutas dentro de un contenedor Docker? Funciona. ¿IDE en la nube sin navegador local? Funciona. El navegador no tiene que estar en la misma máquina que la CLI.
Además, soporta toda la gama de métodos empresariales (SAML, OIDC, MFA) porque todo pasa en el navegador, no en el terminal. La CLI nunca ve tu contraseña.
El device code flow tiene un problema de phishing. Un atacante puede iniciar una solicitud de código de dispositivo, obtener un código legítimo e inducirte a ingresarlo, autorizando así la sesión del atacante. Esto no es teórico. Investigadores han documentado este ataque contra AWS SSO.
Esto es suficientemente grave que AWS cambió su predeterminado. A partir de AWS CLI v2.22.0, el default para aws sso login pasó de device code flow a autorización basada en código PKCE. Device code sigue disponible por --use-device-code, pero ya no es la vía principal.
Mientras tanto, el tenant propio de Microsoft ha empezado a bloquear por completo device code flow vía políticas de acceso condicional, señal clara de que lo consideran de alto riesgo.
Así que hay cierta división: Vercel adoptó device code flow como su default en septiembre de 2025, mientras AWS se alejó de él. El patrón es: device code flow es genial donde de verdad no puedes abrir un navegador, pero si lo puedes abrir local, PKCE es más seguro.
Por el lado de los proveedores, la demanda claramente crece. Logto acaba de lanzar soporte para Device Authorization Grant de OAuth 2.0 para apps nativas en v1.38.0 (código abierto) y Logto Cloud, así que ya puedes habilitarlo como método de autorización para cualquier app nativa. Esto importa si construyes una CLI. Implementar correctamente RFC 8628 (expiración, rate limit, lógica de polling y UX de la página de verificación) requiere más trabajo de lo que la mayoría espera, así que si tu proveedor lo maneja, solo tienes que hacer las llamadas HTTP correctas.
Algunos puntos clave del RFC 8628:
expires_in para device codes lo pone el auth server. El RFC usa 1800 segundos (30 minutos) como ejemplo, pero no es fijo.interval de polling, los clientes deben usar por defecto 5 segundos.slow_down, añade 5 segundos al intervalo.Este es el método más común para CLIs en la máquina local de un desarrollador. Ejecutas login, tu navegador se abre, te autenticas y el navegador redirige de vuelta a un servidor local que levantó la CLI. Las implementaciones modernas agregan PKCE (pronunciado "pixie") encima, que dificulta su explotación.
Quién lo usa: Claude Code, gcloud CLI, Terraform CLI, AWS CLI v2.22+ (para SSO, PKCE es por defecto)
cli loginhttp://127.0.0.1:8742)http://127.0.0.1:8742/callback?code=XXXX&state=YYYYLa experiencia es fluida. Sin copiar códigos, ni teclear URLs. Solo se abre y se cierra una pestaña.
Esto solo funciona cuando la CLI puede abrir un navegador y enlazarse a localhost. Eso descarta:
Por esto, la mayoría de las herramientas que usan browser OAuth también soportan un fallback (usualmente device code flow o claves API).
Fallo 1: Atar el servidor de callback a 0.0.0.0 en vez de 127.0.0.1
El error más común y grave. Si tu servidor escucha todas las interfaces, cualquiera en la red puede interceptar el código de autorización.
Lo he visto en CLIs en producción. Es un error fácil porque muchas librerías server HTTP usan 0.0.0.0 por defecto.
Fallo 2: No validar el parámetro state
El parámetro state es tu protección CSRF. Sin él, un atacante puede hacer que tu CLI acepte códigos de una sesión maliciosa.
Fallo 3: No usar PKCE
Si tu flujo OAuth no usa PKCE (Proof Key for Code Exchange), el código de autorización puede interceptarse y ser reutilizado.
En el authorization code flow estándar, si un atacante intercepta el código (ya sea por red o leyendo la URL), puede canjearlo por tokens. PKCE previene esto exigiendo prueba de que la petición de token viene del mismo cliente que inició la autorización.
Esto añade PKCE al flujo:
code_verifier aleatorio (string de alta entropía)code_challenge hasheando el verifier por SHA-256code_verifier originalUn atacante que intercepte el código no tiene el verifier, no puede completar el canje.
Por esto AWS CLI v2.22+ hizo PKCE el default para SSO, dejando atrás device code flow. Si la CLI puede abrir navegador en la misma máquina, browser OAuth con PKCE es siempre mejor — misma UX, garantías de seguridad más fuertes, sin vector de phishing. Device code flow es lo correcto si el navegador no puede estar en la misma máquina (SSH, contenedores, entornos remotos), pero eso no es lo usual para desarrollo local.
El enfoque más simple. Generas un token en un panel web, lo pegas en el config de la CLI o una variable de entorno, ¡y listo!
Quién lo usa: Stripe CLI (como opción de login), npm, pip, la mayoría de herramientas de IA como fallback (Claude Code con ANTHROPIC_API_KEY, OpenAI con OPENAI_API_KEY, Aider)
sk_live_, ghp_, npm_)~/.config/stripe/config.toml, ~/.aws/credentials) o una variable de entornoLa CLI la lee al iniciar y la manda en peticiones API como un token Bearer en la cabecera Authorization.
Para automatización, las API keys son difíciles de superar. Funcionan en CI/CD, contenedores, scripts, cron jobs. Donde puedas leer una variable de entorno. Sin navegador. Sin prompts interactivos. Sin tokens de actualización.
Para los flujos de agentes AI, API keys es lo más práctico. Cuando Claude Code o Cursor necesitan llamar una API, una variable de entorno con una API key es lo más simple.
Lo ideal con API keys: intercambiarlas por tokens de vida corta en tiempo de ejecución.
AWS innovó con STS (Security Token Service). Tus credenciales de larga duración solo se usan para pedir credenciales temporales que expiran en una hora. Herramientas como aws-vault automatizan esto.
Aunque empieces con API keys, agrega este patrón. Limita el daño de una clave comprometida de "hasta que lo notes" a "una hora".
Este flujo OAuth 2.0 está pensado para autenticación de máquina a máquina: servicios hablando entre sí, sin humanos involucrados.
Usado en: pipelines CI/CD, servicios en background, herramientas automáticas
El servicio envía su client_id y client_secret al servidor auth y recibe un access token de vida corta. Sin navegador, ni interacción, ni redirect.
Úsalo cuando:
No lo uses para humanos. No soporta MFA, SSO ni nada interactivo.
Aquí un desglose actualizado según documentación y código fuente. Muchos artículos lo reportan mal porque los defaults cambian seguido.
| Herramienta CLI | Auth por defecto | Fallbacks | Almacenamiento de tokens |
|---|---|---|---|
GitHub CLI (gh) | Device code via navegador | PAT (--with-token), var env (GH_TOKEN) | Llavero de SO (fallback: archivo plano) |
| AWS CLI v2 | PKCE auth code flow (SSO) | Device code (--use-device-code), archivos credenciales | ~/.aws/sso/cache/ |
Azure CLI (az) | WAM en Windows; browser auth en Linux/macOS | Device code (--use-device-code) | ~/.azure/msal_token_cache.* |
| Vercel CLI | Device code flow (por defecto, sep 2025) | Token API (--token, var env) | ~/.local/share/com.vercel.cli/auth.json |
| Stripe CLI | Flujo de emparejamiento por navegador | API key (--interactive, --api-key o var env) | ~/.config/stripe/config.toml |
| gcloud CLI | Browser OAuth | --no-browser manual | ~/.config/gcloud/ |
| Claude Code | Browser OAuth | API key (var env, apiKeyHelper) | Llaveros SO/ ~/.claude/.credentials.json |
| OpenAI Codex CLI | Browser OAuth | Device code (beta), API key | ~/.codex/auth.json / llavero SO |
| Terraform CLI | Browser OAuth | Pegar token | ~/.terraform.d/credentials.tfrc.json |
La tendencia es clara: browser-based OAuth es el default para desarrollo local, device code flow es el fallback para headless, y API keys para automatización. PKCE va ganando como la opción más segura cuando hay navegador.
Hacer bien la autenticación no sirve si guardas mal los tokens.
Cada SO principal tiene almacén cifrado integrado:
Dan cifrado a nivel SO, control de acceso e integración de hardware. No necesitas implementar cripto propia.
Si no tienes llavero (contenedores, Linux minimalista), usa archivos cifrados con permisos restringidos:
Archivos en texto plano. Parece obvio pero muchos lo siguen haciendo. Un archivo de token plano es accesible por cualquier proceso de tu usuario, herramientas de backup, o cualquiera con acceso temporal a tu máquina.
Variables de entorno para almacenamiento a largo plazo. Las var env se ven en process listings, pueden ser logueadas por crash reporters y heredadas por procesos hijos. Está bien en CI/CD (el CI gestiona el secreto) pero es arriesgado en desarrollo local.
localStorage del navegador. Si tu CLI tiene componente web, no guardes tokens allí. Una XSS los expone todos.
Mantenlos de vida corta. Una hora es el estándar. Al expirar, la CLI debe renovarlo en silencio. La persona no debería tener que hacer login de nuevo por operaciones normales.
Los refresh tokens permiten obtener nuevos access tokens sin reautenticación. Son valiosos para atacantes (duran días o meses).
Los sistemas modernos rotan refresh tokens en cada uso:
Esto reduce el daño si te roban un refresh token. Si un atacante usa uno ya usado por la CLI real, el server detecta el reuso e invalida toda la familia de tokens. Así tanto el token del atacante como el del usuario dejan de funcionar, forzando nuevo login y evitando el acceso del atacante.
Ya lo cubrimos antes, pero repito: siempre usa 127.0.0.1, nunca 0.0.0.0.
Sucede más de lo que piensas. Un log de debug, un error handler que imprime cabeceras, un modo verbose...
Las imágenes Docker no son almacenes de secretos. Cada capa es extraíble.
Cuando un token expira durante una operación, no crashes con error 401. Intenta refrescar, y solo pide re-login si el refresh token también expiró.
No pidas scope admin:* si solo necesitas repo:read. Aplica tanto para scopes de OAuth como permisos de claves API.
Si un agente de IA usa tu CLI, esto es todavía más importante. Probablemente no quieres que tenga permisos para borrar repos solo porque necesita leer código.
Esto hace que 2026 sea diferente de 2023: las CLI ya no son solo para humanos tecleando. Agentes codificadores IA como Claude Code, Codex y el modo agente de Cursor llaman a CLIs de forma programática. Esto suma nuevos retos de autenticación:
Permisos delegados. Cuando Claude Code ejecuta gh pr create por ti, usa tus credenciales de GitHub. ¿Debe un agente IA tener tus mismos permisos? El mínimo privilegio dice que no, pero casi ninguna herramienta permite reducir el alcance solo para agentes.
Exposición de credenciales. Si tu API key está en una var de entorno, cualquier proceso puede leerla, incluido el subproceso del agente de IA. Herramientas como Claude Code han implementado scripts apiKeyHelper que generan tokens temporales bajo demanda, pero esto no es universal.
Auth sin cabeza para agentes. Un agente IA en entorno aislado no puede abrir un navegador. Device code flow funciona (el humano aprueba en otro dispositivo), pero las API keys son aún más comunes porque no requieren interacción humana.
Auditorías. Cuando un agente IA hace llamadas API con tus credenciales, el log de auditoría dice que tú hiciste esas llamadas. No hay manera estándar de distinguir "humano" de "agente actuando por humano".
Esto evoluciona rápido. Lo mejor que puedes hacer ahora:
¿Eligiendo método de autenticación? Resumen rápido:
"Mis usuarios son desarrolladores en local" → OAuth con PKCE en navegador (mejor seguridad + UX suave)
"Mi CLI debe funcionar por SSH y en contenedores" → Device code flow como fallback, OAuth en navegador como primaria
"Esto corre en CI/CD sin humanos" → Client credentials o API keys acotadas
"Necesito implementar lo más rápido posible" → API keys (agrega rotación después)
"Clientes enterprise requieren SSO y MFA" → Cualquier flujo OAuth (device code o navegador), compatible con el stack enterprise
"Agentes IA usarán la CLI" → Soporta API keys (para integración fácil de agentes) + OAuth en navegador (para usuarios humanos), con permisos acotados y tokens de vida corta
Es seguro ante la mayoría de ataques, pero tiene una vulnerabilidad de phishing. Un atacante puede generar un código y engañar a usuarios para autorizarlo. Por eso AWS usa PKCE como predeterminado en SSO. Para entornos sin cabeza donde PKCE no es práctico, device code flow sigue siendo la mejor opción. Solo ten en cuenta el riesgo de phishing.
En CI/CD: sí, porque la plataforma los cifra en reposo e inyecta según ejecución. Para desarrollo local: no. Usa el llavero del SO. Las var de entorno se ven en listas de procesos y pueden ser logueadas o filtradas a procesos hijos.
En la práctica, poca. Ambos son credenciales de larga duración que autentican peticiones. Es más una diferencia organizacional: las API keys suelen estar ligadas a un proyecto/app, los PATs a cuentas de usuario. Algunos servicios los usan indistintamente.
Access tokens: cada hora o menos (refrescado automático). Refresh tokens: rota en cada uso (el servidor auth lo hace). API keys: al menos cada 90 días o inmediatamente si sospechas exposición. En la práctica, la mayoría solo rota API keys tras un incidente, que es tarde.
Tres opciones, en orden de preferencia:
docker run -e API_KEY=${API_KEY}) para CI/CDdocker run -v ~/.config/tool:/root/.config/tool:ro) para desarrollo localNunca metas credenciales en la imagen. Nunca.
MCP es el nuevo estándar para que agentes IA se conecten a servicios externos. Introduce otra dimensión: el agente necesita credenciales para el servidor MCP, que a su vez necesita para las APIs downstream. Se está estandarizando aún. Por ahora, la mayoría de implementaciones usan API keys o tokens OAuth pasados en la config de MCP. Espera que esto evolucione rápido.
La autenticación en CLI cambia rápidísimo. Lo que era best-practice hace dos años (device code flow como default, archivos de credenciales en plano) ya está quedando atrás. Si sumas auth a una CLI hoy, empieza con OAuth en navegador + PKCE para humanos, API keys para automatización, y prepárate para el día en que los agentes de IA sean tus principales usuarios.