Most databases worth backing up are not listening on the public internet. sloop reaches one through an SSH server you can already log into: it opens a forward, binds a local port, and hands that port to pg_dump or mysqldump, which never learn that SSH was involved.
Registering one
The SSH settings live on the record, beside the connection, so you give them once and every command after that just takes the name:
$ sloop db add remote --url postgres://app@127.0.0.1:5432/orders \$ --ssh-host bastion.example.com --ssh-user deployregistered remote in the project registry (the nearest .sloop at or above the working directory), password from the OS keyring postgres://app@127.0.0.1:5432/orders through ssh://deploy@bastion.example.com:22 over deploy@bastion.example.com, from the agent 127.0.0.1:5432 is as bastion.example.com sees it, not as this machine does$ sloop db listremote postgres://app@127.0.0.1:5432/orders project · the OS keyring over deploy@bastion.example.com, from the agent--ssh-user falls back to ~/.ssh/config and then to your own username. --ssh-port is 22 when left out. --ssh-identity takes a particular private key exactly as ssh -i does — and when you leave it out, the agent and ~/.ssh/config decide, which is the documented default. sloop never reads your key file and never copies it.
Where the key's passphrase comes from
The same four routes a database password takes, with the same flags wearing an --ssh- prefix: --ssh-keyring, --ssh-encrypted-file, --ssh-env <VARIABLE> and --ssh-passphrase-from <COMMAND>, plus --ssh-passphrase-stdin for storing one with no terminal.
$ sloop db add keyed --url postgres://app@127.0.0.1:5432/orders \$ --ssh-host bastion.example.com --ssh-user deploy \$ --ssh-identity ~/.ssh/id_ed25519 \$ --ssh-passphrase-from "op read op://vault/ssh/passphrase"note: the password command exited with 1: op read op://vault/ssh/passphrase — registered anyway, because the command is read on every run rather than kept hereregistered keyed in the project registry, password from the OS keyring postgres://app@127.0.0.1:5432/orders through ssh://deploy@bastion.example.com:22#C:/Users/you/.ssh/id_ed25519 over deploy@bastion.example.com, unlocked from the command `op read op://vault/ssh/passphrase`A registry holds the route and never the passphrase, which is exactly the rule database passwords follow. And the note is the point rather than a problem: a command that is not installed yet is fine at registration time, because it is run when it is needed rather than now.
$ sloop db edit remote --no-sshchanged remote in the project registry postgres://app@127.0.0.1:5432/orders through ssh://deploy@bastion.example.com:22 postgres://app@127.0.0.1:5432/orders--no-ssh takes the forward off and the connection becomes a direct one.
One forward per session, not per command
sloop opens one long-lived forward per remote server — the first time something needs it — and closes it when sloop exits. Ten operations against one server in one menu session authenticate once. A tool that made you touch a hardware key before every single command would be a tool people stop using.
Why sloop runs your ssh rather than embedding one
This is a deliberate decision and it is the same one sloop makes about curl. Four reasons, and the first is the product:
$ sh ci/no-http-client.shno-http-client: 269 crates in the graph, not one of them opens a socket. A claim that holds only because the check is narrow is not worth making. That is why the check is not narrow — and why the honest way to reach a closed-off database is to run the ssh you already trust.
When it fails, it fails in OpenSSH's words
Which is the best evidence there is for everything above. Here the bastion does not exist:
$ sloop db test remote remote postgres://app@127.0.0.1:5432/orders through ssh://deploy@bastion.example.com:22 project✗ ssh could not reach deploy@bastion.example.com hint: ssh: Could not resolve hostname bastion.example.com: Name or service not knownssh: Could not resolve hostname … is not sloop's sentence. It is the message your own OpenSSH printed, handed straight back to you — so a wrong key, a rejected host, an expired certificate or a ProxyJump that failed all arrive as the message you would have seen typing ssh yourself, and you fix them the way you already know how.
Every --ssh- flag is on the command reference, generated from --help.