Skip to main content

Ssh

@swamp/sshv2026.06.03.1· 1d agoMODELS
01README

Run commands, copy files, and open port forwards across a declared set of hosts over SSH. Define the hosts once on the model, then target any subset by host name or tag (controlplane), an explicit name list, a CEL expression ('cel:"prod" in host.tags'), or all. Every host runs in parallel and records its own result resource, so individual outcomes are auditable and workflows can gate on them.

OpenSSH targets reuse long-lived connections via ControlMaster; Tailscale SSH targets authenticate with tailnet identity and bypass multiplexing. Hosts can mix both transports in one fleet, and each host can override the fleet defaults (user, port, identity, proxy jump, auth mode, and more).

Highlights

  • Define your fleet once via globalArguments.hosts[] — each host can override the fleet-default transport (kind, user, port, identity, etc.).
  • Mix OpenSSH and Tailscale hosts in the same fleet.
  • Per-host operations land as one resource each — run-<method>-<name> — so you can diff, gate workflows, and audit individual hosts.
  • Selector forms: "all", an explicit name list ["web-1"], a bare host name or tag (controlplane), name:/tag:/cel: prefixes, or a cel: predicate (e.g. 'cel:"prod" in host.tags'). A bare CEL string is deprecated — prefix it with cel:.
  • CEL helpers bundled on every call: matchesRegex(s, pat), cidrContains(cidr, addr).
  • Auth modes: key-based (file, agent, IdentityAgent, inline content via identityContent) and password-based via sshpass -e with the password supplied through ${{ vault.get('<vault>', '<key>') }}.

Methods

Method What it does
apply Materialise the host list as host-* resources; deletes stale entries that disappeared from hosts[].
open Establish ControlMaster sockets for selected ssh hosts (no-op for tailscale).
check Probe ControlMaster (ssh -O check) or run true over tailscale ssh.
close Tear down ControlMaster sockets (ssh -O exit).
exec Run a single shell command on each selected host; optional sudo: true prefixes sudo -n --.
script Pipe a multi-line script over stdin to sh -s -- (or chosen interpreter) — no remote-side shell-quoting from us.
copy scp (or rsync -e ssh) files to/from each selected host.
forward Local/remote port forwarding via the master, or detached tailscale ssh -N -L child for tailscale hosts.

Output capture

Captured by default, opt out at the fleet (captureOutput: false) or per call. No cap — stdout/stderr land verbatim in the matching run-<method>-<host> resource.

Requirements

  • OpenSSH client (ssh, scp) on the runner.
  • rsync if any copy call sets useRsync: true.
  • tailscale if any host uses the tailscale transport.
  • sshpass if any host uses auth.kind: password.
  • The swamp host must expose ctx.createCelEnvironment() on the extension model context (introduced 2026-05).

Usage

swamp extension pull @swamp/ssh

# Create the fleet, then author its globalArguments (transport + hosts).
swamp model create @swamp/ssh awesome
swamp model edit awesome

# Run methods — every selector-taking method requires a `hosts` argument.
swamp model method run awesome open --input hosts=all --json
swamp model method run awesome exec \
  --input hosts='tag:prod' \
  --input command='uptime' --json

See the bundled README for the full configuration shape, transport options, authentication modes, and worked examples.

02Models1
@swamp/sshv2026.06.03.1ssh.ts
fn apply()
Materialize the host list as host-* resources and prune stale ones.
fn open()
Establish ControlMaster sockets for selected ssh hosts (no-op for tailscale).
fn check()
Probe connectivity: ssh -O check for ssh hosts, `true` over tailscale ssh.
fn close()
Tear down ControlMaster sockets (ssh -O exit).
fn exec()
Run a single shell command on each selected host.
fn script()
Pipe a multi-line script over stdin to sh/bash/python3 on each host.
fn copy()
scp (or rsync) files to/from each selected host.
fn forward()
Open/cancel/list a port forward (ssh -O forward, or detached tailscale child).

Resources

host(infinite)— One record per fleet member, written by `apply`. Tagged with the
runResult(infinite)— Per-host outcome of a single method invocation (exec/script/copy).
forwardState(infinite)— Tracks an open port forward — pid for tailscale, ControlPath for ssh.
masterAudit(infinite)— ControlMaster open/check/exit events, per host.
03Previous Versions6
2026.06.01.2Jun 1, 2026
2026.06.01.1Jun 1, 2026
2026.05.29.2May 29, 2026
2026.05.29.1May 29, 2026
2026.05.25.1May 25, 2026
2026.05.19.1May 20, 2026
04Stats
A
100 / 100
Downloads
43
Archive size
57.3 KB
Verified by Swamp
  • Has README or module doc2/2earned
  • README has a code example1/1earned
  • README is substantive1/1earned
  • Most symbols documented1/1earned
  • No slow types1/1earned
  • Dependencies pass trust audit2/2earned
  • Has description1/1earned
  • Platform support declared (or universal)2/2earned
  • License declared1/1earned
  • Verified public repository2/2earned
05Platforms
06Labels