A fast, local CLI for managing API keys and secrets. Built with Go, SQLite, and Bubble Tea.
Keys are stored locally in ~/.keys/keys.db — nothing leaves your machine.
curl -sSL https://raw.githubusercontent.com/stym06/keys/main/install.sh | shOr with Homebrew:
brew install stym06/tap/keysOr with Go:
go install github.com/stym06/keys@latestkeys add OPENAI_KEY sk-abc123If the key already exists, you'll be prompted to overwrite, edit, or cancel.
keys get OPENAI_KEY # prints the value
keys get # interactive typeahead pickerkeys seeInteractive search with checkboxes. Keybindings:
| Key | Action |
|---|---|
| Type | Filter keys |
| Space | Toggle checkbox |
| Tab | Copy selected as KEY=VAL |
| S-tab / Ctrl+Y | Copy selected as export KEY=VAL |
| Ctrl+E | Export selected to .env file |
| Enter | Add a new key (when no matches) |
| Esc | Quit |
Keys show age indicators: green (< 30 days), yellow (30-90 days), red (> 90 days).
keys peekSame as see but values are hidden as ***. Press r to reveal the key under the cursor.
keys edit OPENAI_KEYOpens a TUI editor for the key name and value. Tab switches fields, Enter saves.
keys rm OPENAI_KEYkeys env # interactive .env file generator
keys expose # print export statements to stdoutkeys env lets you select keys and choose a directory for the .env file.
keys import .envParses .env files — handles comments, quotes, and export prefixes.
Isolate keys by project or environment:
keys profile use dev # switch to "dev" profile
keys add DEV_DB localhost # stored under "dev"
keys profile use default # switch back
keys profile list # show all profiles (* = active)$(keys inject API_KEY DB_HOST) ./my-script.sh # inline env vars
docker run $(keys inject -d API_KEY DB_HOST) my-image # Docker -e flags
$(keys inject --all) ./my-script.sh # all keys
$(keys inject --all --profile dev) ./my-script.sh # from specific profile# On machine A (has the keys)
keys sync serve
# Serving 12 keys from profile "default"
# Passphrase: olive-quilt-haven
# Waiting for connections...
# On machine B (wants the keys)
keys sync pull # auto-discover via mDNS
keys sync pull 192.168.1.10:7331 # or connect directlyPeer-to-peer sync over the local network. Auto-discovers peers via mDNS/Bonjour, encrypted with a one-time passphrase. Works over WiFi, Tailscale, or any reachable network.
keys audit # summary: access count + last used per key
keys audit --log # full access log (most recent first)
keys audit --log -n 20 # last 20 events
keys audit --clear # clear the audit logTracks when keys are accessed via get, inject, and expose.
keys check # reads .keys.required from current directory
keys check reqs.txt # custom fileReads key names from a file (one per line, # comments supported) and reports which are present or missing. Exits with code 1 if any are missing — useful for CI and agent pre-flight checks.
Example .keys.required:
# Agent dependencies
OPENAI_KEY
SERP_API_KEY
DATABASE_URL
keys nuke # delete all keys in active profileRequires typing nuke to confirm.
Enable tab-completion for key names:
# zsh (add to ~/.zshrc)
source <(keys completion zsh)
# bash (add to ~/.bashrc)
source <(keys completion bash)
# fish
keys completion fish | sourceWith zsh-autosuggestions, you get inline ghost suggestions as you type.
MIT
