ssh-agent es un programa en segundo plano que guarda tus claves privadas desbloqueadas en memoria y firma con ellas los desafíos de autenticación, así que introduces la frase de contraseña de una clave una vez por sesión en lugar de una vez por conexión. ssh-add es el comando que carga claves en él.
Has hecho lo correcto y le has puesto una frase de contraseña a tu clave SSH —y ahora la estás tecleando por quinta vez antes de comer. El arreglo existe desde hace décadas: el agente SSH. Desbloquea la clave una vez, y cada conexión posterior se autentica en silencio. El problema es que ese «una vez» solo funciona si el agente está de verdad en marcha, tu shell puede encontrarlo y la clave está cargada —tres cosas distintas, cada una con su propia forma de fallar. Esta es la guía práctica: arrancar el agente en cada SO, manejarlo con ssh-add, hacer que todo sea automático, y descifrar los dos errores que explican casi todos los problemas del agente.
Qué es el agente, en un párrafo
ssh-agent es un pequeño proceso en segundo plano que guarda tus claves privadas descifradas en memoria —nunca en disco. Cuando un servidor te lanza un desafío, ssh le pasa el desafío al agente, el agente lo firma con la clave en memoria, y solo la firma vuelve —la clave en sí nunca sale del agente, nunca toca el cable, y queda cifrada en disco. Una pregunta de la frase de contraseña para cargar la clave, y luego cada conexión posterior se sirve desde memoria. Ese es todo el modelo mental: el agente es un servicio de firma, no una bóveda de claves de la que alguien lee —guarda el secreto y solo entrega firmas. (Esa misma propiedad es también el truco de seguridad, y tiene su propia sección al final.)
¿En Windows? Lee primero la guía de Windows
Si llegaste aquí por error connecting to agent: No such file or directory, ese mensaje es específico de Windows: viene del ssh de Git Bash / MSYS2, y también sus soluciones — el servicio OpenSSH Authentication Agent, el propio agente de Git Bash y el error 1058. Están todas en ssh-agent en Windows. Todo lo de abajo es el flujo multiplataforma de ssh-agent y ssh-add, y los errores que decodifica son los propios del cliente OpenSSH: Could not open a connection to your authentication agent y The agent has no identities.
Arrancar el agente, según el SO
Linux — eval "$(ssh-agent -s)"
En un inicio de sesión de escritorio casi seguro que ya tienes un agente —o un servicio de usuario de systemd o GNOME Keyring haciendo el papel— con SSH_AUTH_SOCK exportado para toda tu sesión. Pruébalo con ssh-add -l. Si nada responde (común en un inicio de sesión SSH pelado, en contenedores, o en servidores mínimos), arranca uno a mano:
eval "$(ssh-agent -s)"
El eval importa. ssh-agent -s solo imprime las variables SSH_AUTH_SOCK y SSH_AGENT_PID; el eval es lo que las fija en tu shell actual para que ssh pueda encontrar el socket. Ejecutar ssh-agent pelado y preguntarse por qué no cambió nada es la forma más común de «arrancar» un agente que ninguna herramienta puede ver.
macOS — launchd lo ejecuta por ti
launchd ejecuta un agente por ti desde el inicio de sesión —no hay nada que arrancar. La ventaja específica de macOS es la integración con el Keychain de más abajo.
Arranca ssh-agent en Windows
El Windows moderno trae un servicio OpenSSH Authentication Agent, pero está puesto en arranque manual y no corre por defecto. Actívalo una vez, desde un PowerShell elevado:
Set-Service ssh-agent -StartupType Automatic
Start-Service ssh-agent
Después, ssh-add funciona en cualquier terminal —PowerShell, cmd, o el cliente OpenSSH de Windows bajo Git Bash— y el agente sobrevive a los reinicios. Una trampa: Git para Windows trae su propio ssh y ssh-agent, y dentro de Git Bash el ssh de tu PATH puede ser ese, hablando con un agente aparte. Si ssh-add -l discrepa entre Git Bash y PowerShell, apunta Git al cliente del sistema para que ambos compartan un agente:
git config --global core.sshCommand "C:/Windows/System32/OpenSSH/ssh.exe"
El recorrido completo —el servicio, Git Bash y cargar claves al iniciar sesión— está en ssh-agent en Windows.
Manejarlo con ssh-add
Carga una clave: ssh-add ~/.ssh/id_ed25519
ssh-add # carga las claves por defecto (id_ed25519, id_rsa, …)
ssh-add ~/.ssh/id_ed25519 # carga una clave concreta (pide la frase de contraseña una vez)
Sin ruta, ssh-add carga los nombres de clave por defecto de ~/.ssh; dale una ruta para cargar una clave concreta. En cualquier caso pide la frase de contraseña una vez y luego mantiene la clave descifrada en memoria.
Lista lo que está cargado: ssh-add -l
ssh-add -l # lista las huellas de las claves cargadas
ssh-add -L # imprime las claves públicas completas
ssh-add -d ~/.ssh/id_ed25519 # quita una clave
ssh-add -D # quita todas las claves
ssh-add -l es el primer diagnóstico para cualquier problema de auth: si la clave que esperas no está en esa lista, el agente no puede firmar con ella, por bien que se vea todo lo demás.
Pon un tiempo de espera al agente: ssh-add -t
Dos flags vale la pena volverlos costumbre:
-tfija una duración.ssh-add -t 3600 ~/.ssh/id_ed25519carga la clave durante una hora; después el agente la olvida y el siguiente uso vuelve a preguntar. Una clave que se queda desbloqueada en memoria durante tres semanas de uptime es una clave utilizable mucho después de que dejaras de pensar en ella.-cexige confirmación. Cada petición de firma lanza un aviso local antes de que el agente responda. Ligeramente molesto, exactamente lo correcto para claves de alto valor.
Hazlo automático: AddKeysToAgent
El ritual manual de ssh-add desaparece con una línea en ~/.ssh/config (en inglés):
Host *
AddKeysToAgent yes
Ahora el primer ssh que necesite una clave pide la frase de contraseña una vez y carga la clave en el agente como efecto secundario. Ningún comando aparte que recordar —el aviso simplemente deja de repetirse. También puedes ponerle una duración (AddKeysToAgent 1h) para obtener el comportamiento de -t sin el flag.
macOS: sobrevive a los reinicios con el Keychain. Por defecto el agente olvida las claves al reiniciarse. macOS puede guardar la frase de contraseña en tu keychain de inicio de sesión para que las claves se recarguen sin reteclear:
ssh-add --apple-use-keychain ~/.ssh/id_ed25519
y en ~/.ssh/config:
Host *
AddKeysToAgent yes
UseKeychain yes
Después, la pregunta de la frase de contraseña la responde el Keychain al iniciar sesión y no vuelves a verla —mientras el archivo de la clave en disco sigue cifrado.
Los dos errores que todos se encuentran
Could not open a connection to your authentication agent —ssh-add no encuentra un agente. O no hay ninguno en marcha, o hay uno pero este shell no tiene SSH_AUTH_SOCK fijado. El arreglo es el arranque por SO de arriba: la línea eval "$(ssh-agent -s)" en Linux (comprueba primero si tu sesión de escritorio ya provee uno —arrancar un segundo agente por terminal solo desperdiga las claves cargadas entre procesos), el arranque del servicio en Windows. También te lo encontrarás en trabajos de cron y en CI, donde ninguna sesión de inicio exportó nunca la variable.
The agent has no identities. —el problema opuesto: el agente está bien, pero no hay nada cargado. Haz ssh-add de tu clave. Si estaba cargada y desapareció, expiró una duración de -t o el agente se reinició —que es precisamente para lo que están AddKeysToAgent yes y el Keychain de macOS.
Y el tercer caso: el agente se ve perfecto —ssh-add -l muestra la clave— pero el servidor sigue diciendo Permission denied (publickey). Eso ya no es un problema del agente; recorre la lista de publickey —usuario equivocado, clave equivocada ofrecida, permisos de authorized_keys.
Un agente desbloqueado es una credencial viva
El agente nunca filtra la clave —pero el socket es un oráculo de firma: firma para quienquiera que pueda llegar a él, y nunca pregunta quién pregunta. En tu propia máquina eso está bien —el socket vive en un directorio privado por usuario que solo tú puedes leer. El peligro tiene la forma del diputado confundido (confused deputy): cuando el socket se vuelve accesible para algo que no pretendías —un agente reenviado en un bastión compartido, o un proceso que corre como tu usuario en el que no confías—, esa cosa puede autenticarse como tú ante todos los servidores que alcanzan tus claves, sin ver jamás la clave. Que la clave nunca se filtre es solo la mitad de la garantía; controlar quién puede usarla es la otra mitad, y es por lo que la higiene del agente vale el pequeño esfuerzo.
- Da a las claves una duración (
-t, o una duración enAddKeysToAgent) para que un agente ocioso se enfríe solo. - Bloquea el agente al alejarte:
ssh-add -xlo bloquea tras una contraseña,ssh-add -Xlo desbloquea;ssh-add -Dsimplemente lo suelta todo. - Usa
-cpara las claves que llegan a producción. - No reenvíes el agente por defecto.
ssh -A—el reenvío del agente SSH— expone el uso en vivo de tus claves en el host remoto, así que cualquiera con root ahí puede firmar como tú durante toda tu sesión. Eso merece su propia lectura: el reenvío del agente SSH es cómodo y peligroso (en inglés).
Cómo lo maneja Termalin
Termalin trae todo este flujo integrado, con las aristas limadas. Su agente de claves desbloquea tus claves una vez y firma en tu nombre —sin servicio del SO que activar, sin línea eval, sin socket por shell que perder. El caché de la frase de contraseña viene con un tiempo de re-bloqueo por defecto, que es la costumbre de ssh-add -t impuesta por ti en vez de recordada por ti. Y como habla el protocolo ssh-agent estándar, git y tus herramientas de CLI de siempre firman a través de él sin cambios —reemplaza el ritual, no tu cadena de herramientas.
Termalin es un cliente SSH gratis y multiplataforma cuyo agente integrado desbloquea tus claves una vez y las vuelve a bloquear con un temporizador — descárgalo, o lee cómo maneja tus claves de forma segura.