penguina blog notes from the build

Sealed at rest: how drop and photos store what you hand them

Files land in our sharing and photo apps encrypted from the first byte, in a format that streams, seeks, and fails closed instead of serving damage.

Two apps, one promise

Two of our apps hold things that are nobody else's business. drop is where the household sends files to each other and out into the world — tax documents, scans, the occasional enormous video. photos gives every account its own photo library, imported and browsed privately.

Using them feels ordinary: upload, browse, share, download. The promise sits underneath — on disk, none of it is readable. Every file is encrypted the moment it lands, and nothing is ever stored in the clear.

What "at rest" actually protects

Drives don't live forever. They get replaced, sent back under warranty, resold, or fail in ways that make a confident wipe impossible. Backups multiply copies into places you stop thinking about. And a server that runs many programs has many potential readers of the same storage.

Encryption at rest means the drive can leave without the data leaving. A disk pulled from the machine holds sealed chunks and nothing else.

It's one layer of three, and we try to be honest about that. Sign-in decides who may ask for a file at all. Encrypted transport protects it on the way to you. At-rest encryption protects the sleeping copy. None of the three substitutes for the others.

Sealed in chunks, not in one piece

We didn't encrypt each file as one big blob. Files are sealed in small chunks, each independently encrypted and authenticated with AES-256-GCM. Three useful properties fall out of that shape:

  • Constant memory. A file streams through the sealer a chunk at a time, so a giant video costs no more memory than a text note.
  • Verify before serve. Every chunk proves its integrity before a single byte of it is released. A tampered or truncated file fails closed mid-stream — the app refuses, rather than quietly serving damaged bytes and hoping.
  • Seeking still works. Resuming a download or jumping to the middle of a video doesn't mean decrypting from the top. We skip straight to the chunks the request touches.
A sealed file should still behave like a file: streamable, seekable, and honest about damage.

Each chunk's number is baked into its seal, along with a marker on the final chunk — so chunks can't be reordered and a file can't be silently shortened. The file's own header is bound into the seal too, so metadata can't be swapped out from under the contents.

Every file gets its own key

The master key never encrypts a single byte of anyone's data. Each file gets a fresh key, derived from the master key and a random value chosen at sealing time. Compromising one file's key tells you nothing about the next file, and the master key itself only ever exists to derive.

The master keys live outside the apps entirely and are backed up in more than one place — never in the code, never inside the containers that run the apps.

The uncomfortable part, on purpose

If a master key were ever truly lost, the library it seals would be gone. There is no recovery path, because a recovery path is a back door with better marketing. We treat the keys with the care that design demands, and we'd rather carry that weight than pretend a skeleton key is safe.

Small print we like

Uploads to drop are scanned for malware before they're sealed, not after. Photo libraries are per person — encryption doesn't blur ownership, and one account's library is never another's to browse. And files land on disk with tight permissions even before the seal closes around them.