Swiss Vault Architecture

Your data is encrypted with a key we don't have

We built the vault. We maintain the vault. But only you have the combination. This is not a policy — it is a technical guarantee.

Your data is encrypted with a key we don't have. We store ciphertext. We return ciphertext. We cannot read it. Not our engineers, not a subpoena, not a breach. Your key lives only in RAM on your machine — never on ours.

How it works

Every piece of data you create — messages, documents, contacts, health metrics, financial data — is encrypted on your VPS before being stored. The encrypted data travels to Cloudflare's infrastructure (D1, R2, Vectorize) for storage and search. The key that makes it readable is held in RAM on your VPS, provided by a Swiss-jurisdiction KMS via mTLS.

Swiss KMS wraps the key. Your VPS unwraps and encrypts. Cloudflare stores ciphertext. Only your VPS decrypts.

The honest caveat: when you use the web portal, your browser connects to your customer subdomain (e.g. handle.mycelium.id) which is proxied through Cloudflare. Cloudflare terminates TLS at their edge, sees the live HTTP traffic, then re-encrypts to your VPS. This is the same architecture every Cloudflare-fronted SaaS uses. Cloudflare is a contractual subprocessor under their standard data processing terms — they cannot access the data you've already stored (it's encrypted), but they can technically see live portal traffic in transit. We disclose this rather than hide it. See the trust model below for the full picture.

Swiss KMS                Your Machine                Our Infrastructure

  KEK-wrapped key             |
        |                     |
  mTLS 1.3 ──────────>  Unwrap KEK
                        Store in tmpfs (RAM)
                              |
                        You write a message
                              |
                        Encrypt with your key
                        (AES-256-GCM)
                              |
                        Ciphertext ─────────>  Store in Cloudflare D1
                                               (cannot decrypt)

                        You read a message
                              |
                        Ciphertext <─────────  Return ciphertext
                              |
                        Decrypt with your key
                              |
                        Plaintext (only on your machine)
      

The technical details

Each record is encrypted with its own unique data encryption key (DEK). That DEK is wrapped by a scope key, which is derived from your master key using HKDF-SHA256. Even if one record's DEK were somehow exposed, no other record is affected.

ComponentSpecification
AlgorithmAES-256-GCM (authenticated encryption)
Key derivationHKDF-SHA256 with scope-specific info strings
Key wrappingAES-KW (RFC 3394) — DEK wrapped by scope key
IV96-bit random per record (never reused)
Auth tag128-bit GCM tag (tamper detection)
Scopespersonal, org, wealth, moms — each derived independently
Master key256-bit (64 hex chars), KEK-wrapped in Swiss KMS, unwrapped on VPS only
Session tokensSHA-256 hashed before storage — D1 breach cannot expose active sessions
API secretsBot tokens and API keys encrypted (AES-256-GCM) in D1 — key names and values both encrypted

What's encrypted

All content that could identify you or reveal your thinking. Metadata fields like tags and entities are also encrypted. Timestamps and volume metrics remain unencrypted for functionality.

DataEncrypted fields
Messagescontent, thinking, tags, entities, entity_summary
Documentscontent, summary, title, tags, entities, metadata
Contactsname, email, phone, company, position, LinkedIn URL
Healthsleep, HRV, heart rate, steps, workouts, mindfulness
Wealthtransaction notes, costs, values, P&L
Agent taskscontext, results
Attachmentstranscripts, file_name, description, metadata
SecretsAPI keys, bot tokens — both key names and values encrypted

How the master key is protected

The master key is the single most sensitive piece of data in the system. Even with the encryption architecture above, if an attacker can read the key from memory or disk, the entire vault unlocks. We've hardened key storage at eight layers — starting with a Swiss-jurisdiction KMS that wraps the key before it ever reaches your VPS.

