Skip to main content

SSH Access via Proxy

How an LLM agent runs commands on remote machines safely through an SSH-Proxy API instead of raw SSH keys.

Language: EnglishDeutsch

SSH Access via Proxy

Agents need to run commands on remote machines — deploy a container, read a log, fix a config. Handing raw SSH private keys to an LLM is a bad idea: keys end up in context windows, logs and transcripts. An SSH-Proxy solves this: it owns the credentials, the agent only speaks HTTP.

The Model

LLM ──HTTPS──► SSH-Proxy ──SSH──► target machines
                (owns keys,
                 audit log,
                 rate limits)

The proxy exposes persistent sessions with a simple REST surface:

Endpoint Purpose
POST /connect?target=vps1 open a session → session_id
POST /<sid>/exec {command, timeout} run a command (async) → exec_id
GET /<sid>/exec/<exec_id> poll for output
SFTP endpoints file up-/download, ls, mkdir, rm

Auth is a Bearer token — the same pattern as every other API you use.

The Execution Pattern

# 1. connect once, reuse the session for the whole task
SID=$(curl -s -H "Authorization: Bearer $KEY" \
  "https://ssh-proxy.example/connect?target=vps1" | jq -r .session_id)

# 2. run a command
EID=$(curl -s -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -X POST "https://ssh-proxy.example/$SID/exec" \
  -d '{"command": "docker ps --format \"{{.Names}}\"", "timeout": 120}' | jq -r .exec_id)

# 3. poll the result
curl -s -H "Authorization: Bearer $KEY" "https://ssh-proxy.example/$SID/exec/$EID"

Rules of Engagement

  1. Reuse sessions. Connecting per command wastes resources and trips rate limits. Store the session_id (e.g. /tmp/vps1_sid) and heartbeat it before reuse.
  2. Name targets, don't discover them. Targets are pre-registered (vps1, pi, …). The proxy is the single source of truth — never hardcode IP addresses in agent code.
  3. Prefer SFTP over shell cat/heredoc for files. Escaping binary data through exec corrupts payloads. Use the dedicated upload/download endpoints.
  4. Quote your commands. The JSON body is parsed twice (HTTP + shell). Wrap remote commands in single quotes and keep them one-liners.
  5. Assume auditing. Every exec lands in the proxy's audit log — behave as if the human reads everything (they can).

When NOT to use exec

  • Reading structured state that has an API (Docker, databases, the Synapse Mind API) — always prefer the API over parsing CLI output.
  • Long-running interactive processes. exec is fire-and-forget with a timeout; use nohup + a status file on the target instead.
  • Anything destructive without an explicit instruction. The proxy gives you the power — the human gives you the permission.

Error Recovery

Symptom Fix
401 on connect token expired — re-read it from memory/settings, never from a transcript
session 404 session expired (24h cap) — reconnect
exec timeout raise timeout or split the command; check load on the target
garbled file content you used exec instead of SFTP — switch to the SFTP endpoints