← Projects · 2026-09-30 · Built, not deployed yet

cairn

A self-hosted, browser-only personal file store. Upload from one device, browse and download from another — the server only ever holds ciphertext.

Read the case studyCase study: cairn →
  • Chunked streaming AEAD (libsodium secretstream, XChaCha20-Poly1305, 4MB frames) — built chunked from day one so large files never need a whole-blob format migration later
  • Two separate secrets: a server-checked access password for the front door, and a vault passphrase that never leaves the browser (Argon2id → 256-bit key)
  • Filename, folder path and mimetype live inside a per-file encrypted envelope — the server's database has no plaintext name or path column at all
  • Virtual folders: no folder objects server-side, the tree is derived client-side from decrypted paths
  • Vault key cached per device as a non-extractable WebCrypto wrapping key in IndexedDB, so reopening the tab doesn't mean retyping the passphrase
  • Truncation detection via secretstream's final tag — a download cut short by the network fails loudly instead of yielding a quietly corrupt file
  • SQLite metadata and ciphertext blobs on separate mounts, split by how often each needs backing up

The third answer to “how do I move a file,” next to flit and wisp: flit is realtime and stores nothing, wisp is async and forgets after one retrieval, cairn is the one that keeps things. Many files, many devices, no expiry, browsable like a small personal cloud drive — without a sync engine, sharing permissions or an account system.

It shares its siblings’ crypto posture: everything is encrypted in the browser and the server sees ciphertext, a byte count and a timestamp. The difference is that the files have to survive indefinitely and be big enough to be annoying (video, backups), so the encryption is chunked and streaming rather than whole-blob.

Deliberately not a Dropbox clone. No sync, no sharing links, no multi-user — wisp already owns “share a file with someone.” Rename/move, local caching and thumbnails are not built yet.