sshush

# sshush **An interactive terminal UI for SSH keys, the ssh-agent, and `~/.ssh/config`.** [![Latest release](https://img.shields.io/github/v/release/s-johri/sshush)](https://github.com/s-johri/sshush/releases/latest) [![CI](https://github.com/s-johri/sshush/actions/workflows/ci.yml/badge.svg)](https://github.com/s-johri/sshush/actions/workflows/ci.yml) [![Go version](https://img.shields.io/github/go-mod/go-version/s-johri/sshush)](go.mod) [![License: MIT](https://img.shields.io/github/license/s-johri/sshush)](LICENSE) ![sshush demo — browsing keys and hosts, filtering, and a live theme switch](/sshush/docs/demo.gif)

sshush is an interactive terminal UI (TUI) for managing SSH keys, the ssh-agent, and your ~/.ssh/config — an SSH key manager, agent controller, config editor, and connection launcher in one keyboard-driven app, written in Go. Switch keys, see what’s loaded in the agent, browse and connect to hosts, and edit your config safely without leaving the terminal.

Status: in active development. Edits to your SSH config are gated behind a confirmation and a .bak backup is written before the first change, but treat it as pre-1.0 software.

Features

Themes

16 built-in color themes (foreground + background), switchable live with t — Dracula, Nord, Gruvbox, Solarized, Catppuccin, Tokyo Night, and more:

Dracula Nord
sshush with the Dracula theme sshush with the Nord theme
Catppuccin Mocha Solarized Light
sshush with the Catppuccin Mocha theme sshush with the Solarized Light theme

Requirements

Install

Homebrew (macOS / Linux)

brew install s-johri/tap/sshush

Arch Linux (AUR)

yay -S sshush-bin   # or: paru -S sshush-bin

Both ship shell completions and the man page (man sshush).

Install script

curl -fsSL https://raw.githubusercontent.com/s-johri/sshush/main/install.sh | sh

Detects your OS/arch, downloads the matching release archive, verifies its checksum, and installs sshush to ~/.local/bin (override with INSTALL_DIR). Pin a version with SSHUSH_VERSION=v0.7.0.

Prebuilt binary

Download the archive for your OS/arch from the latest release, extract it, and put sshush on your PATH. Once installed from a release, update in place:

sshush update    # fetches the latest release and replaces the binary
sshush version   # show the installed version

Build from source

git clone https://github.com/s-johri/sshush.git
cd sshush
go build -o "$(go env GOPATH)/bin/sshush" ./cmd/sshush

Make sure $(go env GOPATH)/bin is on your PATH.

Run the tests with go test ./.... The end-to-end suite (a throwaway ssh-agent, key, and config) is behind a build tag — go test -tags e2e ./... — and needs ssh-agent/ssh-add/ssh-keygen on your PATH.

go install

go install github.com/s-johri/sshush/cmd/sshush@latest

Shell completions

The Homebrew and AUR packages install completions automatically. For a manual install, run sshush install-extras to write the embedded man page and all three completion scripts to your user directories (XDG paths); sshush update and install.sh refresh them. Or print a single script yourself:

sshush install-extras   # man page + bash/zsh/fish completions → user dirs
sshush completion bash > /etc/bash_completion.d/sshush
sshush completion zsh  > "${fpath[1]}/_sshush"
sshush completion fish > ~/.config/fish/completions/sshush.fish

Usage

sshush              # launch the interactive TUI
sshush load-default # load the configured default identity into the agent
sshush shell-init   # print a shell snippet to load the default on shell start
sshush restore      # revert the SSH config to the backup from before edits
sshush update       # update to the latest release
sshush version      # print the installed version
sshush completion <shell>  # print a bash/zsh/fish completion script
sshush install-extras      # install the man page + completions to user dirs
sshush help         # show help

Keybindings

Keys pane

Key Action
enter / space load / unload the selected key in the agent
U unload all keys from the agent
s toggle the selected key in/out of the startup defaults
c copy the public key or fingerprint to the clipboard
n generate a new key (ssh-keygen)
d delete the selected key’s files (irreversible)

