Installation
# Via cargo
cargo install ssm
# From GitHub Releases
# Download the binary for your platform from:
# https://github.com/CtrlUserKnown/ssm/releases
ssh -V.
First run
Run ssm to launch the TUI. On first launch, a config directory is created at ~/.config/ssm/. Sessions are stored in sessions.json and preferences in config.toml.
TUI overview
The TUI has several screens:
- List view (default): Shows all sessions with status dots, host info, tags, and latency sparklines.
- Form view: Add or edit a session (7 fields: Name, Host, User, Port, ProxyJump, Tags, Password).
- Search: Filter sessions with
/. - Tag picker: Filter by tag with
T. - Help: Press
?for the full keybinding reference. - Confirm delete: Safety prompt before removing a session.
Keyboard shortcuts
| Key | Action |
|---|---|
j / k | Move down / up (supports numeric prefixes, e.g. 5j) |
gg / G | Go to first / last session |
Ctrl-d / Ctrl-u | Half-page scroll down / up |
Ctrl-f / Ctrl-b | Full-page scroll down / up |
Enter | Connect to selected session |
a | Add new session |
e | Edit selected session |
D | Delete selected session (prompts for confirmation) |
y | Yank (copy) user@host to clipboard |
/ | Search / filter sessions (matches tags too) |
T | Filter by tag (group view); Esc clears the filter |
s | Open settings menu (herdr, probe, biometric, theme) |
u | Reload sessions from disk |
Space | Open which-key menu (delete, yank, tag filter, import, settings) |
? | Toggle help screen |
q | Quit |
CLI options
| Command | Description |
|---|---|
ssm | Launch the full-screen TUI |
ssm -c USER@HOST[:PORT] | Connect directly to a host |
ssm -l / ssm --list | Print saved sessions as a table |
ssm --import [PATH] | Import hosts from an ssh_config file (default ~/.ssh/config); skips names that already exist |
ssm --version | Print version |
ssm --help | Print help |
use_herdr = true in config.toml to connect via herdr instead of ssh.
Managing sessions
Each session has 7 fields:
- Name: Display name for the session.
- Host: Hostname or IP address.
- User: SSH username.
- Port: SSH port (default 22).
- ProxyJump: Optional jump host (e.g.,
bastionoruser@bastion:2222). - Tags: Free-form comma or space-separated labels.
- Password: Optional, stored in OS keychain only.
SSH config import
Run ssm --import to import sessions from ~/.ssh/config. The import reads concrete Host blocks and carries over HostName, Port, User, and ProxyJump directives. Wildcard blocks (Host *, Host web-*) are skipped. Sessions with duplicate names are not overwritten.
# Import from default location (~/.ssh/config)
ssm --import
# Import from a custom path
ssm --import /path/to/ssh/config
ProxyJump
The ProxyJump field specifies an intermediate host to SSH through. This is passed to ssh as -J <jump>. Examples:
bastion # simple hostname
user@bastion:2222 # with user and port
bastion,internal # multi-hop, comma-separated
ProxyJump values imported from ~/.ssh/config are carried over automatically.
Password storage
ssm stores passwords in your OS keychain, never in plaintext on disk:
- macOS: macOS Keychain (via the
apple-nativekeyring backend) - Linux: Secret Service API (via
secret-servicebackend, e.g., gnome-keyring)
The JSON session file (sessions.json) contains all session fields except passwords.
SSH_ASKPASS
When connecting to a session with a stored password, ssm uses the SSH_ASKPASS mechanism:
- ssm creates a temporary Unix domain socket with 0600 permissions.
- Sets
SSH_ASKPASS=/path/to/ssmandSSH_ASKPASS_REQUIRE=force. - ssh re-execs ssm as the askpass helper.
- The helper connects to the socket, presents a random nonce, and receives the password.
- Serve-once semantics: on auth retry, the helper returns empty.
Biometric unlock
Optional feature, off by default. Enable via Space > Settings > b, or biometric_unlock = true in config.toml. When on, ssm requires a biometric check before revealing a stored password at connect time. Passwords are loaded lazily (only at connect), so the prompt actually gates access.
- Linux: Uses
fprintd-verify— a fingerprint presence gate in front of the Secret Service release. Not cryptographically bound to the secret. - macOS: Touch ID is not wired up yet. A real implementation needs
LocalAuthenticationand a stably code-signed binary so the Secure Enclave keychain item survives rebuilds. Usescripts/sign-macos.shwith a free self-signed certificate for personal use, or a Developer ID certificate + notarization to distribute. Until it lands, enabling biometric on macOS falls back to a plain keychain read with a warning.
Config file
Location: ~/.config/ssm/config.toml
use_herdr = true
theme = "noir-cat"
probe = true # background reachability probing + latency in the list
biometric_unlock = false # require a biometric check before revealing a password
Override the config directory with DOTS_SSM_DIR=/path/to/dir.
Themes
ssm ships with 7 built-in themes:
- auto: Follows terminal ANSI palette
- noir-cat: Catppuccin Mocha on neutral gray
- knew-pines: Rose Pine inspired
- catppuccin: Catppuccin Mocha
- gruvbox: Gruvbox dark
- nord: Nord
- tokyo-night: Tokyo Night
Switch themes from the TUI: Space > Settings > Theme. Or set in config.toml.
Probing
Background TCP probes run every few seconds on a dedicated thread. Each session gets:
- A color-coded status dot: green (<50ms), yellow (<200ms), red (unreachable), gray (not yet probed)
- A latency sparkline showing history
Toggle probing: Space > Settings > Probe, or set in config.toml.