keyward

module
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 26, 2026 License: MIT

README

Keyward

A terminal UI for managing SSH keys, editing your ~/.ssh/config, auditing security, and keeping encrypted backups — all from one keyboard-driven screen.

CI Release Go Report Card Go

Keyward demo

Contents

Why Keyward?

Your SSH setup is usually scattered across a pile of files: keys in ~/.ssh, hosts in ~/.ssh/config, permissions you hope are right, and no easy way to tell a strong key from a weak one. Keyward puts all of it behind a single keyboard-driven screen:

  • See everything at once — every key with its type, size, fingerprint, and whether it's passphrase-protected, instead of ls-ing a directory and running ssh-keygen -l by hand.
  • Know if you're safe — a graded A–F security audit flags weak keys, missing passphrases, loose file permissions, and risky config directives, each with a concrete fix.
  • Edit config without breaking it — host-by-host editing with validation and byte-identical round-trip serialization: your comments, spacing, and ordering survive untouched, and the last 5 versions are backed up automatically.
  • Encrypted by default — key metadata (tags, notes) and full ~/.ssh backups are encrypted at rest with a key derived from your master password.

No daemon, no config file to learn, no network calls. Just a single static binary.

Features

  • Key management — discover, inspect, generate, rotate, and delete SSH keys (ed25519 / rsa), with fingerprints, comments, and per-key tags & notes.
  • Config editor — edit ~/.ssh/config host-by-host with validation, comment toggling, and byte-identical round-trip serialization. Automatic backups (last 5 kept).
  • Security audit — graded A–F report covering weak keys, missing passphrases, file permissions, and risky config directives, each with a concrete fix: hint.
  • Known hosts viewer — browse ~/.ssh/known_hosts (host, key type, fingerprint, @revoked / @cert-authority markers) and forget a host in place; the file is rewritten atomically with its mode preserved.
  • Encrypted backups — age-encrypted .tar.age snapshots of your ~/.ssh directory plus key metadata, restorable from within the TUI.
  • Encrypted metadata vault — tags and notes are stored encrypted at rest, unlocked by your master password.

Install

Homebrew
brew install gateway-of-last-resort/tap/keyward
Arch Linux (AUR)
yay -S keyward-bin

The keyward-bin package is maintained by the community rather than by this project, so it can lag a release behind. It installs the same signed binaries published here.

Download a release binary

Copy-paste this to grab the right archive for your OS/arch from the latest release, extract keyward, and put it on your PATH:

OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m); case "$ARCH" in x86_64) ARCH=amd64;; aarch64) ARCH=arm64;; esac
VER=$(curl -fsSL https://api.github.com/repos/gateway-of-last-resort/keyward/releases/latest \
      | grep -m1 '"tag_name"' | cut -d'"' -f4)
curl -fsSL "https://github.com/gateway-of-last-resort/keyward/releases/download/${VER}/keyward_${VER#v}_${OS}_${ARCH}.tar.gz" -o keyward.tar.gz
tar -xzf keyward.tar.gz keyward && sudo mv keyward /usr/local/bin/ && keyward --version

Prefer to do it by hand? Download the keyward_<version>_<os>_<arch>.tar.gz for your platform, then tar -xzf it. Verify the download against the published checksums.txt (and its cosign signature — see SECURITY.md) if you like.

[!NOTE] Some browsers (notably Safari) auto-decompress .gz downloads, leaving you with a plain keyward_..._.tar. If you only see a .tar, unpack it with tar -xf (no z).

With Go
go install github.com/gateway-of-last-resort/keyward/cmd/keyward@latest

This installs the keyward binary into $(go env GOPATH)/bin.

Usage

Just run it — no arguments launches the interactive TUI:

keyward

On first launch you set a master password; this creates an encrypted vault at ~/.keyward/master.key. Subsequent launches unlock with that password.

keyward                     launch the interactive TUI
keyward <command> [flags]   run a non-interactive command (see below)
keyward [--version] [--help]
Navigation
Key Action
Tab / Shift+Tab Cycle screens: Keys → Audit → Config → Generate → Known Hosts → Backup → Settings
↑/↓ or j/k Move within a list
Enter Open / confirm
Esc Back / cancel
/ Search (Keys screen)
i Import an external key (Keys screen)
A Add the selected key to ssh-agent (Detail screen)
q Quit (from the Keys screen)
Ctrl+C Quit from anywhere

