OPENSSH EXTENSIONS
Every Swamp extension that covers OpenSSH, as published in the registry. Install
any of them with swamp extension pull.
Extensions
| Extension | Version | License | Contents |
|---|---|---|---|
| @swamp/ssh | 2026.10.13.1 | - | 1 behavior types |
| @keeb/ssh | 2026.07.18.1 | - | 1 behavior types |
| @hivemq/ssh/authorized-keys | 2026.08.27.1787839816 | - | 1 behavior types |
| @hivemq/hetzner/ssh/authorized-keys | 2026.08.27.1787839802 | - | 1 behavior types |
| @hivemq/ssh/keygen | 2026.09.11.1789122871 | - | 1 behavior types |
| @hivemq/ssh/rotate-config | 2026.08.27.1787839821 | - | 1 behavior types |
| @evrardjp/ssh-ca | 2026.07.17.1 | - | 1 behavior types, 1 reports |
@swamp/ssh
swamp extension pull @swamp/sshBehavior type @swamp/ssh
Global arguments, set with --global-arg on swamp behavior create:
| Name | Type | Required | Description |
|---|---|---|---|
name |
string | yes | - |
transport |
object {kind: "ssh", user?: string, port: integer, auth: object {kind: "key"} | object {kind: "password", password: string}, identityFile?: string, identityContent?: string, identityAgent?: string, identitiesOnly?: boolean, knownHostsFile?: string, strictHostKeyChecking?: "yes" | "accept-new" | "no" | "off", connectTimeoutSec: integer, serverAliveIntervalSec?: integer, proxyJump?: string, proxyCommand?: string, extraOptions: array of string, controlMaster: object {enabled: boolean, persistSec: integer}} | object {kind: "tailscale", user?: string, tailscaleBinary?: string, sshExtraArgs: array of string} | yes | - |
hosts |
array of object {name: string, address: string, tags: array of string, attrs: object, transport?: object {kind?: "ssh" | "tailscale", user?: string, port?: integer, auth?: object | object, identityFile?: string, identityContent?: string, identityAgent?: string, identitiesOnly?: boolean, knownHostsFile?: string, strictHostKeyChecking?: "yes" | "accept-new" | "no" | "off", connectTimeoutSec?: integer, serverAliveIntervalSec?: integer, proxyJump?: string, proxyCommand?: string, extraOptions?: array, controlMaster?: object, tailscaleBinary?: string, sshExtraArgs?: array}, env?: object} | yes | - |
defaultParallel |
integer | no | - |
defaultTimeoutSec |
integer | no | - |
failFast |
boolean | no | - |
captureOutput |
boolean | no | - |
runHistory |
integer | no | - |
sshBinary |
string | no | - |
scpBinary |
string | no | - |
rsyncBinary |
string | no | - |
tailscaleBinary |
string | no | - |
sshpassBinary |
string | no | - |
Methods, run with swamp behavior run:
| Method | Description | Arguments |
|---|---|---|
apply |
Materialize the host list as host-* resources and prune stale ones. | - |
resolve |
Resolve a host selector to the matching fleet members without connecting — zero matches is data, not an error. | hosts |
open |
Establish ControlMaster sockets for selected ssh hosts (no-op for tailscale). | hosts, parallel (optional), timeoutSec (optional), failFast (optional), env (optional), captureOutput (optional) |
check |
Probe connectivity: ssh -O check for ssh hosts, true over tailscale ssh. |
hosts, parallel (optional), timeoutSec (optional), failFast (optional), env (optional), captureOutput (optional) |
close |
Tear down ControlMaster sockets (ssh -O exit). | hosts, parallel (optional), timeoutSec (optional), failFast (optional), env (optional), captureOutput (optional) |
exec |
Run a single shell command on each selected host. | hosts, parallel (optional), timeoutSec (optional), failFast (optional), env (optional), captureOutput (optional), command, stdin (optional), sudo (optional), okExitCodes (optional) |
script |
Pipe a multi-line script over stdin to sh/bash/python3 on each host. | hosts, parallel (optional), timeoutSec (optional), failFast (optional), env (optional), captureOutput (optional), script, interpreter (optional), sudo (optional), okExitCodes (optional) |
copy |
scp (or rsync) files to/from each selected host. | hosts, parallel (optional), timeoutSec (optional), failFast (optional), env (optional), captureOutput (optional), src, dst, direction, recursive (optional), useRsync (optional) |
forward |
Open/cancel/list a port forward (ssh -O forward, or detached tailscale child). | hosts, parallel (optional), timeoutSec (optional), failFast (optional), env (optional), captureOutput (optional), action, spec (optional), type (optional) |
collect-host-public-key |
Read and validate a remote host's SSH public key file. Emits a hostPublicKey resource with the raw key, algorithm, and SHA256 fingerprint. Defaults to /etc/ssh/ssh_host_ed25519_key.pub. | hosts, parallel (optional), timeoutSec (optional), failFast (optional), env (optional), captureOutput (optional), hostKeyPath (optional) |
Data written:
| Resource | Description |
|---|---|
host |
One record per fleet member, written by apply. Tagged with the fleet name so workflow CEL can select via data.findByTag. |
runResult |
Per-host outcome of a single method invocation (exec/script/copy). Captured stdout/stderr land here verbatim when capture is on. Tagged with fleet, host, method, and exitCode (omitted when the process was killed by a signal or failed to spawn). |
forwardState |
Tracks an open port forward — pid for tailscale, ControlPath for ssh. |
masterAudit |
ControlMaster open/check/exit events, per host. |
hostPublicKey |
Observed SSH host public key. One per host, written by collect-host-public-key. Contains the raw public key line, parsed algorithm, and SHA256 fingerprint. |
selection |
Result of a resolve call: the selector, its matched fleet members (addressing + tags/attrs only, never credentials), and the match count. Instance resolve-<hash> is stable per selector; zero matches writes an empty list rather than failing. Tagged with fleet, method, and count. |
@keeb/ssh
swamp extension pull @keeb/sshBehavior type @keeb/ssh/host
Global arguments, set with --global-arg on swamp behavior create:
| Name | Type | Required | Description |
|---|---|---|---|
host |
string | yes | SSH hostname or IP |
user |
string | no | SSH user |
via |
"key" | "tailscale" | "bastion" | "proxy-command" | no | Transport style for the SSH connection |
bastion |
string | no | user@host of the jump host (required when via=bastion) |
proxyCommand |
string | no | Command piped into ssh via -o ProxyCommand (required when via=proxy-command) |
Methods, run with swamp behavior run:
| Method | Description | Arguments |
|---|---|---|
exec |
Run a command over SSH and return stdout/stderr/exitCode | command, timeout (optional) |
upload |
Upload a file to a remote host via scp (or piped cat on tailscale) | source, dest |
waitForConnection |
Poll SSH until the host is reachable | timeout (optional) |
Data written:
| Resource | Description |
|---|---|
result |
SSH operation result |
@hivemq/ssh/authorized-keys
swamp extension pull @hivemq/ssh/authorized-keysBehavior type @hivemq/ssh/authorized-keys
Global arguments, set with --global-arg on swamp behavior create:
| Name | Type | Required | Description |
|---|---|---|---|
privateKey |
string | no | Default PEM private key body for SSH auth. Used for any host that does not declare its own privateKey. May be omitted entirely if every host carries its own key. |
defaultUser |
string | no | - |
connectTimeoutSeconds |
number | no | - |
totalTimeoutSeconds |
number | no | - |
concurrency |
integer | no | - |
searchPaths |
array of string | no | Filesystem roots to scan for authorized_keys files. |
hosts |
array of object {name: string, address: string, user?: string, privateKey?: string, hostKeyFingerprint?: string} | yes | - |
keys |
array of object {name: string, publicKey: string, state: "present" | "absent", notes?: string} | yes | Declarative list of SSH pubkeys to manage on every host. |
Methods, run with swamp behavior run:
| Method | Description | Arguments |
|---|---|---|
audit |
Read every authorized_keys file under searchPaths on every host. Read-only. | filter (optional), privateKey (optional) |
verify |
Check each managed key's state on every host. state=present keys must appear in every authorized_keys; state=absent keys must appear nowhere. |
filter (optional), privateKey (optional) |
add |
Append every state=present managed key to every authorized_keys file. Idempotent (matches on algo+body, ignores comment). |
filter (optional), privateKey (optional) |
seal |
Overwrite every authorized_keys file under searchPaths with ONLY the state: present managed keys. Destructive: orphan keys are wiped. Idempotent: skips files already matching the desired content. Run only after all consumers are confirmed to be using a managed key. |
filter (optional), privateKey (optional) |
exec |
Run a one-shot diagnostic shell command on each host. Persists per-host stdout/stderr/exitCode as execResult resource. Read-only by convention (caller's command may mutate). Warning: useSudo: true provides arbitrary root shell execution on every host in scope -- restrict method-run access accordingly. |
command, filter (optional), useSudo (optional), privateKey (optional) |
strip |
Remove every state: absent managed key from every authorized_keys file under searchPaths. Matches on algo+body (ignores comment). Preserves file ownership and mode via atomic mv -T on a sibling temp file. |
filter (optional), privateKey (optional) |
Data written:
| Resource | Description |
|---|---|
audit |
Per-host audit of every authorized_keys file under searchPaths (forensic listing). |
verify |
Per-host compliance result against the managed keys list. |
addResult |
Per-host result of the add operation. |
sealResult |
Per-host result of the seal operation. |
execResult |
Per-host result of the exec diagnostic operation. |
stripResult |
Per-host result of the strip operation. |
@hivemq/hetzner/ssh/authorized-keys
swamp extension pull @hivemq/hetzner/ssh/authorized-keysBehavior type @hivemq/hetzner/ssh/authorized-keys
Global arguments, set with --global-arg on swamp behavior create:
| Name | Type | Required | Description |
|---|---|---|---|
privateKey |
string | no | PEM private key body for SSH auth. Set either this or password. |
password |
string | no | Password for SSH auth (requires sshpass on the runtime). Set either this or privateKey. |
defaultUser |
string | no | - |
connectTimeoutSeconds |
number | no | - |
totalTimeoutSeconds |
number | no | - |
concurrency |
number | no | - |
searchPaths |
array of string | no | Filesystem roots to scan for authorized_keys files. |
hosts |
array of object {name: string, address: string, user?: string, privateKey?: string, password?: string} | yes | - |
keys |
array of object {name: string, publicKey: string, state: "present" | "absent", notes?: string} | yes | - |
Methods, run with swamp behavior run:
| Method | Description | Arguments |
|---|---|---|
audit |
Read every authorized_keys file under searchPaths on every host. Read-only. | filter (optional) |
verify |
Read-only conformance check: state=present keys must be in every file; state=absent keys must appear nowhere. | filter (optional) |
Data written:
| Resource | Description |
|---|---|
audit |
Per-host audit of every authorized_keys file under searchPaths (forensic listing). |
verify |
Per-host compliance against the declared keys set (read-only assertion). |
@hivemq/ssh/keygen
swamp extension pull @hivemq/ssh/keygenBehavior type @hivemq/ssh/keygen
Global arguments, set with --global-arg on swamp behavior create:
| Name | Type | Required | Description |
|---|---|---|---|
vaultName |
string | no | Swamp vault name where the private key will be stored. |
secretName |
string | yes | Vault key name to write (e.g. MY_SSH_KEY). UPPER_SNAKE_CASE. |
comment |
string | no | ssh-keygen -C comment. Empty by default; pass something like hetzner-cicd-dev to make the pubkey self-describing. |
Methods, run with swamp behavior run:
| Method | Description | Arguments |
|---|---|---|
generate |
Generate a fresh ed25519 keypair, store the private key in the Swamp vault, return the public key as a resource. Overwrites the existing vault entry if present. | - |
Data written:
| Resource | Description |
|---|---|
pubkey |
Most recently generated public key + fingerprint. The matching private key lives in the Swamp vault at globalArguments.secretName. |
@hivemq/ssh/rotate-config
swamp extension pull @hivemq/ssh/rotate-configBehavior type @hivemq/ssh/rotate-config
Global arguments, set with --global-arg on swamp behavior create:
| Name | Type | Required | Description |
|---|---|---|---|
vaultName |
string | no | Swamp vault name where both keys are stored. |
legacyKey |
string | yes | Vault key name of the bootstrap credential (e.g. MY_SSH_KEY_LEGACY). |
newKey |
string | yes | Vault key name where the freshly generated key will live (e.g. MY_SSH_KEY). |
Methods, run with swamp behavior run:
| Method | Description | Arguments |
|---|---|---|
describe |
Write the instance config as a config data record. Idempotent. Run once when the instance changes; downstream workflow steps then read via data.latest(). |
- |
Data written:
| Resource | Description |
|---|---|
config |
Snapshot of the instance's globalArgs. Workflows reference its fields via data.latest(name, "config").attributes.{legacyKey,newKey,vaultName}. |
@evrardjp/ssh-ca
swamp extension pull @evrardjp/ssh-caBehavior type @evrardjp/ssh-ca
Global arguments, set with --global-arg on swamp behavior create:
| Name | Type | Required | Description |
|---|---|---|---|
caName |
string | yes | Logical OpenSSH CA name |
vaultName |
string | yes | Swamp vault for private keys, passphrases, and optional certificates |
bits |
number | no | ssh-keygen -b bits; useful for rsa and ecdsa |
comment |
string | no | ssh-keygen -C comment; defaults to caName |
metadataLabels |
record | yes | - |
sshKeygenBinary |
string | yes | - |
Methods, run with swamp behavior run:
| Method | Description | Arguments |
|---|
Data written:
| Resource | Description |
|---|---|
ca |
OpenSSH CA public metadata; private key and passphrase are vault references |
certificate |
Issued OpenSSH host/user certificate and issuance metadata |
certificateauthority |
OpenSSH known_hosts @cert-authority line for this CA |
trustedusercakeys |
OpenSSH TrustedUserCAKeys material for this CA |
revocation |
OpenSSH certificate/key revocation event including generated KRL |
keyrevocationlist |
OpenSSH binary Key Revocation List (KRL), base64 encoded |
casummary |
Summary of this CA, active certificates, and OpenSSH configuration snippets |
Reports in @evrardjp/ssh-ca
| Report | Description |
|---|---|
@evrardjp/ssh-ca-inventory |
Inventory OpenSSH CA models, certificates, KRLs, and SSH config snippets |