Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

FAQ & troubleshooting

Why doesn’t sshelf just use my SSH config?

By design. ~/.ssh/config is often shared, load-bearing infrastructure (Ansible, Terraform, and your editor’s remote mode all read it), and a tool that rewrites it can corrupt all of that. sshelf keeps an independent database and builds ssh commands from it with plain flags; its only contact with your SSH config is the explicit, read-only import. (ssh itself still reads your config normally when sshelf launches it; sshelf just never writes it.) It isn’t a one-way street either: sshelf export generates an Include file so plain ssh/scp, and anything that reads SSH config like VS Code Remote, can use your sshelf hosts by name.

What does sshelf need at runtime?

OpenSSH 8.4+ on your machine. Password and passphrase auto-supply ride on SSH_ASKPASS_REQUIRE, added in OpenSSH 8.4 (2020). Key/agent hosts work with anything reasonably modern. Platforms: macOS + Linux, x86_64 and arm64.

Run sshelf doctor. It reads your version and says whether it’s enough.

Does sshelf phone home?

No. No telemetry, no account, no network calls of its own. The only network activity is the ssh/sftp it runs for you. See Security.

Then how does the Tailscale import work?

The same way: by running a program you already have. sshelf import --tailscale executes your tailscale CLI (tailscale status --json) and parses its output. sshelf opens no sockets, holds no API key, and talks to no Tailscale server. It only ever runs when you type that command: never at startup, on a save, on a timer, or from the TUI. Nothing tailscale-specific (node IDs, keys) is written to hosts.toml, and the import only ever adds hosts.

Password auto-supply isn’t working

  • Built from source on macOS? An unsigned binary can hit a Keychain approval prompt on every connect (Keychain ACLs are keyed to the code signature). Approve it, or ad-hoc sign your build: codesign -s - target/release/sshelf.

Start with sshelf doctor: it checks the OpenSSH version and round-trips your secret backend, which covers both of the usual causes.

I’m on a headless box with no keyring

Set SSHELF_VAULT_PASSPHRASE and secrets then live in an age-encrypted vault file instead of a keyring. Details: where secrets live; the env-inheritance tradeoff is documented in Security.

sshelf doctor confirms which backend it’s actually using and whether it opens.

Can a jump host use password auth?

Not currently; jump hosts are key/agent only. The askpass helper holds the target’s secret and can’t tell which hop in a chain is prompting. If a jump-host connection fails, check your agent is reachable: sshelf doctor.

Can I open connections in tmux windows instead of leaving the picker?

Yes. Set tmux = "window" (or "pane") in config.toml, or cycle the field on the F2 settings screen. When sshelf is running inside tmux, Enter then opens the host in a new window named after it and keeps the picker up, so you can fire off several in a row. Outside tmux the setting does nothing.

Why did my 2FA host not open a tmux window?

Because the verification code would have to travel as tmux new-window -e KEY=VALUE, the tmux client’s own command line, which anyone on the machine can read with ps. sshelf refuses to put a one-time code there, so those hosts connect in place instead, printing 2FA host — connecting here before the handoff. The same applies to stored-password hosts in vault mode (the master passphrase would cross the same boundary), and to tmux older than 3.0, which has no -e at all. Key, agent, and keyring-backed password hosts open in tmux normally. Details: Connecting inside tmux.

Can I send more than one file at a time?

Mark them: Space toggles a mark in the transfer screen, Ctrl-a marks everything the filter shows, and Ctrl-s sends the lot, folders included and recursively, one at a time over the one connection. F7 (or Ctrl-f) creates a directory on either side without leaving the screen.

My 2FA host fails before I can type the code

Flag it: 2FA = yes in the edit form (or --2fa on sshelf add). A stored-secret connect routes all prompts to the askpass helper with no terminal fallback, so the verification prompt needs the 2FA flow to answer it.

Tab completion doesn’t complete my host names

Completion has two layers. The packages install static completion (subcommands + flags), so open a new shell to load it. Completing your saved host names needs the dynamic engine sourced in your shell rc, one line per shell: Shell completions.

If host names still don’t complete, check the database itself parses: sshelf doctor.

A forward vanished from F4

F4 only ever shows forwards whose processes are actually running: the list is reconciled against the OS on launch and refreshed live while open. If the tunnel died ( reboot, sleep, network drop, killed from another terminal), it leaves the list; start it again with Ctrl-f. Automatic re-launch of dropped forwards isn’t there yet.

How do I back up or sync my hosts?

hosts.toml is one human-readable TOML file, so keep it in your dotfiles like any config (a custom path is a setting: Configuration). Secrets don’t travel with it: they’re per-machine, in each machine’s keyring or vault, so re-add them with sshelf set-password. Frecency state is per-machine and app-managed.

On the new machine, run sshelf doctor. It checks the file parses, has no duplicate names or ids, and that its sites all exist.

Where did the first-connection host-key prompt go?

Connections pass StrictHostKeyChecking=accept-new: a brand-new host’s key is accepted and recorded on first use (so the prompt can’t interfere with automated password supply), while a changed key for a known host still hard-fails, as ever. The tradeoff is discussed in Security.

Windows?

Not currently. Connect hands off via Unix exec(), and the askpass/process plumbing is Unix-specific. macOS + Linux for now.

Something isn’t working and I don’t know why

Run sshelf doctor. It checks the OpenSSH version, your secret backend, the host database, dangling site references, the ssh-agent, and the exported ssh_config fragment, and names a fix for anything that isn’t right. It’s local and read-only, and it never contacts a host.

My question isn’t here

Ask in GitHub Discussions. Questions, ideas, and feature requests all belong there, and answers that come up often end up on this page.