Hosts pane

Key Action
enter ssh into the selected host
e edit host directives (tab to cycle, ctrl+o add option, ctrl+d delete)
i attach / detach keys for the host
c copy a ready-to-run ssh command to the clipboard
n add a new host (guided wizard)
d delete the host

Read-only Match blocks are shown for reference; edit/connect actions are declined on them.

Anywhere

Key Action
tab / switch panes
/ k j move
PgUp PgDn, g G page / jump to top / bottom
/ filter the active pane (esc clears)
P / K permission audit / known_hosts
R restore config from backup (undo edits since session start)
t / m switch theme / toggle motion
? full keybinding help
r refresh
q / ctrl+c quit

Writes are confirmed with y / n; esc cancels an overlay.

Load the default key on shell startup

Mark a key as default in the TUI (Keys pane → s), then add the snippet to your shell rc so each new shell loads it:

sshush shell-init >> ~/.bashrc   # or ~/.zshrc

The snippet only runs if sshush is on your PATH, and load-default is a no-op when the keys are already loaded — cheap and safe to run on every shell. shell-init warns (on stderr) if the snippet is already in a shell rc, so you don’t add it twice; the TUI also nudges you to install it when you set a default.

Configuration

sshush stores its own settings (separate from ~/.ssh/config) at $XDG_CONFIG_HOME/sshush/config.toml (default ~/.config/sshush/config.toml):

# Keys auto-loaded into the agent on startup (toggle with `s` in the TUI).
default_identities = ["id_ed25519", "id_work"]

# Optional: point sshush at a non-default SSH location.
# ssh_dir resolves relative Includes and ~ in the config; config_path defaults
# to <ssh_dir>/config when only ssh_dir is set.
ssh_dir = "~/.ssh"
config_path = "~/.ssh/config"

# Optional: color theme (sets foreground + background). Switch live in-app with
# `t`. Presets: default, mono, high-contrast, dracula, nord, gruvbox-dark,
# gruvbox-light, solarized-dark, solarized-light, catppuccin-mocha,
# catppuccin-macchiato, catppuccin-frappe, catppuccin-latte, tokyonight,
# tokyonight-storm, tokyonight-day.
theme = "default"

# Optional: check for a newer release on launch (default true). The check is
# async and best-effort; a notice appears in the status line if an update exists.
check_updates = true

# Optional: opt-in motion/animation (off by default). Toggle in-app with `m`.
[motion]
enabled = false
intensity = "normal"   # subtle | normal | arcade

default_identities is managed from the TUI (s toggles a key in/out; all are loaded on startup). An older default_identity = "..." is migrated automatically. The path overrides can also come from the environment (which takes precedence):

export SSHUSH_SSH_DIR=~/work/.ssh
export SSHUSH_CONFIG=~/work/.ssh/config

The keys above are the stable config.toml schema (frozen as of the v0.9.0 release candidate): within the 1.x line they are never removed or repurposed, only added. Parsing is forward-compatible — an unknown key is ignored, with a sshush: unknown setting "…" (ignored) warning on stderr at startup so typos and stale keys stay visible.

How it works

sshush merges three sources into one view on each refresh:

  1. key pairs scanned from ~/.ssh,
  2. hosts parsed from ~/.ssh/config (following Includes),
  3. identities currently loaded in the agent,

matching disk keys to agent keys by SHA256 fingerprint. Config writes go through a round-tripping parser so comments, ordering, and unknown options survive edits. See ARCHITECTURE.md for the design.

Looking for the YAML config generator?

There is an unrelated, similarly named project: bencromwell/sshush generates a static ssh_config file from YAML source files. This sshush is different — an interactive TUI that works with your existing ~/.ssh/config directly and also manages keys, the ssh-agent, known_hosts, and permissions. If you arrived here looking for the YAML tool, the link above is what you want.

Changelog

See CHANGELOG.md for the per-release history.

License

MIT — see LICENSE.