DefenseWhat it blocks
Swiss KMS via mTLS 1.3Key is KEK-wrapped in Swiss jurisdiction. VPS receives wrapped key, unwraps locally. KMS validates client certificate before release.
Key on tmpfs (RAM-only filesystem)Disk theft, rescue mode, file backups, .env leaks
sodium-native SecureBuffer (mlock'd, MADV_DONTDUMP)Heap snapshots, memory dumps, V8 string interning
Encrypted swap (random key per boot)Swap pages from previous boots become unreadable
Core dumps disabledCrash dumps cannot capture key from memory
ptrace restricted (yama=1)gdb -p <pid> from another shell blocked
Node --inspect blocked at startupDevTools heap snapshots cannot be enabled
PM2 dump.pm2 filtered + scrubbedProcess env serialization cannot leak secrets

The master key is fetched from a Swiss-jurisdiction KMS over mTLS 1.3. The KMS stores the key as a KEK-wrapped blob. On startup, the VPS presents its client certificate, the KMS validates it, and the wrapped key is sent over the mutual TLS channel. The VPS unwraps the KEK locally and stores the result on tmpfs (RAM-only). The key never enters a bash variable, never appears in shell history, never touches a regular file. On reboot the tmpfs is empty and the KMS re-provides the key automatically — no manual re-keying needed. Disk theft and rescue mode can never recover the key.

Residual risk: A root attacker on a running system could still read process memory directly. However, the master key in memory was provided by the Swiss KMS via mTLS — the KMS validates the client certificate before unwrapping. An attacker would need both root access to the running VPS and the ability to impersonate the client certificate to re-obtain the key from the KMS. The split-jurisdiction architecture means that even full compromise of the data VPS does not give an attacker persistent access to the key material.

How the managed service works

When you sign up for Mycelium Managed, we provision and maintain your infrastructure: a VPS running your agents, Cloudflare Workers for storage, and the web portal. We handle updates, monitoring, and uptime.

Your master key is generated during setup. It is KEK-wrapped and stored in a Swiss-jurisdiction KMS, accessible only via mTLS with your VPS's client certificate. The key is unwrapped on your VPS and held in RAM only. It never passes through our systems, our logs, or our databases. We maintain the vault. You hold the only key.

If your VPS needs maintenance or migration, we provision a new one with a new client certificate. The Swiss KMS re-provisions the wrapped key via mTLS. Your data — still encrypted in Cloudflare — becomes readable again automatically. No manual re-keying. We never touch the key.

Tenant isolation

Each customer is fully isolated at every layer. There is no shared state between tenants except operator-level provisioning metadata.

LayerIsolation
D1 databasesPer-tenant database — no shared tables, no cross-tenant queries
Vectorize namespacesPer-tenant namespace — 4-layer defense: CF namespace enforcement, post-fetch filtering + embedding value stripping, metadata filter redundancy, D1 cross-validation
R2 storagePer-tenant path prefix — no shared buckets
Request routingX-Tenant-ID header validated against authenticated token identity — cannot request another tenant's data
Encryption scopesPer-tenant master key — even if isolation fails, data is encrypted with a different key

Search embeddings (BGE-M3 1024D vectors) are stored in Cloudflare Vectorize with per-tenant namespaces. Raw embedding float arrays are never exposed through API responses — mitigating embedding inversion attacks where an attacker attempts to reconstruct plaintext from semantic vectors. Post-fetch filtering strips embedding values before returning results, and metadata filters provide redundant namespace enforcement.

Your master key & recovery code

During setup, a 256-bit master key is generated locally on your device — 64 hexadecimal characters. A short recovery code is derived from it for easier backup. Store both somewhere safe — a password manager, a fireproof box, or split across trusted locations.

Master key
a7f3e901 4bc28d56 e0f1a3c7 9d82b4e6 53c71f08 2da9e4b7 f6018c35 92d7a4e0
Recovery code
MYCEL-A7F3E-4BC28-D56E0-F1A3C
Example only — yours will be unique

Your master key is the 64-character hex string used to encrypt all your data. The recovery code is a shorter derivative for easier backup. Either one can restore access to your data on any new machine. Without them, your data is permanently gone. There is no "forgot password" flow. There is no admin override. There is no backdoor.

What happens when things go wrong

What if Mycelium gets hacked?
The attacker gains access to our codebase and infrastructure. They find encrypted data in Cloudflare D1. Without your master key — which was never on our servers — the data is unreadable. They get ciphertext. That's it.
Your data: safe
What if Cloudflare is compromised?
Stored data is safe. Cloudflare holds your encrypted data in D1 (database), Vectorize (embeddings), and R2 (files). Full access to all three yields only ciphertext. The master key has never been sent to Cloudflare — not as a Worker secret, not as an environment variable, not in any request. Anything stored on disk is unreadable without your key.

Live portal traffic is a different story. While you're actively using the web portal, your browser connects to handle.mycelium.id via Cloudflare's proxy. Cloudflare terminates TLS at their edge and sees the unencrypted HTTP traffic before re-encrypting to your VPS. If Cloudflare were compromised at the edge layer during your session, an attacker could observe the messages and search queries you sent during that session. They could not access your historical data (it's stored as ciphertext), and they could not extract your master key (it never crosses Cloudflare). This is the same trust boundary as every Cloudflare-fronted SaaS.
Stored data: safe. Live portal traffic: visible to Cloudflare in transit (industry-standard subprocessor model).
What if your VPS is compromised?
This is the one real risk. Your master key lives on your VPS in RAM only (tmpfs), provided by a Swiss KMS via mTLS. An attacker with root access to a running VPS could read process memory. However, the key was provided by the Swiss KMS which validates the client certificate before unwrapping — the attacker cannot re-obtain the key without the mTLS certificate. On reboot, the tmpfs is empty and the key must be re-fetched from the KMS. We use hardened Ubuntu images, SSH key-only access, AppArmor profiles, automatic security updates, and per-tenant isolation. For maximum security, self-host on hardware you physically control.
Your data: at risk if attacker gains root on a running system. KMS + mTLS limits persistence.
What if a government demands my data?
We comply with valid legal orders — and hand over what we have: encrypted data we cannot read. We do not have your key. We cannot produce plaintext. This is not a policy decision that could change with new management. It is a technical architecture. The key does not exist in our systems.
We hand over ciphertext. We cannot do more.
What if I lose my recovery phrase and my VPS dies?
Your data is gone. Permanently. The encrypted data still exists in Cloudflare, but without the master key it is indistinguishable from random noise. No one can help you. This is the price of sovereignty — and it is non-negotiable. We will never build a backdoor to make recovery possible, because a backdoor that helps you also helps everyone else.
Your data: unrecoverable. By design.
What if I want to leave Mycelium?
Export your data in plaintext from the portal at any time. Your agents can generate full exports of messages, documents, contacts, and health data. Delete your Cloudflare resources when you're done. Your key, your data, your choice.
No lock-in. Full portability.

What we can and cannot see

DataMycelium (your VPS)Cloudflare (storage)Cloudflare (live portal traffic)
Message content (stored)PlaintextCiphertext
Contact names (stored)PlaintextCiphertext
Document text (stored)PlaintextCiphertext
Health metrics (stored)PlaintextCiphertext
Financial records (stored)PlaintextCiphertext
Master encryption keyIn memory only (from Swiss KMS)Never transmittedNever transmitted
Live chat & portal sessionPlaintext (it's yours)Visible in transit (TLS terminated at edge)
Search queries (live)PlaintextVisible in transit
Passkey assertionsVerified locallyVisible in transit
Session tokensPlaintextHashed (SHA-256)
API secrets / bot tokensPlaintextCiphertext (key names and values)
TimestampsVisibleVisibleVisible
Message counts & volumeVisibleVisibleVisible
Search embeddingsVisibleNamespace-isolated per tenant (vectors, not text; raw values never exposed via API)
Tags & entitiesPlaintext (derived on your VPS)Ciphertext

Stored data is protected. Every piece of vault data is encrypted on your VPS before it ever leaves the box. Cloudflare's storage layers (D1, R2, Vectorize) only ever see ciphertext. The master key is KEK-wrapped in a Swiss KMS and never crosses the wire to Cloudflare — not as a Worker secret, not as an environment variable, not in any request body. Session tokens are stored as SHA-256 hashes, so even a D1 breach cannot expose active sessions. API secrets and bot tokens are stored encrypted with both key names and values as ciphertext. Tags and entities are encrypted fields. If Cloudflare's storage is breached or subpoenaed, the result is encrypted blobs and hashed tokens that neither we nor they can decrypt.

Live portal traffic is the honest caveat. When you load the web portal at handle.mycelium.id, your browser hits Cloudflare first. Cloudflare terminates TLS at their edge using their cert, inspects the HTTP request (this is how their proxy and WAF work), then re-encrypts to your VPS. During an active session, Cloudflare can technically see the messages you type and the queries you run. They are a contractual subprocessor under their standard data processing terms. This is the same trust boundary that every Cloudflare-fronted SaaS — including most banks and most "private" tools — relies on. We disclose it rather than hide it behind diagrams that show end-to-end encryption.

Why we accept this tradeoff. The alternative is to point DNS directly at your VPS's public IP, eliminating Cloudflare from the traffic path entirely. That removes the TLS subprocessor, but it exposes your server's raw IP to the public internet — meaning direct DDoS surface, port scanning, and zero-day exposure with no edge protection. For a single-tenant personal vault on a small VPS, that risk is worse than the privacy gain. We've chosen to keep Cloudflare's edge protection and be honest about what that costs in transit visibility.

What this means in practice. Your historical data, your archive, your years of conversations and documents — all of that is encrypted with a key only your VPS holds. A breach of Cloudflare, a subpoena to Cloudflare, or a rogue Cloudflare employee with full database access cannot read any of it. The remaining surface is the live HTTP traffic during active portal sessions: the same surface every other web app has. We're working on options to shrink even that surface (client-side encryption for chat, end-to-end TLS via direct VPS connections for advanced users) and will document them as they ship.

What's protected, and what isn't

Your vault data (messages, documents, contacts, health, financial records) is encrypted with AES-256-GCM — symmetric cryptography. The master key is generated locally, never transmitted, and never stored on our infrastructure. Key derivation uses HKDF-SHA256. No asymmetric cryptography, no key exchange, no public/private key pairs. Quantum computers running Shor's algorithm have nothing to attack here. The best quantum attack (Grover's algorithm) halves the effective key length to AES-128 equivalent — still 2128 operations, far beyond any foreseeable capability.

The infrastructure uses the same transport security as every other internet service: TLS for HTTPS connections, SSH for server access, elliptic curve signatures for passkey authentication. These rely on asymmetric cryptography that quantum computers will eventually break. This is an industry-wide problem, not specific to Mycelium.

The practical implication: if someone records your encrypted network traffic today and decrypts it with a future quantum computer, they see ciphertext moving between your browser and your server — but that ciphertext is AES-256-GCM encrypted with your master key, which was never in the traffic. The vault contents remain protected even if the transport layer is compromised.

We don't claim the entire system is quantum-proof. The transport layer has the same limitations as everyone else's. What we can say is that your data at rest is encrypted with a stack that has no known quantum vulnerability.

Ready to own your data?

Start with Mycelium Managed or self-host on your own infrastructure.

Get Started