Per-screen actions (generate, rotate, delete, copy public key, edit config, forget a known host, backup/restore, change master password) are shown contextually in the footer.

[!WARNING] Rotate, delete, and restore modify real files under ~/.ssh. To experiment safely, point Keyward at a throwaway directory — run it under a sandbox HOME or change the SSH directory in Settings before trying destructive actions.

Command line

Beyond the TUI, Keyward exposes headless subcommands for scripting, CI, and cron:

Keyward CLI demo

Command What it does
keyward audit [--json] [--fail-on=<sev>] Run the security audit; print text or JSON
keyward list [--json] List discovered SSH keys (alias: keys)
keyward import <path> [--force] Copy an external key into ~/.ssh with 0600 perms
keyward agent add <key> [--passphrase-env VAR] Load a key into the running ssh-agent
keyward agent list Show which keys are currently loaded in the agent
keyward backup [--out <path>] Write an encrypted ~/.ssh backup

Audit in CI. --fail-on=<critical\|warning\|info> makes the audit exit non-zero when a finding meets that severity, so it can gate a pipeline:

keyward audit --fail-on=critical      # fail the build only on critical findings
keyward audit --json | jq '.grade'    # machine-readable report

Passwords for scripts. keyward backup reads the master password from $KEYWARD_PASSWORD (or prompts if unset). keyward agent add takes the key passphrase from the variable named by --passphrase-env (export it first and pass the variable name, not the passphrase), or prompts when the flag is omitted:

export KEYWARD_PASSWORD='…'
keyward backup --out /mnt/usb/ssh-backup.tar.age

Security

Keyward encrypts metadata and backups with a master key derived from your password (argon2id → ChaCha20-Poly1305 → age identity). For the full threat model, cryptographic details, release-signature verification, and how to report a vulnerability, see SECURITY.md.

Stability

As of 1.0.0, Keyward follows semantic versioning. The on-disk formats (master.key, metadata.age, and .tar.age backups) and the command-line interface are stable: a vault created today keeps working across all 1.x releases, and any breaking change to a format or flag would require a 2.0. The format and migration guarantees are documented in SECURITY.md.

Building from source

git clone https://github.com/gateway-of-last-resort/keyward
cd keyward
go build ./cmd/keyward
go test ./...

Requires Go 1.26+. The security-sensitive core (crypto, config, storage, audit, key parsing) depends only on filippo.io/age and golang.org/x/crypto; the terminal UI layer adds the Charm stack (bubbletea, bubbles, lipgloss).

Roadmap

Ideas being considered for after 1.0 (directions, not commitments):

  • Include directive support in the config editor (multi-file configs)
  • More audit checks: duplicate fingerprints, SSH certificate detection, agent socket permissions
  • Hardware-backed keys (sk-ssh-ed25519@openssh.com, FIDO2) and SSH certificate management
  • Multiple or custom-location vaults, key-rotation reminders, and incremental backups

Feedback and feature requests are welcome via issues.

Contributing

Bug reports, feature ideas, and pull requests are welcome — see CONTRIBUTING.md for build/test/style conventions and the branch-and-PR workflow.

License

MIT

Directories

Path Synopsis
cmd
keyward command
internal
agent
Package agent is a thin wrapper around golang.org/x/crypto/ssh/agent for the two operations keyward needs: loading a key into the running ssh-agent and listing which keys are currently loaded (by fingerprint).
Package agent is a thin wrapper around golang.org/x/crypto/ssh/agent for the two operations keyward needs: loading a key into the running ssh-agent and listing which keys are currently loaded (by fingerprint).
cli
Package cli implements keyward's non-interactive command-line interface.
Package cli implements keyward's non-interactive command-line interface.
knownhosts
Package knownhosts parses and edits an OpenSSH known_hosts file.
Package knownhosts parses and edits an OpenSSH known_hosts file.
ui
Package ui implements the TUI for Keyward using Bubble Tea.
Package ui implements the TUI for Keyward using Bubble Tea.
pkg

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL