SSH Testing
Test the :ssh step locally (mock mode), and against a real VM/VPS (real SSH).
If you still need to set up the VPS/VM, SSH user, key material, and Breyta connection from scratch, start with Set Up A VPS Or VM For Breyta SSH.
Local (Mock) — Sync SSH
Use this only for short command validation. For long-running agent workloads, test the async
pattern in this guide (ssh-async-callback) instead of a single sync :ssh step.
1) Start a local flows-api with demo flows
From breyta/:
./scripts/start-flows-api.sh --profile=memory --seed --demos
This starts:
- API:
http://localhost:8090 - nREPL:
localhost:7889 - Demo flows are seeded into workspace
ws-acme
The breyta commands below assume your local CLI defaults are already pointing at that local dev API and workspace, so the commands omit explicit --api, --workspace, and --token flags.
2) Create a mock SSH connection
breyta --dev \
connections create \
--type ssh --backend ssh --name "Mock VPS (SSH)" \
--config '{"host":"example.com","port":22,"username":"ubuntu","mode":"mock"}'
Copy the returned connection-id.
3) Configure the demo flow and run it
Bind the SSH connection to the flow’s :vps slot:
breyta --dev \
flows configure ssh-exec --set vps.conn=<CONN_ID>
Run and wait:
breyta --dev \
flows run ssh-exec --wait \
--input '{"command":"echo hi"}'
Expected: a completed run whose step result includes stdout starting with MOCK SSH.
Local (Mock) — Async Agent Callback Pattern
This uses the demo flow ssh-async-callback, which:
- kicks off an “agent/job” via
:ssh(quick) - pauses via
:wait - resumes when something POSTs JSON to the callback URL
1) Configure the demo flow
breyta --dev \
flows configure ssh-async-callback --set vps.conn=<CONN_ID>
2) Start the run (don’t wait yet)
breyta --dev \
flows run ssh-async-callback \
--input '{"command":"echo started"}'
Copy the returned workflowId (looks like flow-ssh-async-callback-ws-acme-r1).
3) Compute the wait key and POST the callback
In this demo flow, the wait key is deterministic:
wait-key = "agent-" + workflowId
Example callback:
curl -X POST \
"http://localhost:8090/ws-acme/events/agent-<WORKFLOW_ID>" \
-H 'content-type: application/json' \
-d '{"status":"ok","result":{"answer":42}}'
4) Confirm the run completes
breyta --dev \
runs show <WORKFLOW_ID>
Expected: status completed and result.callback.result.answer == 42.
Real SSH — Connect To A VM/VPS
For production-like long jobs, validate with the async kickoff + callback flow pattern.
Do not rely on a single sync :ssh step to prove long-duration reliability.
To connect to a real host, you need:
host(DNS or IP)port(usually22)username(Linux user)- auth: private key (recommended) or password
- host key verification:
known_hosts(recommended)
1) Create known_hosts for the target host
mkdir -p ./tmp
ssh-keyscan -H -p 22 <HOST> > ./tmp/ssh-known-hosts
2) Store secrets in the workspace secret-store (via flow configuration)
The seeded demo flows declare optional secret slots that store secrets under these refs:
ssh-private-keyssh-known-hostsssh-key-passphrase(optional)
Bind secret values using --set ...=@file for multiline content. Use @/absolute/path or @./relative/path; do not use @~/.ssh/..., because shells do not expand ~ reliably in that form:
breyta --dev \
flows configure ssh-exec \
--set ssh-private-key.secret=@$HOME/.ssh/id_ed25519 \
--set ssh-known-hosts.secret=@./tmp/ssh-known-hosts
Use the same key file here that already works in a direct manual SSH check. Do not assume your local SSH agent and Breyta are using the same key automatically.
If your key is encrypted:
breyta --dev \
flows configure ssh-exec \
--set ssh-key-passphrase.secret=@./tmp/ssh-passphrase.txt
3) Create a real SSH connection that references those secret refs
breyta --dev \
connections create \
--type ssh --backend ssh --name "My VPS (SSH)" \
--config '{
"host":"<HOST>",
"port":22,
"username":"<USER>",
"auth":{"type":"private-key","secret-ref":"ssh-private-key","passphrase-secret-ref":"ssh-key-passphrase"},
"known-hosts":{"secret-ref":"ssh-known-hosts"}
}'
4) Bind the real connection and run
breyta --dev \
flows configure ssh-exec --set vps.conn=<REAL_CONN_ID>
breyta --dev \
flows run ssh-exec --wait \
--input '{"command":"uname -a"}'