In our previous post we introduced Garland: an S3-style virtual drive over blossom that gives you complete data sovereignty. Every file recoverable with just your nsec.
Today we're sharing an architecture we're considering - and we want your feedback before we commit to it.
The Proposed Stack
- Encryption: Cryptomator (via yombar, the Rust implementation)
- Blob storage: Blossom servers
- State/metadata: Nostr events
The Key Insight
Cryptomator expects a password. We give it your nsec.
Cryptomator runs scrypt on passwords to derive encryption keys - that's designed to slow down brute-force attacks on weak passwords. Your nsec is already 256 bits of entropy, so the scrypt step is overkill. But it's harmless, and it means we can use yombar completely unmodified.
nsec + optional passphrase
↓
Cryptomator password
↓
Standard vault encryptionData Flow
Saving Files
- User modifies files locally
- Cryptomator encrypts to
.c9rformat (32 KiB chunks, AES-256-GCM) - Each
.c9ruploads to Blossom as a blob - Build manifest:
{ path: "/photos/dog.jpg", blob: "sha256:abc...", size: 524288 } - NIP-44 encrypt manifest + vault config with nsec
- Publish to Nostr relays
Recovery
- Fetch Nostr events with nsec
- NIP-44 decrypt to get manifest + vault config
- Fetch blobs from Blossom servers listed in manifest
- Unlock vault with nsec (+ passphrase)
- Decrypt files
That's it. No local database. No device keys. Just nsec.
What Cryptomator Gives Us
| Concern | Solution |
|---|---|
| Chunk encryption | 32 KiB chunks, AES-256-GCM |
| Chunk integrity | AAD binding prevents reordering |
| Filename privacy | AES-SIV encryption |
| Key derivation | scrypt (N=32768, r=8) |
| Vault integrity | HMAC-SHA256 signed JWT |
This is audited cryptography (Cure53, 2017). We don't have to reinvent it.
What We'd Build
- Blossom backend for yombar - Upload/download encrypted files as blobs
- Nostr manifest layer - Store file tree + blob locations in events
- NIP-44 wrapper - Encrypt vault config for relay storage
The encryption code stays untouched. We're adding storage backends, not forking crypto.
File Mapping
Cryptomator normally outputs files to paths like:
d/BZ/R4VZSS5.../ENCRYPTED.c9rWe flatten this. Each .c9r becomes a Blossom blob addressed by hash. The directory structure lives in the Nostr manifest, not in blob paths.
Recovery Guarantees
A user with only:
- Their nsec
- Optional passphrase
- Access to any Nostr relay with their events
- Access to the Blossom servers referenced in manifest
...can recover all files from a fresh device.
What Do You Think?
We're not committed to this approach yet. Some open questions:
- Is reusing Cryptomator the right call, or are we inheriting unnecessary complexity?
- Should chunks be individual Blossom blobs, or is one blob per file simpler?
- Are there edge cases in the nsec-as-password approach we're missing?
If you see holes in this architecture - or have experience with Cryptomator, yombar, or similar systems - we'd love to hear from you. Reach out on Nostr or open an issue on GitHub.
