Skip to content

Flowvault v1.0.0 — First public release

Choose a tag to compare

@flowdeskadmin flowdeskadmin released this 20 Apr 09:19
· 33 commits to master since this release

Zero-knowledge encrypted notepad with plausible deniability. One URL can
hide multiple notebooks behind different passwords, and the server cannot tell
how many notebooks actually exist.


What ships in 1.0

Hidden-volume vaults (the headline)

One URL, up to 64 independently encrypted slots, one opaque 512 KiB blob.
Every vault is exactly the same size on disk regardless of how much you've
actually written, so the ciphertext on the server is cryptographically
indistinguishable from a vault that holds a single decoy paragraph.
Hand over the decoy password at a border crossing; the real notebook stays
invisible.

Multi-notebook tabs per password

Each password now unlocks a workspace, not a single page. Add, rename,
reorder (drag-and-drop), and delete tabs. Tab titles, order, contents, and
the active-tab pointer all live inside the encrypted slot — the server
still sees one opaque blob. Decoy slots keep their own independent tab set.

Time-locked notes (drand + tlock)

Encrypt a message to a future date using drand's public randomness beacon
and identity-based encryption over BLS12-381 (tlock-js). The decryption
key literally does not exist until drand publishes the target round's
signature — we can't unlock it early, a subpoena can't unlock it early,
the sender can't unlock it early. Optional password gate on top
double-wraps the note with Argon2id(password) → AES-256-GCM, so a leaked
link plus elapsed time still isn't enough.

Encrypted Send (Bitwarden-Send-style)

One-shot, self-destructing shares for passwords, API keys, recovery phrases.
AES-256-GCM in the browser; the 256-bit key travels in the URL fragment
(#k=…) so browsers never send it to servers. Configurable view count (1–
100, default 1) and TTL (up to 30 days). Reads go through a Cloud Function
so the view counter is atomic; the server hard-deletes the ciphertext the
moment the last view is consumed. Firestore rules deny client reads of the
send document entirely. Optional password gate available.

Dead-man's switch

Arm a vault to auto-release to a pre-chosen beneficiary password if you
stop saving for the interval + grace you configure (weekly / monthly /
quarterly / yearly). The beneficiary key wraps your master key client-side;
the server just schedules the release. Hourly Cloud Function sweep plus
Firestore rules that forbid faking a release or extending one you can't
actually open.

Optimistic concurrency and conflict recovery

Edit the same vault in two tabs without losing work. Version-counter
transactions on writes; on conflict the client auto-refetches, merges
server state into the local store without dropping your edits, and retries.
Save rejections from the dead-man's-switch released state surface a clear
message instead of a silent promise rejection.

Editor

  • Clean, modern dark-mode UI
  • Keyboard-first: Ctrl/Cmd+S to save
  • Debounced autosave for typing, immediate save for structural tab ops
  • In-editor "Syncing" indicator, visible save status chip, dirty-state
    warning before close
  • Slot capacity meter (bytes used / available, computed across all tabs)
  • Drag-to-reorder tabs with visible borders and active-tab accent

Security

Property Flowvault
Password → key derivation Argon2id, 64 MiB memory-hard, 3 iterations, HKDF-SHA256 expansion
Symmetric encryption AES-256-GCM (authenticated)
Ciphertext size Fixed 512 KiB, independent of content
KDF parameters Stored in vault, upgradable without breaking old vaults
Optimistic concurrency Yes — version-counter transactions
Time-lock drand BLS12-381 IBE via tlock-js
Zero-knowledge firewall Enforced by public, auditable Firestore rules
Tracking / analytics None
Account / email / phone None

Open source, end-to-end

Not just the frontend. The Cloud Functions (dead-man's-switch sweep,
Encrypted Send atomic-view counter, Encrypted Send sweep) and the
Firestore security rules — the actual boundary that stops the operator
from reading or mutating your data — ship in this repo under MIT, deploy
unmodified, and are fully self-hostable.

Threat model

Published and specific. We tell you what we do and do not protect against,
including cases where plausible deniability is weaker (persistent network
observer correlating writes, traffic analysis, endpoint compromise).
See /security.


Deployment & tooling

  • Frontend: Next.js 16 + React 19 + Tailwind 4, deployed to Vercel from
    the master branch.
  • Backend: Firebase Firestore + Functions on the Blaze plan.
  • CI: GitHub Actions — lint, type-check, and build on every push; Firebase
    deploy workflow for Functions + rules + indexes on release tags.
  • SEO: sitemap, robots.txt, FAQ with FAQPage JSON-LD,
    SoftwareApplication / Organization / WebSite structured data, OG +
    Twitter cards, canonical URLs.

Donations

Crypto-only, via NOWPayments. No donor account, no email, fresh address
each donation, 100+ supported coins including Monero. We never see the
donor, only that a donation occurred. See /donate.


Known limitations / not yet shipped

  • PWA / offline — on the roadmap for a subsequent release.
  • Build reproducibility — release-commit bundle-hash publishing is
    planned but not yet automated.
  • Network correlation — a persistent observer of your IP can correlate
    your writes. Route via Tor / a VPN if this matters to you. This is
    fundamental to the threat model, not a v1.0 bug.

Install / self-host

npm install
(cd functions && npm install)

cp .env.local.example .env.local   # fill in Firebase + NOWPayments values

# dev
npm run dev

# ship
npm run build
firebase deploy --only firestore:rules,firestore:indexes,functions