SSM — Secure Shell Manager
A fast, keyboard-driven TUI that makes your existing
~/.ssh/configdelightful to use at fleet scale.
No agents. No changes on your servers. Just a better way to navigate the SSH config you already have.
30-second quick start
# 1. Install curl -fsSL https://github.com/lfaoro/ssm/raw/main/scripts/get.sh | bash # 2. Tag a few hosts in ~/.ssh/config Host prod-api #tag: production,api HostName 10.0.0.42 User deploy # 3. Launch ssm production # filter to production hosts ssm # or see everything
That's it. SSM reads your existing config (including Include directives), adds powerful navigation on top, and never touches your remote machines.
What you get
- Instant filtering by tags, names, or fuzzy search (
/) - Live reachability —
ppings the selected host,Ppings everything visible (bounded concurrency based on CPU cores) - One-keystroke connect —
Enter(toggle SSH/Mosh withTab) - Batch commands —
ssm [tag] -r 'uptime && whoami'runs across any filtered set, non-interactively - Integrated SFTP —
Ctrl+sopens a two-pane file browser with batch transfers - Remote execution —
Ctrl+rfor interactive commands on the selected host - Cloud discovery —
ssm sync hetzner|aws|gcp|azurepulls running instances into your config automatically - Live config editing —
Ctrl+eopens your SSH config in$EDITOR, then reloads - Everything else — copy host name with
y/Y, config inspector (Ctrl+v), themes,--pingat startup,--exitfor clean handoff, and more
How tagging works
Add lightweight comments to your existing entries:
#tagorder # optional: show tagged hosts first Host web-01 #tag: production,web,eu HostName 203.0.113.10 User deploy IdentityFile ~/.ssh/prod_ed25519 Host db-primary #tag: production,database HostName 203.0.113.20 ProxyJump web-01
Then use those tags as filters:
ssm production # all production hosts ssm web # anything tagged "web" ssm eu,production # combine tags
SSM supports full Include recursion, globs, #tagorder, and cycle detection.
Cloud provider sync
Discover running servers and write them into your SSH config with zero manual work:
ssm sync # all configured providers ssm sync aws hetzner # specific providers ssm sync --dry-run # preview only ssm sync --user deploy --key ~/.ssh/id_ed25519
- Each provider gets its own file under
~/.ssh/config.d/50-ssm-{provider} Include config.d/*is added to your main config automatically- Hosts are tagged with the provider name so you can filter with
ssm aws
Supported providers and credentials:
- Hetzner:
HCLOUD_TOKEN - AWS: standard SDK chain (
AWS_PROFILE, env vars, IAM role) - GCP:
GCP_PROJECT+ Application Default Credentials - Azure:
AZURE_SUBSCRIPTION_ID+ Azure auth chain
Key bindings (TUI)
| Key | Action |
|---|---|
Enter |
Connect (SSH or Mosh) |
Tab |
Toggle SSH ↔ Mosh |
p |
Ping selected host |
P |
Ping all visible hosts |
y / Y |
Copy host name to clipboard |
/ |
Fuzzy search / filter |
q or Ctrl+c |
Quit |
Ctrl+e |
Edit ~/.ssh/config in $EDITOR |
Ctrl+r |
Run command on selected host |
Ctrl+s |
Open SFTP file browser |
Ctrl+v |
Toggle parsed config inspector |
Ctrl+y |
Open cloud sync panel |
Esc |
Clear filter / close panels |
Emacs navigation (Ctrl+p/n/b/f) also works.
CLI flags & batch usage
ssm [tag] # launch TUI, optionally filtered ssm --backend mosh # launch with mosh as default for direct connections (Tab toggles; Ctrl+r and batch stay on ssh) ssm exec prod 'uptime' # run command on matching hosts and exit (recommended) ssm e web --delay 150ms 'nginx -t' # with pacing and concurrency control ssm [tag] -r 'uptime' # legacy form (still works; see --help) ssm --exit prod-api # connect and fully replace the ssm process ssm --order production # show tagged hosts first ssm -t matrix # use a different theme (sky | matrix) ssm -c ~/.ssh/work_config # use a custom config file # env var also works: SSM_BACKEND=mosh ssm
The -r / --command flag (and the newer ssm exec subcommand) are fully scriptable and exit non-zero if any host fails. Use ssm exec --help for the current options including --delay, --threads, and jitter control.
Note: --backend / SSM_BACKEND (and the Tab toggle) only affect direct Enter connections in the TUI. Batch execution, the legacy -r path, and the Ctrl+r "run command" submodel always use ssh.
Security & hardening
SSM is built for production infrastructure teams:
- Zero software is ever installed on remote hosts
- Every SSH, mosh, and SFTP invocation uses the
--delimiter to prevent flag injection BatchMode=yes+RequestTTY=nofor all non-interactive operations- Sensitive keys (
IdentityFile,ProxyCommand, etc.) are filtered from the config viewer - SSH config file permissions are checked (warns if not 0600)
- All remote output is sanitized (ANSI stripped, stderr truncated)
- Ping uses ordinary TCP connects — no raw sockets or elevated privileges
See SECURITY.md for the full model.
Installation
Fastest:
curl -fsSL https://github.com/lfaoro/ssm/raw/main/scripts/get.sh | bashPackage managers:
| Platform | Command |
|---|---|
| Go | go install github.com/lfaoro/ssm@latest |
| macOS | brew install lfaoro/tap/ssm |
| Arch Linux | yay -S ssm-bin (AUR) |
| Nix | nix profile install github:lfaoro/ssm |
| Nix (run) | nix run github:lfaoro/ssm |
| Debian | sudo apt install ./ssm_*_linux_*.deb download from Releases |
| RPM | sudo rpm -i ssm_*_linux_*.rpm download from Releases |
Pre-built static binaries for Linux, macOS, FreeBSD, and OpenBSD (amd64 + arm64) are available on the releases page.
From source:
# requires Go git clone https://github.com/lfaoro/ssm.git \ && cd ssm \ && make \ && bin/ssm
Development
See CONTRIBUTING.md.
The project follows a strict “never commit unless explicitly told” policy for AI agents and careful humans. Full rules are in AGENTS.md.
Release process is documented in DEPLOY.md.
Sponsorship
SSM is developed in the open.
- GitHub Sponsors
- BTC:
bc1qzaqeqwklaq86uz8h2lww87qwfpnyh9fveyh3hs - XMR:
89XCyahmZiQgcVwjrSZTcJepPqCxZgMqwbABvzPKVpzC7gi8URDme8H6UThpCqX69y5i1aA81AKq57Wynjovy7g4K9MeY5c - FIAT: Revolut
- Telegram: @leonarth
License
MIT © Leonardo Faoro and contributors
