COFFERBorn Between Generals
★ Local-first · Offline by design

Your secrets never leave your machine.

Coffer is a zero-dependency encrypted vault for passwords, private notes, build commands, and API keys. One encrypted file on your own disk. No cloud, no account, no telemetry — encrypted with AES-256-GCM and a key derived from your master passphrase.

AES-256-GCM authenticated encryption scrypt key derivation (N=16384) 127.0.0.1 only · never binds public 0 dependencies
The idea

A vault you actually control

Coffer is a small command-line tool. It keeps everything in a single encrypted JSON file at ~/.secretschmod 600, atomic writes, rotating backups. There is no server to trust and nothing to sync.

🔒

Encrypted at rest

Your master passphrase derives a 256-bit key. The vault is sealed with AES-256-GCM, so tampering or a wrong passphrase is rejected — not silently mis-decrypted.

✈︎

Offline by design

No network calls, ever. The optional serve UI binds 127.0.0.1 only. Nothing is uploaded, backed up to a cloud, or phoned home.

⚠︎

Unrecoverable by design

There is no reset link and no recovery key. If you lose the master passphrase, the data is gone. That is the point — only you can open it.

The crypto model

Honest, boring, standard cryptography

No home-grown ciphers. Coffer uses well-understood primitives from the Node standard library — nothing else.

How a vault is sealed

passphraseYour master secret. Never stored anywhere.
scrypt(N=16384)Derives a 256-bit key from the passphrase + a random salt. Deliberately slow to resist brute force.
AES-256-GCMEncrypts the vault JSON with a fresh random IV. GCM adds an authentication tag.
auth tagVerified on every open. Wrong passphrase or a modified file → decryption is refused.
~/.secretsOne file, chmod 600, atomic writes, rotating backups.

What Coffer never does

no cloudNothing is uploaded or synced. There is no account.
no telemetryNo analytics, pings, or crash reports leave the machine.
no plaintext at restSecrets only exist decrypted in memory while the vault is open.
no recoveryNo backdoor key, no reset. Lost passphrase = lost data.
no public bindserve listens on loopback only.
What goes inside

Four item types

Every item carries a title and tags, plus fields specific to its type.

PASSWORD

Logins

  • username
  • url
  • password
API

API keys

  • service
  • env
  • key
  • url
BUILD

Builds

  • project
  • command
  • url
NOTE

Private notes

  • body
The real tool

A zero-dependency Node CLI

Coffer is one file you run from your terminal. Here is what a session looks like.

$ coffer init
Set a master passphrase (won't echo): ••••••••
✓ vault created at ~/.secrets (chmod 600)

$ coffer add password --title "GitHub" \
    --username kristenslab --url github.com
Password (leave blank to generate):
✓ generated + stored · tags: git,work

$ coffer add api --title "Anthropic (prod)" \
    --service anthropic --env AF
✓ stored

$ coffer search anthropic
api   Anthropic (prod)   [anthropic · AF]

$ coffer serve
→ http://127.0.0.1:7777  (loopback only)

Every verb

Manage the vault entirely from the command line.

initaddlist getsearchedit rmgenpasswd exportimportimport-env servedoctor

gen makes strong passwords · passwd rotates the master key · import-env pulls keys straight from a .env · doctor checks file perms and backups.

Try it — safely

In-browser demo vault

This runs entirely in your browser using the WebCrypto API. Type a passphrase, add a few items, lock it, and try the wrong passphrase to see the vault refuse to open.

Demo Vault LOCKED
This web page stores nothing on any server. All cryptography runs locally via WebCrypto. The encrypted blob lives only in your browser's localStorage and never touches the network. Security note: this browser demo derives its key with PBKDF2-SHA256 because WebCrypto has no scrypt — the real Coffer CLI uses scrypt (N=16384). Same AES-256-GCM sealing.

Try locking, then unlocking with a different passphrase — GCM authentication fails and the vault refuses to decrypt. There is no way around it.