Encrypted quick notebook
Paste text, code or an image behind a passcode or a short code+PIN; the server stores ciphertext it cannot read and forgets it within 5h18m.
- Stack
- Go, PostgreSQL, WebCrypto, Argon2id
Problem
I want to move a snippet between machines without a messaging app, a cloud drive or trusting the thing in the middle. The requirements are small:
- a passcode is the only credential; no accounts;
- the same passcode from any device opens the same notebook;
- the server never sees plaintext;
- items expire on their own (UI offers only 3m, 8m, 18m, 38m, 1h18m, 2h 38m, 5h18m).
Design
The passcode is stretched with Argon2id in the browser into 96 bytes, split into three keys:
| Key | Purpose | Leaves the browser? |
|---|---|---|
| lookup key | notebookId = SHA-256(lookupKey) names the notebook |
as its hash only |
| auth key | authProof = SHA-256(authKey) authorises writes |
as the proof; server stores SHA-256(authProof) |
| encryption key | AES-256-GCM for every item | never |
A leaked database yields ciphertext plus hashes of hashes: nothing replayable and nothing readable. A compromised running server could delete or overwrite items for notebooks that were open during the compromise window, but not read them.
Trade-off
Two people who choose the same passcode share a notebook. That is inherent to “passcode is the only credential”. The UI enforces a minimum length, offers a generated passphrase and says so plainly.
Status
Design accepted (ADR-0009). Implementation is in apps/notebook-api and
/notes. Threat model: docs/security/notebook-threat-model.md.