Business . Technology . Strategy

Burner Notes
SECURITY · OPEN SOURCE

Burner Notes

SUN AUG 09 20263 MIN READNORIK DAVTIAN

Some things should only be read once — a database password, a recovery phrase, the door code for the studio. lilsecret is a tiny open-source app for sharing them as sealed drops: the recipient gets one link and a one-time code, and after one read (or three wrong guesses, or a missed deadline) the drop erases itself. It lives at lilsecret.norik.io — and below is the live app itself.

One link, one code, one read

A drop is a handful of plain-text notes in a simple line editor. Nothing fancy — titles, line numbers, and text that stays exactly as typed.

The lilsecret composer — what goes in the drop

Then you pick the burn conditions: how long the reading window stays open once it’s unlocked (immediately up to 30 minutes), and how long an unopened drop survives before it shreds itself (1 to 48 hours). Sealing produces a single-use link plus a six-digit code, or a passphrase the recipient already knows. Relay them through different channels: the link in chat, the code over a call.

Setting the burn conditions

The recipient gets three tries. On the last mistake the drop self-destructs, and every revisit of a dead link gets an honest answer — already opened, expired unread, burned by hand, or self-destructed. Nothing is archived; what remains only says how it ended.

Two halves of one key

The part I care most about: the server cannot read a drop — and neither can anyone who steals its database. Notes are encrypted in the browser before anything travels, and the key is derived from two halves:

key = HKDF( PBKDF2(code, salt) + linkKey )

code    — the 6-digit code or passphrase, relayed by you
linkKey — random bytes living only in the URL fragment (#…)
          browsers never send fragments to servers

The link alone faces a three-attempt limit refereed by the server. The database alone holds ciphertext and a hash — brute-forcing every six-digit code gets you nothing without the link half. Only link + code opens a drop, which is exactly why you send them separately.

A decrypted drop with its reading-window timer running

A server that cannot peek

The whole backend is one zero-dependency Node file: node:http for the API, node:sqlite for storage. Every record is sealed again server-side with a key that lives in a Kubernetes Secret rather than on the volume — a leaked disk snapshot reveals nothing, not even the burn policies. On a successful unlock the payload leaves the server exactly once and is wiped on the spot.

Design first, then a day of building

The app started as a Claude Design canvas — the noir look, the fingerprint waves, every screen from the composer to the flame on the burned page. Implementation kept the design’s markup nearly verbatim and swapped the prototype’s localStorage for the real protocol: PBKDF2, AES-256-GCM, and a verifier hash so the server can referee wrong codes without ever being able to decrypt. Tests run in-process with node:test at ~90% line coverage on the server, and CI ships every deploy to Kubernetes.

Run your own

git clone https://github.com/NorikDavtian/lilsecret.git
cd lilsecret && node server.js --port 8789

MIT licensed. No accounts, no cookies, no trackers. The container listens on 8080, wants a 64-hex STORAGE_KEY secret, and keeps its SQLite file in /data — hand those three facts to your favorite LLM and it will land it on your infra. The README has the full sealing story. And please — don’t use it for shady shit.

Steal My Agentic Playbook

Follow my progress as I ship new builds, orchestrate AI agents, and post field notes from the studio. No spam — just signal.

Norik.io · Business · Technology · Strategy