Skip to content

nerdgeschoss/encrypted-credentials

Repository files navigation

credentials

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).

Quick start

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.js

The 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 format

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=value per 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 master key

The key is resolved in this order:

  1. MASTER_KEY environment variable
  2. RAILS_MASTER_KEY environment 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)
  3. 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.js

Multiple environments

Pass -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

Overriding credentials at runtime

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.js

Editor

edit 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 edit

If the editor exits nonzero or the content is invalid, nothing is saved.

Encryption details

  • 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

Key rotation

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 up

Development

npm install
npm test            # vitest
npm run lint        # tsc --noEmit + eslint (with prettier)
npm run format      # prettier --write
npm run build       # vite → dist/cli.js

About

Rails-style encrypted credentials for any language, written in TypeScript

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages