BlaiseBlaise
Documentation
Runner and PlugsHow-to guides

Run the agent over SSH

Use any machine you can SSH into as the host for the agent and the plugs after it.

blaise:ssh makes a machine reached over SSH the host for every plug listed after it, and for the agent. The machine outlives the session, so a resume is a reconnect and there is nothing to destroy.

1. Find the machine's host key fingerprint

The plug refuses to talk to a machine whose key it does not know. Read the fingerprint from the machine itself, or from a place you trust:

ssh-keyscan -t ed25519 devbox.example.com 2>/dev/null | ssh-keygen -lf -

Copy the SHA256:… part. Compare it with what the machine prints for ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub when you can.

2. Add the plug

Put ssh before the plugs that should run on the machine:

setup:
  - use: blaise:ssh
    with:
      host: devbox.example.com
      user: dev
      identityFile: ~/.ssh/blaise_ed25519
      hostKey: SHA256:qLq7tG1hQ0yH0m1tTq8F3xQZ0wX0u1y3nV9bR2aKq4s
      workdir: /home/dev/app
  - use: blaise:git/worktree
  - use: blaise:mise

identityFile is a path on the runner's machine. The key is read when the host is first used. workdir is where the agent starts on the machine.

3. Check it

Start a session. The first command that needs the machine connects, so nothing happens until a plug or the agent uses it. A host key that does not match fails with a message that shows both fingerprints.

Things to know

  • Plugs after ssh run their commands on the machine, and so does the agent. Plugs before it still run on the runner.
  • The agent has a watchdog. The machine outlives the session, so the agent is started under a small supervisor that ends it if the SSH session process disappears (for example when the runner crashes). It needs only sh, kill and sleep on the machine.
  • Secrets in the agent's environment are exported by the remote shell just before it starts the agent, so they can be seen in that machine's process list for an instant. Do not put production secrets on machines shared with people you do not trust.
  • Port forwarding works in both directions through ctx.host.forward.
  • The file system is SFTP. The synchronous fs methods work through a worker thread and cost one round trip each; prefer fs.promises.

For all inputs, see Shipped plugs.

On this page