Initial design: async single-retrieval encrypted file drop
README covers the pitch and how this differs from flit (synchronous, zero server storage) and zipline (persistent hosting). IMPLEMENTATION covers the crypto scheme (key-in-fragment, same primitives as flit/waste-go), storage shape, and the deletion-race problem — delete-on-first-byte-served is the wrong default (see Firefox Send's history with this exact bug); confirm-then-delete with a TTL backstop is the fix. No code yet — design stage. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
49
README.md
Normal file
49
README.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# wisp
|
||||
|
||||
Short-lived, end-to-end encrypted file sharing. Send a file to someone who
|
||||
isn't online right now — they get a link, they get the file once, and then
|
||||
it's gone. The server never has the ability to read what it's holding.
|
||||
|
||||
## Why
|
||||
|
||||
`flit` already does encrypted file transfer between devices, but it's
|
||||
synchronous — both sides have to be online at the same time for the WebRTC
|
||||
handshake. That's fine for "send this to my other laptop right now," and
|
||||
wrong for "here's a file for you, grab it whenever."
|
||||
|
||||
wisp is the asynchronous counterpart: upload once, the recipient retrieves
|
||||
later, on their own schedule. That async gap is the one thing flit's
|
||||
architecture (zero server storage, direct P2P) structurally can't do — it
|
||||
requires the server to actually hold ciphertext for a while, which is new
|
||||
territory for this project family, not a variant of something already built.
|
||||
|
||||
## What it isn't
|
||||
|
||||
- **Not zipline.** Zipline is persistent link/screenshot hosting — you keep
|
||||
the URL, the file stays. wisp is the opposite: single retrieval, then the
|
||||
file is unrecoverable, by design.
|
||||
- **Not flit.** Flit needs both peers online simultaneously and never stores
|
||||
anything server-side. wisp is deliberately async and requires temporary
|
||||
server-side ciphertext storage.
|
||||
|
||||
## Core model
|
||||
|
||||
1. Sender encrypts the file client-side (symmetric, libsodium secretbox —
|
||||
same primitive flit's browser client already uses).
|
||||
2. Ciphertext uploads to the server. The encryption key never leaves the
|
||||
sender's browser except inside the URL fragment (`#key=...`), which
|
||||
browsers never transmit in HTTP requests. The server only ever sees
|
||||
opaque bytes.
|
||||
3. Sender shares the link through any channel they like.
|
||||
4. Recipient opens the link, downloads the ciphertext, decrypts client-side.
|
||||
5. On successful decrypt, the client sends a short confirmation to the
|
||||
server. Only then does the server delete the blob.
|
||||
6. A TTL (default: a few days) is the backstop for links nobody ever opens,
|
||||
so nothing sits on disk forever.
|
||||
|
||||
Full design, including why "delete on first byte served" is the wrong
|
||||
default, is in [IMPLEMENTATION.md](./IMPLEMENTATION.md).
|
||||
|
||||
## Status
|
||||
|
||||
Design only. No code yet.
|
||||
Reference in New Issue
Block a user