Docs
Command reference.
Two programs: keyward (CLI and agent) and keyward-manager (setup wizard and GUI). Every command that opens the vault tries an enrolled security key first and falls back to the passphrase; --passphrase skips the key. Full design notes ship with the source.
What exists today
keyward is pre-release. Built means in the main branch and tested. In development means designed and under construction. Nothing is promised for a date.
- BuiltEncrypted vault: Argon2id passphrase, FIDO2 security key, recovery phrase, passphrase plus USB; a file or a raw partition behind a root/SYSTEM service
- BuiltAgent for Windows (named pipe) and Linux (Unix socket), per-program allowlists, process memory hardening
- BuiltDestination-aware approvals: verified session binding; root, sudo and forwarded requests always re-authenticate; per-key modes; time-boxed dangerous mode
- BuiltHardware-held keys inside a YubiKey, with backup-device pairing
- Builtkeyward-host: enrol, audit, grant, revoke, rotate over ssh only; pinned host keys
- BuiltShort-lived certificates (10 minutes, one server, one account) from a CA in your vault, offered before raw keys; software keys only so far
- BuiltShadow-login detection, configuration-drift alerts, canary keys, rekey, encrypted backups, restore from the phrase alone
- In developmentTask approvals: one touch issues exactly the access a named task needs
- In developmentCaller attestation by code signature
- In developmentRedesigned manager (built, not yet tested on real hardware), signed and reproducible builds, winget and Linux packages
- LatermacOS; an external review before 1.0
The vault
One file (or partition) holding your keys, encrypted with XChaCha20-Poly1305 under a data key that each unlock method wraps separately. Adding or removing an unlock method never re-encrypts the contents; rekey does, on purpose.
keyward initCreate the vault. Prints the 24-word recovery phrase once; write it down.keyward phraseShow the recovery phrase again (vault must be unlocked).keyward gen dj-2026 --comment daf@keywardNew Ed25519 key, derived from the phrase so it can be recreated. Prints the public line.keyward import name ~/.ssh/id_ed25519Copy an existing OpenSSH private key into the vault. Ed25519, ECDSA and RSA (2048 bits or more). RSA keys sign with rsa-sha2-256/512 only, never SHA-1.keyward discover [--import]Find private keys on this machine, including the other OS's home on a dual boot; import the new ones.keyward list · keyward pub name · keyward rm nameWhat's inside, a public line for authorized_keys, remove an entry.keyward backup fileEncrypted copy, imported keys included. Unlocks first. Opens with the phrase, a passphrase or an enrolled key.keyward restore [--from-backup file]Rebuild a lost vault from the phrase alone (generated keys), or from a backup (everything).keyward rekeyNew data key. Keeps the slot you authenticate with and the phrase slot; other credentials stop opening the vault and its previous copy (the .bak file or the partition's older half) is destroyed. Backups made before the rekey still open with the old credentials; make a new one.Unlock methods
keyward slotsList unlock methods. No unlock needed.keyward slot add-fido2 [--no-pin]Enrol a FIDO2 security key: touch twice, PIN. Repeat for a backup key. Touch-only slots open for anyone holding the key and a copy of the vault.keyward slot add-passphrase · add-recoveryAnother passphrase; another 24-word code that unlocks but can't recreate keys.keyward slot add-usb partition-idPassphrase plus a keyward USB (see below): both needed.keyward slot rm idRemove a slot. The last passphrase-or-key slot stays. Follow with rekey if the credential may have leaked.keyward recoverOpen with the recovery phrase and set a new passphrase.keyward usb list · usb format disk --eraseTurn a USB stick into a keyward USB: a small filesystem-less partition holding a random token. A possession factor, not a hardware key.Hardware-held keys
keyward hwkey yubi-2026An SSH key made inside the security key. The private key never leaves the device; every use is a touch (and PIN).keyward hwkey yubi-backup --backup-of yubi-2026The same on a second device. host grant authorizes both.The agent
keyward agent [--locked]Serve until Ctrl+C. Setup installs it at sign-in instead.keyward envThe SSH_AUTH_SOCK line for your shell.keyward statusLocked or not, keys, who holds them, recently refused programs and why, recent approvals, dangerous mode.keyward lock · keyward unlockAlso ssh-add -x and ssh-add -X.keyward allow dj-2026 ssh gitRestrict one key to certain programs. No programs: back to the global list.Approvals
Root and sudo logins, and anything arriving through agent forwarding, always ask you to re-authenticate in a prompt that names the program, key, account, server and what it reaches. Approving re-opens the vault with the security key or passphrase; the agent accepts nothing else. Other uses follow the key's setting.
keyward approval github relaxedNever ask unless root or sudo. For GitHub and git signing.keyward approval dj-2026 session:15Ask once per 15 minutes, per destination.keyward approval deploy alwaysAsk every time.keyward danger dj-2026 --hours 2Root and sudo without asking, at most 24 hours, confirmed by typing a phrase, logged. --off ends it.keyward eventsThe vault's security event log.Servers
keyward-host is the server half: a static Linux binary reached only as an sshd forced command, no listener. Enrolled servers, their pinned host keys and their management keys live in the vault. Every connection uses a throwaway in-memory agent, an empty ssh config and the pinned host keys only.
keyward host check au [--remember au]One-off read-only audit through your own ssh. Installs nothing. Remembering pins the host keys and facts so prompts know where logins go.keyward host enroll au --via auInstall keyward-host and the locked keyward account, pin the host keys.keyward host report auAccounts, what each can do, keys, last use, and any logins not made by keyward.keyward host grant au okwl zas.pub --restrict --from 203.0.113.0/24Authorize a key for an account with structured options. A hardware key's backup is granted with it.keyward host revoke au okwl SHA256:…Remove a key by fingerprint. Refuses the account's last key without --force.keyward host rotate au svcadmin SHA256:old… dj-2026Swap one key for another in a single write.keyward host list · host forget nameEnrolled and remembered servers; forget one (the server is untouched).Configuration
~/.config/keyward/config.toml on Linux, %APPDATA%\keyward\config.toml on Windows. Everything is optional.
vault = "service" # or a file path, or "partition:/dev/disk/by-partlabel/keyward"
idle_lock_minutes = 30 # 0 = never
allow = ["/usr/bin/ssh", "ssh", "git", "keyward"] # [] = any program
An allow entry is a full path, or a program name. A name only counts for a program in a directory you can't write to, so something renamed to ssh in your home directory is refused, and keyward status says why. KEYWARD_VAULT, KEYWARD_CONFIG and KEYWARD_SOCK override the vault, config and socket.
Lock on screen lock and sleep
The agent locks after idle_lock_minutes. Locking the moment the screen locks is a hook in your desktop: on Linux a small user unit watches the screensaver and logind signals and runs keyward lock; on Windows a Task Scheduler task triggered "on workstation lock" does the same. The Linux unit ships with the source; the Windows task is made by hand, as the README describes.
Source
The repository, licence and signed releases are published together with the first release. Until then this site is the public face, and the threat model is the honest one.