Rails-style encrypted credentials for Node. Store secrets as an encrypted
.env-style file that is safe to commit, edit them in your $EDITOR, and run
any command with the credentials injected as environment variables.
Zero runtime dependencies — just Node's built-in crypto (AES-256-GCM).
npm install -g @nerdgeschoss/credentials
# create (or edit) your credentials in $EDITOR
credentials edit
# print the decrypted contents
credentials show
# run any command with all credentials exported as env vars
credentials run -- node server.jsThe first edit generates config/master.key (the encryption key, kept out
of git — it's added to your .gitignore automatically) and
config/credentials.env.enc (the encrypted secrets, safe to commit).
Credentials are plain .env-style text:
# comments and blank lines are fine
AWS_ACCESS_KEY_ID=AKIA...
DATABASE_URL="postgres://user:pass@host/db"
PRIVATE_KEY="line1\nline2"- one
KEY=valueper line; keys must be valid environment variable names - values may be single- or double-quoted; double quotes unescape
\n,\",\\ - duplicate keys are rejected when saving
The key is resolved in this order:
MASTER_KEYenvironment variableRAILS_MASTER_KEYenvironment variable (so existing deploy setups — Heroku config vars, Kubernetes secrets — work as-is; only the variable name is borrowed, the file format is not Rails-compatible)- the key file (
config/master.key)
In production you typically don't ship the key file — set MASTER_KEY
instead:
MASTER_KEY=abc123... credentials run -- node server.jsPass -e/--environment to any command to use a separate credentials file
and key per environment, following the Rails layout:
credentials edit -e production
credentials run -e production -- node server.js| file (commit this) | key (never commit) | |
|---|---|---|
| default | config/credentials.env.enc |
config/master.key |
-e production |
config/credentials/production.env.enc |
config/credentials/production.key |
credentials run never overwrites variables that are already set — the
process environment always wins. That's the override mechanism:
# uses DATABASE_URL from the encrypted file
credentials run -- node server.js
# overrides just DATABASE_URL, everything else still comes from the file
DATABASE_URL=postgres://elsewhere/db credentials run -- node server.jsedit decrypts to a private temp file (mode 0600, deleted afterwards even
on ^C), opens $VISUAL or $EDITOR, validates the result, and re-encrypts.
Editors that need flags work too:
EDITOR="code --wait" credentials editIf the editor exits nonzero or the content is invalid, nothing is saved.
- AES-256-GCM with a random 96-bit IV per save; the GCM auth tag detects wrong keys and tampering
- master key: 32 random bytes, hex-encoded (64 chars) in the key file
- envelope:
NCRED1:<base64 iv>:<base64 tag>:<base64 ciphertext>— a single line of text, friendly to git and code review diffs - not byte-compatible with Rails'
credentials.yml.enc
There is no rotation command yet; the manual recipe:
credentials show > plain.env # 1. decrypt
rm config/master.key config/credentials.env.enc
credentials edit # 2. generates a fresh key; paste plain.env
rm plain.env # 3. clean upnpm install
npm test # vitest
npm run lint # tsc --noEmit + eslint (with prettier)
npm run format # prettier --write
npm run build # vite → dist/cli.js