AES-256-GCM
Authenticated encryption straight from node:crypto — no external crypto dependency, no GPG.
A wrong passphrase or a tampered file fails fast: ENCRYPTION_FAILED, with zero technical detail leaking out.
Keyr is a local-first CLI vault for API keys and credentials — AES-256-GCM encrypted, scrypt-hardened, stored in a single file at ~/.keyr/vault.json, and injected into any tool with keyr run. Nothing ever leaves your machine.
CAPABILITIES
Standard primitives, explicit errors, atomic writes — and not a single surprise hiding behind a flag.
Authenticated encryption straight from node:crypto — no external crypto dependency, no GPG.
A wrong passphrase or a tampered file fails fast: ENCRYPTION_FAILED, with zero technical detail leaking out.
Your passphrase never becomes the key directly. scrypt derives a 32-byte AES key with a random salt generated per vault — brute-forcing the ciphertext gets deliberately expensive.
Spawn any command with your secrets injected into its environment — plaintext exists only in the child process's memory, never back on disk.
Run keyr bare for a menu-driven session. It requires a real TTY — non-interactive pipes are politely rejected.
There is no network code in Keyr at all. No telemetry, no sync, no account — nothing to opt out of, nothing to leak.
The whole vault is ~/.keyr/vault.json — written atomically, chmod 0o600 best-effort,
user-scoped ACLs on Windows. Repoint it with KEYR_HOME for sandboxes and tests.
A new IV is generated on each save — two writes of the same plaintext never produce the same ciphertext.
9f4ce2a1b7d05538A codebase you can audit over coffee — Commander, Ink, ora, esbuild. Nothing exotic.
LIFECYCLE
One passphrase becomes one AES-256 key — and your secrets become one authenticated file. The salt persists; the IV never repeats.
{
"version": 1, // vault format
"kdf": "scrypt", // N=16384 · r=8 · p=1
"salt": "qK1e…", // random · per vault
"iv": "8Mwz…", // fresh on every write
"authTag": "tX9p…", // GCM integrity
"ciphertext": "kJ8s…" // your secrets, sealed
}
{
"secrets": {
"OPENAI_API_KEY": "sk-…",
"GEMINI_API_KEY": "…",
"ANTHROPIC_API_KEY": "sk-ant-…"
}
} // plaintext exists only while a command runs
Flip one byte of ciphertext and the auth tag fails the whole decryption — tampering is a hard stop, not a warning.
ENV INJECTION
keyr run spawns your command with secrets injected straight into its environment — plaintext lives only in the child process's memory.
The passphrase arrives via a masked prompt, or KEYR_PASSPHRASE for scripts — never as a CLI argument, so it stays out of shell history and logs.
stdio: 'inherit' keeps TUIs, colors and Ctrl-C intact; shell: true resolves .cmd shims on Windows; env merges your secrets in by name.
The child's exit code propagates — so $? and $LASTEXITCODE stay meaningful inside your scripts.
spawn(command, {
stdio: 'inherit', // TUI · colors · Ctrl-C — untouched
shell: true, // resolves .cmd shims on Windows
env: { ...process.env, ...secrets } // name → env var
})
IF IT READS CREDENTIALS FROM ENV, ONE VAULT CAN FEED IT
"apiKey": "{env:HIVE_API_KEY}"
Tools reference the name, never the value — substitution happens in memory when the process starts. The vault never writes plaintext back to disk.
THE VERBS
Nine verbs with explicit error codes — VAULT_EXISTS, SECRET_NOT_FOUND, ENCRYPTION_FAILED — and nothing hidden behind flags you'll never find. Click any command to copy it.
Create a fresh vault. Refuses to clobber an existing one — VAULT_EXISTS.
Add or update a secret. Decrypt → mutate → re-encrypt with a fresh IV → atomic write.
Print one secret. Misses are explicit: SECRET_NOT_FOUND / VAULT_NOT_FOUND.
Every secret name in the vault — the values stay sealed.
Remove a secret. Asks y/N unless --yes is passed for scripts.
Take your secrets with you.
Deletes the vault permanently. There is no recovery — by design.
Spawn a command with secrets injected into its environment; the child's exit code is inherited.
Bare invocation opens the interactive TUI menu. Requires a real TTY — pipes are politely rejected.
HONEST LIMITS
Keyr is explicit about what it isn't. No overclaims — that's the whole point.
Malware running as your user can still read the child's environment and keystrokes. Keyr moves secrets from permanent storage to session memory — it narrows the window of exposure, it doesn't build a wall.
scrypt makes brute-force expensive, but a short passphrase is still the weak link. Choose long.
The passphrase is never stored anywhere — not on disk, not in a log. Lose it and the data is gone. There is no recovery, by design.
The primitives are standard and correctly used — but Keyr has not been through an independent security audit. Honest today; better later.
One file. One passphrase. Every tool.
Node ≥ 18 · Windows / macOS / Linux — and yes, this page is a single static file.