Skip to main content
← Back to list
01Issue
FeatureOpenSwamp CLI
AssigneesNone

#304 Add an official @swamp/ssh extension for general-purpose SSH (brownfield-friendly)

Opened by bixu · 5/9/2026

Problem

There is no official general-purpose SSH model in swamp. Existing SSH-capable models in our repo are purpose-built for narrow tasks — e.g. @hivemq/host-kernel-ssh only exposes probeAll (kernel/module probe) and mitigateAlgif (CVE-2026-31431 mitigation). For one-off operational work or for integrating with brownfield fleets (hosts swamp didn't provision and that may use varied auth mechanisms), there is no sanctioned path. Today the choices are:

  1. Hijack an existing command/shell model to wrap ssh — pollutes the original model's data-artifact history with unrelated output, drags the per-model lock + datastore into a one-off path, and bypasses swamp's typed data model.
  2. Build a one-off SSH extension per use-case — N extensions for N use-cases, each duplicating connection/auth handling.
  3. Drop out of swamp and SSH from raw Bash — loses audit trail, vault integration, and the model-data lineage that is the point of swamp.

Concrete example from a 2026-05-09 incident: investigating a backup failure on a Hetzner Robot CI host required ad-hoc df -hT, crontab -l, and log inspection. SSH credentials were in the swamp vault, but no available swamp method fit an arbitrary read-only command. The investigator ended up running ssh from raw Bash to avoid hijacking an unrelated command/shell model.

Proposed solution

An official @swamp/ssh extension that provides general-purpose SSH primitives:

  • exec — run a command on one host (single-host method).
  • execAll — fan-out factory: run a command across many hosts, one data artifact per host (mirrors the probeAll shape that already works well).
  • Optional: copyTo / copyFrom for file transfer (scp-style).

Each method should emit typed data artifacts:

{ host, user, command, exitCode, stdout, stderr, durationMs, executedAt, reachable }

so output wires into reports and CEL expressions like any other swamp model.

Auth support — the brownfield requirement

Brownfield fleets use a mix of auth mechanisms. The extension should support all of:

  • Private key, PEM-bodied (ed25519, ecdsa, rsa, …) — common case, already used by @hivemq/host-kernel-ssh.
  • Password (via sshpass on PATH).
  • SSH agent forwarding (SSH_AUTH_SOCK).
  • Certificate-based auth (signed user certs / IdentityFile + CertificateFile).
  • Jump hosts / ProxyJump / ProxyCommand.
  • Per-host overrides for user, port, identity, known-hosts policy.

globalArguments would carry instance-wide defaults; each method's hosts[] entry overrides per-host.

Brownfield-friendly defaults

  • No assumption that target hosts are swamp-managed.
  • No mutation of remote state outside the explicit command.
  • Tunable connectTimeout, totalTimeout, concurrency (already established by host-kernel-ssh).
  • Configurable StrictHostKeyChecking (default probably accept-new).

Alternatives considered

  • Status quo: per-domain SSH models. Doesn't scale — every new operational concern needs a new extension or a new method on an existing model, and encourages hijacking when it doesn't.
  • command/shell wrapping ssh. The pattern people actually use today, but pollutes the host model's data history, doesn't surface auth as typed config, and produces opaque generic shell output instead of typed SSH-result artifacts.
  • First-class swamp shell CLI for one-off Bash. Would help local one-offs but doesn't address brownfield/multi-host integration where typed model data is the value.

Why this belongs in @swamp/*

SSH is foundational enough that every nontrivial swamp deployment will eventually need it for brownfield integration. Putting it in the official namespace gives it stable typeVersion guarantees and a single canonical place to consolidate auth + connection handling, instead of letting each org reinvent it.

02Bog Flow
OPENTRIAGEDIN PROGRESSSHIPPED

Open

5/9/2026, 8:30:45 AM

No activity in this phase yet.

03Sludge Pulse

Sign in to post a ripple.