Case · Backend · TypeScript
Konvert: notes encrypted in the browser
A one-time note service on TypeScript, Cloudflare Workers and D1: the text is encrypted in the browser (AES-256-GCM), the key lives only in the URL fragment and never reaches the server. A note has a lifetime, an optional password and burns after the first read. A side project.
- TypeScript
- Cloudflare Workers
- D1
- Web Crypto
- Vite
- vitest
- fast-check
- GitHub Actions
01 · How it looks
Screenshots


02 · About
What it is and why
Konvert (paste-vault) is a one-time note service in TypeScript: the backend runs on Cloudflare Workers with a D1 (SQLite) database, the frontend is vanilla TypeScript and Vite with no frameworks. A side project.
The text is encrypted in the browser (AES-256-GCM); the key is generated there too and lives only in the link fragment after #, so the server stores a single ciphertext. D1 was chosen over KV for burn-after-reading: the read and the delete are one transaction, so a note is handed out exactly once.
Limitations
If you lose the link with the key, the note is lost: there is no recovery. The size, creation time and view count are visible to the server, the text length is not masked.
The "exactly one success" test ran on 40 parallel reads in a local D1 emulation and on 12 parallel requests to the live Worker; it is not a proof for any load.
The IP limit is based on CF-Connecting-IP: networks sharing an address hit it sooner, and it does not protect against distributed floods. Expired notes stop being served at once but are physically deleted by a cron job every 30 minutes.
There is no external audit, it is a learning project.
What is inside
- Client-side encryption: a random 256-bit key in the URL fragment, an optional password through PBKDF2 (600k iterations) and HKDF; neither the key nor the password leaves the browser
- A note lifetime from 10 minutes to 7 days, burn after the first read, deletion with a secret token
- API: metadata without spending the note, an atomic read (DELETE ... RETURNING in one batch), cron cleanup of expired notes
- A custom syntax highlighting tokenizer: tokens always join back into the source text
- A strict CSP with no inline code, HSTS, nosniff, an Origin check, a per-IP rate limit, notes are served with noindex and no-store
- 52 automated tests in the workerd runtime: client crypto, fast-check property tests, request schema fuzzing, no key or text in the DB, TTL, delete rights, burn under 40 parallel reads
- A browser scenario over CDP: two independent profiles, burn, password, XSS, TTL, axe without violations
03 · How to run
Run it locally
git clone <repository on request> paste-vault
cd paste-vault
npm install
npm run dev # a local Worker with D1 emulation04 · Code
The repository is private
The source is in a private repository. Message me on Telegram and I will open access.
Request the code