Garland: Exploring the Architecture

Garland: Exploring the Architecture

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.

Garland: Your Keys, Your Files, No Trusted Third Partyby Max

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 encryption

Data Flow

Saving Files

  1. User modifies files locally
  2. Cryptomator encrypts to .c9r format (32 KiB chunks, AES-256-GCM)
  3. Each .c9r uploads to Blossom as a blob
  4. Build manifest: { path: "/photos/dog.jpg", blob: "sha256:abc...", size: 524288 }
  5. NIP-44 encrypt manifest + vault config with nsec
  6. Publish to Nostr relays

Recovery

  1. Fetch Nostr events with nsec
  2. NIP-44 decrypt to get manifest + vault config
  3. Fetch blobs from Blossom servers listed in manifest
  4. Unlock vault with nsec (+ passphrase)
  5. 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

  1. Blossom backend for yombar - Upload/download encrypted files as blobs
  2. Nostr manifest layer - Store file tree + blob locations in events
  3. 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.c9r

We 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.