
SSH para developers: claves, servidores y agentes IA
Configura SSH paso a paso: conexion a servidores, deploy keys en GitHub, y como proteger tus claves cuando usas Claude Code o Cursor.
SSH te autentica sin contrasenas usando criptografia asimetrica. En lugar de enviar un secreto por la red, demuestras que tienes la clave privada sin revelarla jamas.
Este tutorial cubre tres escenarios que vas a encontrarte si o si:
- Conectar desde tu PC a un servidor
- Que tu servidor clone repos privados de GitHub
- Usar SSH con agentes de IA (Claude Code, Cursor, Copilot Workspace...)
Una vez entiendas estos tres, entiendes SSH.
Como funciona: pares de claves
Siempre trabajas con un par:
| Clave | Donde vive | Que hace |
|---|---|---|
| Privada | Nunca sale de donde se genero | Firma mensajes para demostrar identidad |
| Publica | Se copia a donde quieres acceder | Verifica que la firma es valida |
Piensalo asi: la privada es tu DNI. La publica es una fotocopia que dejas en recepcion de los sitios donde quieres que te dejen pasar.
Caso 1: Conectar tu PC a un servidor
El escenario mas comun. Quieres hacer ssh usuario@servidor sin escribir contrasena cada vez.
Paso 1: Genera el par en tu PC
ssh-keygen -t ed25519 -C "tu-email@ejemplo.com"
Esto crea dos ficheros en ~/.ssh/:
~/.ssh/
├── id_ed25519 # Clave privada — no la compartas jamas
└── id_ed25519.pub # Clave publica — esta si la copias
Paso 2: Copia la publica al servidor
# Opcion automatica (recomendada)
ssh-copy-id usuario@ip-del-servidor
# Opcion manual
cat ~/.ssh/id_ed25519.pub | ssh usuario@ip-del-servidor "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
Paso 3: Conecta
ssh usuario@ip-del-servidor
Sin contrasena. SSH firma con tu clave privada, el servidor verifica con la publica que tiene guardada.
Que hay en el servidor
~/.ssh/
└── authorized_keys # Una linea por cada PC/persona autorizada
El contenido es simple:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... tu-email@ejemplo.com
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... otro-dev@empresa.com
Quieres dar acceso a alguien? Anade su .pub como nueva linea. Revocar? Borra la linea.
Diagrama del flujo
TU PC SERVIDOR
───── ────────
~/.ssh/id_ed25519 ──firma──►
~/.ssh/id_ed25519.pub ~/.ssh/authorized_keys
◄─verifica─
Caso 2: Tu servidor necesita acceso a GitHub
El servidor tiene que clonar repos privados o hacer git pull en deployments automaticos.
Paso 1: Genera el par en el servidor
ssh-keygen -t ed25519 -C "deploy@mi-servidor"
Paso 2: Anade la publica a GitHub
cat ~/.ssh/id_ed25519.pub
Copia el contenido y ve a:
- Un repo concreto: Settings > Deploy Keys > Add deploy key
- Todos tus repos: Profile > Settings > SSH Keys
Paso 3: Prueba la conexion
ssh -T git@github.com
Si funciona:
Hi usuario! You've successfully authenticated...
Paso 4: Clona o haz pull
git clone git@github.com:usuario/repo-privado.git
Sin credenciales.
Diagrama
SERVIDOR GITHUB
──────── ──────
~/.ssh/id_ed25519 ──firma──►
~/.ssh/id_ed25519.pub Deploy Key
◄─verifica─
Caso 3: SSH con agentes de IA
Aqui es donde muchos developers la lian sin darse cuenta.
Herramientas como Claude Code, Cursor, Aider o Copilot Workspace ejecutan comandos en tu nombre. Cuando dices "despliega esto en produccion" o "clona el repo y arregla el bug", el agente necesita acceso SSH.
El problema
Tu clave SSH privada es lo mas sensible que tienes. Si un agente tiene acceso a ~/.ssh/id_ed25519, tiene acceso a todo lo que esa clave abre: servidores de produccion, repos privados, infraestructura critica.
No es que el agente sea malicioso. Es que:
- Errores de contexto: le pides que "limpie ficheros temporales" y borra
~/.ssh/porque interpreto mal - Prompt injection: codigo malicioso en un repo que clona le inyecta instrucciones
- Logs y telemetria: algunos agentes loguean comandos ejecutados, incluyendo claves si las pasas inline
- Scope excesivo: le das acceso a produccion para una tarea que solo necesitaba staging
Reglas para usar SSH con agentes
1. Nunca expongas tu clave principal
Crea claves especificas para el agente con permisos minimos:
# Clave solo para el agente, solo para staging
ssh-keygen -t ed25519 -f ~/.ssh/id_agent_staging -C "agent-staging-only"
2. Usa deploy keys de solo lectura
En GitHub, no marques "Allow write access" a menos que el agente realmente necesite hacer push.
3. Limita el scope en ~/.ssh/config
# El agente solo puede usar esta clave para staging
Host staging-for-agent
HostName staging.miempresa.com
User deployer
IdentityFile ~/.ssh/id_agent_staging
# Produccion ni aparece en su config
4. Usa passphrase + ssh-agent con timeout
# Clave protegida con passphrase
ssh-keygen -t ed25519 -f ~/.ssh/id_agent -C "agent"
# (te pedira passphrase)
# Anadela al agente SSH con expiracion de 1 hora
ssh-add -t 3600 ~/.ssh/id_agent
El agente de IA puede usar la clave mientras este en memoria, pero no puede extraerla ni usarla despues del timeout.
5. Audita que comandos ejecuta
Antes de dar acceso SSH a un agente, entiende que va a hacer. Si la tarea es "formatea este codigo", no necesita SSH. Si es "despliega en produccion", piensatelo dos veces.
6. Separa entornos radicalmente
~/.ssh/
├── id_personal # Tu uso, nunca para agentes
├── id_trabajo # Uso manual en trabajo
├── id_agent_staging # Solo agentes, solo staging
└── id_agent_ci # Solo CI/CD automatizado
7. Considera un vault para claves sensibles
En lugar de dejar claves en disco, usa un gestor de secretos que requiera autenticacion explicita para cada uso. El agente no puede usar lo que no tiene.
Lo que NO debes hacer
- Dar al agente tu
~/.ssh/id_ed25519principal - Ejecutar comandos SSH que el agente sugiere sin revisarlos
- Asumir que "es solo desarrollo" cuando la clave tambien abre produccion
- Poner claves privadas en variables de entorno que el agente puede leer
- Confiar en que el agente "sabe" que claves son sensibles
Ejemplo de setup seguro para Claude Code
# 1. Crea clave especifica
ssh-keygen -t ed25519 -f ~/.ssh/id_claude_code -C "claude-code-dev"
# 2. Config restrictivo
cat >> ~/.ssh/config << 'EOF'
Host dev-server
HostName 192.168.1.50
User developer
IdentityFile ~/.ssh/id_claude_code
EOF
# 3. Solo esta clave en authorized_keys del servidor de dev
# (no en produccion)
# 4. En GitHub: deploy key de solo lectura en repos no criticos
Ahora Claude Code puede trabajar en tu servidor de desarrollo, pero no tiene acceso a produccion ni puede hacer push a repos criticos.
Anatomia del directorio ~/.ssh/
| Fichero | Que es | Nombre fijo? |
|---|---|---|
id_ed25519 | Tu clave privada | No, es el default |
id_ed25519.pub | Tu clave publica | No, es el default |
authorized_keys | Claves publicas que pueden conectar | Si |
known_hosts | Huellas de servidores conocidos | Si |
config | Configuracion de hosts y aliases | Si |
El fichero known_hosts
La primera vez que conectas a un servidor, SSH pregunta:
The authenticity of host '192.168.1.100' can't be established.
ED25519 key fingerprint is SHA256:xXxXxXx...
Are you sure you want to continue connecting (yes/no)?
Si dices yes, guarda la huella. La proxima vez no pregunta.
Si el servidor cambia (lo reinstalaste, cambio de IP), SSH avisa:
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
Solucion:
ssh-keygen -R 192.168.1.100
Multiples claves con ~/.ssh/config
Si manejas varios servidores y servicios:
# Produccion
Host prod
HostName 162.55.62.72
User deployer
IdentityFile ~/.ssh/id_produccion
# Desarrollo
Host dev
HostName 192.168.1.50
User dev
IdentityFile ~/.ssh/id_desarrollo
# GitHub personal
Host github.com
IdentityFile ~/.ssh/id_github_personal
# GitHub trabajo (cuenta diferente)
Host github-trabajo
HostName github.com
IdentityFile ~/.ssh/id_github_trabajo
Ahora:
ssh prod # en lugar de ssh deployer@162.55.62.72
git clone git@github-trabajo:empresa/repo.git
Diagrama completo
TU PC SERVIDOR GITHUB
───── ──────── ──────
~/.ssh/ ~/.ssh/
├── id_ed25519 ───────────────► authorized_keys
├── id_ed25519.pub ├── id_ed25519 ─────────────────► Deploy Key
├── id_agent_staging ─────────► authorized_keys (solo staging)
├── known_hosts ├── id_ed25519.pub
└── config └── known_hosts
Flujo 1: PC > Servidor
Firma con privada local, verifica con publica en authorized_keys
Flujo 2: Servidor > GitHub
Firma con privada del servidor, verifica con publica en Deploy Keys
Flujo 3: Agente IA > Servidor dev
Usa clave especifica con scope limitado
Comandos de referencia
# Generar par de claves
ssh-keygen -t ed25519 -C "comentario"
# Generar con nombre especifico
ssh-keygen -t ed25519 -f ~/.ssh/mi_clave -C "comentario"
# Copiar publica a servidor
ssh-copy-id usuario@servidor
# Ver tu clave publica
cat ~/.ssh/id_ed25519.pub
# Probar conexion a GitHub
ssh -T git@github.com
# Limpiar huella de servidor antiguo
ssh-keygen -R ip-del-servidor
# Conectar con clave especifica
ssh -i ~/.ssh/mi_clave usuario@servidor
# Ver fingerprint de una clave
ssh-keygen -lf ~/.ssh/id_ed25519.pub
# Anadir clave al agente SSH con timeout (1 hora)
ssh-add -t 3600 ~/.ssh/mi_clave
# Listar claves en el agente SSH
ssh-add -l
# Eliminar todas las claves del agente SSH
ssh-add -D
Errores comunes
"Permission denied (publickey)"
- Tu clave publica no esta en
authorized_keysdel servidor - Estas usando la clave privada incorrecta
- Solucion: verifica con
ssh -v usuario@servidorpara ver que clave intenta usar
"WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED"
- El servidor cambio (reinstalado, IP reasignada a otra maquina)
- Solucion:
ssh-keygen -R ip-del-servidor
"Permissions are too open"
- La clave privada tiene permisos 644 o similares
- Solucion:
chmod 600 ~/.ssh/id_ed25519
"Could not resolve hostname"
- El alias en
~/.ssh/configesta mal escrito - No tienes entrada para ese host
"Agent admitted failure to sign"
- El agente SSH no tiene la clave cargada
- Solucion:
ssh-add ~/.ssh/tu_clave
Checklist de seguridad SSH
- Cada contexto (personal, trabajo, CI, agentes IA) tiene su propia clave
- Las claves privadas tienen permisos 600
- El directorio
~/.sshtiene permisos 700 - Las claves sensibles tienen passphrase
- Los agentes de IA solo acceden a claves de scope limitado
- Deploy keys en GitHub son de solo lectura salvo que necesites push
- Tienes backup de claves de infraestructura en un vault
- Rotas claves cuando alguien deja el equipo o una maquina se compromete
- No hay claves privadas en repos, logs ni variables de entorno expuestas
Conclusion
SSH no es complicado una vez entiendes que todo gira alrededor de un concepto: la clave privada firma, la publica verifica.
Lo que si se complica es gestionar multiples claves en multiples contextos, sobre todo ahora que los agentes de IA entran en el flujo de trabajo. La regla de oro: minimo privilegio. Cada clave debe abrir solo las puertas que necesita abrir, y los agentes automatizados deben tener las llaves mas restrictivas de todas.
Lectura adicional
- Por que los archivos .env son peligrosos con agentes IA si quieres entender que pasa cuando tus secretos estan en disco
- Seguridad de agentes IA: guia practica cubre el modelo de amenazas completo para herramientas como Claude Code y Cursor
- 5 errores con secretos en tu servidor para los problemas mas comunes con JWT secrets, credenciales de base de datos y rotacion
- Gestionar secretos con Claude Code para montar un vault que funcione con agentes de IA
- Como evitar que tus secretos acaben en git si todavia no tienes pre-commit hooks configurados
- Criptografia asimetrica: la idea que cambio internet para la teoria detras de como funcionan las claves SSH
- Prueba SecureCode gratis. Secretos zero-knowledge para developers que usan agentes de IA.