" type="image/svg+xml" />
free & open source

A local-first secret manager for API keys and secrets

One encrypted vault on your own machine — AES-256-GCM with scrypt key derivation. No server. No account. No telemetry.

Requires Node.js 18+. Windows, macOS and Linux.

keyr init
Vault created at ~/.keyr/vault.json
keyr set HIVE_API_KEY
Secret value: ********
Secret "HIVE_API_KEY" saved.
keyr run opencode
Injected 1 secret(s) into the child process environment.
# secrets live in process memory only — never on disk in plaintext

Where do your keys live now?

  • A notes app or a message to yourself
  • A plaintext apiKey in a config file, synced and backed up along with everything else
  • Pasted into source code that gets committed and pushed

None of these are attacks on you. They are just the only options when there is no proper place to put things.

One vault, one file

Keyr keeps every secret in a single encrypted file at ~/.keyr/vault.json. The file can be copied, synced or stolen — without your passphrase it is unreadable.

When a command needs a key, keyr run injects secrets into that process's environment only. Nothing is written to disk in plaintext, and the values disappear when the process exits.

What it does

Four things, done deliberately. That is the whole feature list.

AES-256-GCM + scrypt

Node's built-in crypto: authenticated encryption, memory-hard key derivation, random salt per vault, fresh IV per write. No GPG, no system dependencies.

Single-file vault

Everything lives in ~/.keyr/vault.json. Back it up like any file, delete it to reset. No account to provision, no store to migrate.

keyr run — secrets as env vars

Launch any command with your secrets injected as environment variables. Tools that read {env:VAR} in their config — like OpenCode — get real values without secrets ever touching disk.

TUI + scriptable

Interactive menu for everyday use; direct commands and a KEYR_PASSPHRASE environment variable for scripts. Passphrase is always prompted masked, never a CLI argument.

How it works

1

Create the vault

keyr init — pick a passphrase, get an encrypted file. The passphrase stays in your head; it is never stored anywhere.

2

Store secrets

keyr set HIVE_API_KEY — values prompted masked so they stay out of shell history and scrollback.

3

Run tools safely

keyr run opencode opens the vault, injects secrets into the child process environment, and exits with the command. Point configs at names, not values: "apiKey": "{env:HIVE_API_KEY}"

How it compares

Established tools exist — Keyr is a specific trade-off, and it is fine to pick another.

ToolThe trade-off
pass / gopassBattle-tested, but requires GPG (painful on Windows) and spreads one file per secret across a tree.
Bitwarden CLINeeds a server (cloud or self-hosted) and an account.
1Password CLIGreat env injection — but paid, cloud, account.
Infisical / DopplerBuilt for teams; heavy for personal secrets.
age / sopsEncrypt files, but are not managers — no list/set/get or TUI.
KeyrNode-native (no GPG), single-file vault, keyr run injection, zero accounts. Local-only by design.

Honest questions

Is the vault file safe if someone copies it?

Yes, within the limits of the passphrase. The file is AES-256-GCM encrypted and the key is stretched with scrypt, so guessing is expensive. A weak passphrase weakens this — pick a long one.

Does this protect me from malware on my machine?

No. Any process running as your user can read a child's environment or capture keystrokes. Keyr removes secrets from where they sit permanently on disk — it does not defend against active compromise. No local tool honestly can.

Where is my data sent?

Nowhere. Keyr has no network code at all. No telemetry, no update checks, no sync.

What if I forget the passphrase?

The secrets are gone. There is no recovery, by design. keyr reset deletes the vault so you can start over.