Security architecture

The server stores ciphertext. The link carries the key boundary.

Cinderpass is built so encryption and decryption happen in browsers, while the server only stores opaque encrypted blobs and one-time state. The architecture is less about fancy crypto primitives than about keeping the decryption key physically separate from what the server stores.

System surfaces

Three places, three different trust boundaries.

Client-side encryption

Sender browser

  • Generates a fresh random 256-bit AES key with Web Crypto.
  • Encrypts plaintext with AES-256-GCM before upload.
  • Can optionally protect the key fragment with a passphrase.
Ciphertext storage

Cinderpass server

  • Receives ciphertext, IV, note, expiry, and burn state.
  • Never receives plaintext or the raw decryption key.
  • Marks the secret burned on first successful reveal.
Client-side decryption

Recipient browser

  • Reads the `#k` fragment locally from the shared link.
  • Requests the encrypted payload using only the secret ID.
  • Decrypts in-browser after passphrase verification if required.
Data movement

What moves, and what stays separated.

Upload from sender to server
Sender browserCinderpass server
ciphertext + IV + metadata

The plaintext and raw AES key never cross the network.

Shared link between people
SenderRecipient
/secret/abc123#k=random-key

The secret ID points to the stored ciphertext. The `#k` fragment stays in the browser.

Reveal request from recipient to server
Recipient browserCinderpass server
/api/retrieve/:id

Browsers do not send URL fragments in HTTP requests, so the server never sees `#k`.

Key separation

The design works because the two halves stay apart.

Server-visible

  • Secret ID
  • Ciphertext
  • IV
  • Expiry, note, burn status
  • Optional passphrase verifier data

Browser-local only

  • Plaintext before encryption
  • Random 256-bit AES key
  • `#k` URL fragment
  • Recovered plaintext after decryption

Need the full behavior details too?