La forma segura de darle a un modelo local acceso SSH es no darle nunca una clave. Haz que llame a una herramienta — un servidor MCP que hace de custodio — que guarda las claves (o emite certificados de corta duración), llega solo a los hosts que hayas listado, aplica una lista de comandos permitidos por host, y registra cada uno. Entonces un prompt secuestrado solo puede solicitar una acción a través del custodio; no puede tomar tu identidad ni llegar a un host que no listaste. Lo primero que la gente malentiende: ejecutar el modelo en tu propio hardware protege tus prompts, no tus servidores — «es local, así que es seguro» no es cierto, y no hace nada respecto a lo que pasa cuando ese modelo consigue un shell.
Los modelos locales están de moda. Ollama en una estación de trabajo, un modelo de pesos abiertos detrás de tu propio endpoint, un agente de código autoalojado — los ejecutas por buenas razones: privacidad, coste, sin límites de tasa, funciona en un avión. Y una vez que un modelo ya gestiona tus prompts, el siguiente paso obvio es apuntarlo a tu infraestructura: que siga un registro, reinicie un servicio, ejecute la migración — y ahí es donde cae la verdadera pregunta.
Por qué «local» no hace seguro el acceso al servidor
Dos cosas siguen siendo exactamente igual de peligrosas tanto si el modelo corre en un centro de datos como en la máquina de debajo de tu escritorio.
La clave sigue siendo una credencial al portador. Suelta id_ed25519 en el entorno del agente para que pueda ejecutar ssh por su cuenta, y quienquiera — o lo que sea — que tenga esos bytes eres tú, en todos los hosts que confían en la clave. Ejecutar el modelo en local no cambia eso; solo mueve la copia a una máquina que resulta ser tuya. Y sigues sin poder recuperarla: una vez que la clave ha pasado por el contexto del modelo — una variable de entorno, un archivo montado, una llamada a una herramienta, una transcripción — ya no puedes demostrar que no acabó en algún sitio donde no debía. La única respuesta honesta a «¿vio el modelo mi clave?» es rotarla en todos los hosts.
Un modelo local también se confunde. La inyección de prompts no necesita un modelo en la nube. Una línea de registro envenenada, un nombre de archivo malicioso, un resultado de herramienta con trampa, un plan demasiado entusiasta — un modelo local actúa sobre todos ellos con la misma facilidad que uno alojado. Si acaso el riesgo es peor, porque la gente confía más en las configuraciones locales, las monta con menos salvaguardas, y les concede un acceso más amplio, precisamente porque «está en mi máquina». Ese es el instinto equivocado: el juicio del modelo no es mejor porque los pesos sean locales.
Así que el objetivo es el mismo que para cualquier agente — dejar que el modelo haga el trabajo sin tener nunca la credencial, y hacer que cada acción sea acotada, visible y reversible.
Tres formas de hacerlo mal
Pegar la clave en crudo. La vía directa, y la peor: sin alcance, sin caducidad, y con la irreversibilidad de arriba. La clave que despliega en staging normalmente también puede llegar a la base de datos de producción a dos saltos de distancia.
Emitir un token de larga duración. Un token de despliegue o una credencial de «automatización» que no caduca nunca. Parece más ordenado que una clave, pero es el mismo problema de credencial al portador con pasos de más. Si revocar algo implica acordarse de que existe, sobrevivirá al experimento que lo creó.
Darle su propio acceso root y desentenderse. El instinto correcto — una identidad aparte — hecho de la forma equivocada. Suelta una clave pública en el authorized_keys de un usuario bot y has construido un acceso sin rastro de auditoría: nada distingue los comandos del modelo de los de nadie más, y cuando algo se rompe a las 2 de la madrugada estás reconstruyendo su sesión a partir del historial de bash y la intuición.
El hilo común: el modelo tiene una credencial permanente, y la observabilidad es una ocurrencia tardía.
El patrón que funciona: un custodio, no una copia
Dale la vuelta. El modelo no debería tener la credencial en ningún momento.
- El modelo pide; un custodio firma. Un intermediario guarda las claves (o emite certificados de corta duración) y se autentica en nombre del modelo. Compromete el contexto del modelo y obtienes la capacidad de solicitar acciones a través del intermediario — no la capacidad de suplantarte desde cualquier parte.
- El alcance es explícito. El modelo llega solo a los hosts que hayas listado. Un host nuevo es una decisión nueva, no algo por defecto.
- Los comandos están vigilados. Por host, decides si el modelo obtiene una shell completa, una lista de comandos permitidos, o nada — de modo que «reiniciar nginx» esté permitido en la capa web y «cualquier cosa» no lo esté nunca.
- Una persona puede observar — en vivo. No solo en el análisis posterior, y con el registro distinguiendo «esto lo hizo el modelo» de «esto lo hice yo».
- Revocar es un interruptor, no una rotación. Como nunca se compartió nada, apagar el acceso no cuesta nada.
Nada de esto es exótico — es más o menos como ya funciona el SSH basado en certificados en los equipos de infraestructura serios. La pega siempre ha sido que cablearlo tú mismo es un proyecto, así que la gente salta a una de las malas opciones de arriba.
Cómo conectarlo a un modelo local
MCP — el Model Context Protocol — es la forma limpia de hacerlo, y es agnóstico del cliente: cualquier cliente con soporte de MCP puede manejarlo, así que da igual si tu modelo es Claude, un modelo de pesos abiertos detrás de Ollama, o algo que alojas tú mismo.
- Ejecuta tu modelo local a través de un cliente con soporte de MCP (un agente de código o un cliente de chat que hable MCP).
- Apúntalo a un servidor MCP que haga de frente para SSH — uno que se autentique por el modelo en lugar de entregarle una clave.
- Activa solo los hosts que quieras, y fija la política de comandos de cada host (completa / lista de permitidos / bloqueado).
- Mantén la sesión a la vista y deja que escriba en un registro de auditoría, para que cada comando que el modelo ejecuta sea atribuible y reproducible.
El modelo obtiene herramientas — abrir una sesión, ejecutar un comando, leer o escribir un archivo — y el custodio se encarga de la autenticación. Tu clave nunca entra en el entorno del modelo, ni en tu máquina ni en ninguna otra parte. Y como es el custodio quien tiene la credencial y no el modelo, el mismo montaje se traslada en cuanto echas mano de un agente alojado — Claude Code por SSH y OpenAI Codex por SSH ofrecen este patrón idéntico con un modelo en la nube al otro lado.
Cómo lo hace Termalin
Termalin es un cliente SSH con un servidor MCP integrado, así que este patrón es lo que hay por defecto en lugar de un proyecto.
- En tu máquina, registra el servidor local incluido con tu agente (
claude mcp add termalin -- <path>/termalin-mcp, o el equivalente para cualquier cliente MCP). El modelo llega solo a los hosts que actives — el acceso de agentes está desactivado por defecto — y la autenticación pasa por el custodio de claves de Termalin: desbloqueas tus claves una vez, Termalin firma en nombre del modelo, y nunca hay ningún archivo de clave que el modelo pueda leer. - Por host, fijas la política — acceso completo, una lista de comandos permitidos, o bloqueado — para que un modelo local que se confunde no pueda ejecutar algo que nunca autorizaste en esa máquina.
- Lo ves suceder. Las sesiones del agente corren como pestañas de terminal en vivo; el watch grid las refleja, y los mosaicos que un modelo conduce brillan. Cada comando queda marcado en la grabación de sesión — solo la salida, nunca tus pulsaciones — y escrito en un registro de auditoría con el dispositivo y la IP de los que vino.
- ¿Sin la app abierta? Apunta el modelo al endpoint MCP alojado de Termalin con una clave API acotada a servidores concretos, con una caducidad, con política de comandos, y que autentica cada ejecución con un certificado de corta duración — de modo que ni siquiera una clave filtrada puede llegar a un host no listado ni ejecutar fuera de sus comandos permitidos.
En cualquier caso, se mantiene la propiedad que querías: tu modelo local puede operar tus servidores, y nunca ha visto una clave.
Empieza con un host aburrido
No empieces por producción. Da de alta una máquina de bajo riesgo — un servidor de staging, un VPS de juguete — ponla en una lista de permitidos, y dale al modelo una tarea de verdad: sigue el registro hasta que aparezca el error, arregla la configuración, reinicia el servicio. Mantén el grid abierto mientras trabaja. Lo que aprendes en la primera hora — cómo se comporta, dónde duda, qué hace con la ambigüedad — te dice si el segundo host se da de alta, y con cuánta cuerda.
Esa es la recompensa silenciosa del modelo de custodio: amplías de un host en uno, porque ningún paso que das es uno que no puedas deshacer — sin importar dónde esté corriendo el modelo.
Termalin es un cliente SSH gratuito y multiplataforma con un servidor MCP integrado, un custodio de claves y política de agente por host — descárgalo, o lee cómo gestiona las claves con seguridad.