Encrypted Storage
Store encrypted files on Cascade with wallet-derived keys and secure collaboration.
Overview
Cascade stores files publicly by default — any wallet can download a file if they know the action ID. For private data, you can encrypt files client-side before uploading to Cascade. This guide shows how to implement wallet-based encryption using libsodium.
This pattern is used in the Lumera Research Archive for encrypted draft papers with secure collaboration.
Architecture
Dependencies
If using Vite, add this to your config:
Deriving an Encryption Key from a Wallet
Instead of asking users to manage separate encryption passwords, derive a deterministic key from their wallet signature:
Why ADR-036? By signing a fixed message, the same wallet always produces the same signature, which derives the same encryption key. The key is never stored — it is re-derived on demand. Users only need their wallet to decrypt.
Encrypting and Decrypting Files
Uploading Encrypted Files
Files are uploaded as isPublic: true even when encrypted. Cascade's isPublic flag controls access at the SN-API level, but client-side encryption is the real confidentiality mechanism. This ensures the encrypted blob is available for download by any collaborator you share the key with.
Downloading and Decrypting
Sharing with Collaborators
To share an encrypted file, re-encrypt the document key under the collaborator's wallet-derived key:
The collaborator downloads the invitation, decrypts the document key with their wallet, and uses it to decrypt the file.
For a complete implementation of this pattern, see the Research Archive example.