Skip to main content
Mauvely Cloud is zero-access: the server stores files it cannot read. This page says precisely what that means, and precisely what it does not. Everything below is a summary of what the product actually does — including the parts where the honest answer is “this is not protected”.

The claim, stated precisely

File contents, file names and MIME types are encrypted in your browser before they are transmitted. No key that opens them is ever sent to Mauvely, derivable by Mauvely, or stored on Mauvely’s servers in a usable form. A complete dump of Mauvely’s database and file storage, with nothing else, decrypts to nothing.

The key hierarchy

Four properties everything else follows from: Your password and your recovery phrase are peers. Two independent wrappings of the same master key. Either opens it, neither reveals the other. There is no third copy and no administrative override, because either would be a key Mauvely holds. Folder keys chain under their parent. Handing someone a folder key gives them that folder and everything beneath it, and nothing above it. Sharing a subtree is one key handed over, not a re-encryption pass. Content keys are separate from folder keys. Renaming, moving and re-sharing rewrap a key and never touch a byte of the file. The master key never changes. A password change re-wraps it; so does generating a new recovery phrase. Both are instant regardless of how much you store, and neither re-encrypts anything.

Why these choices

Your password stopped reaching Mauvely

Your vault key is derived from your account password. If the account system still received that password, it could derive your vault key — and “we cannot read your files” would be false, however good the cryptography underneath. So it does not. Your browser stretches your password and sends the result as its credential. Two separate derivations, two separate salts, from the same password:
  • One produces the credential mauvely.com verifies.
  • One produces your vault key, which never leaves the browser.
Neither can be computed from the other’s output.

File encryption

Files are encrypted in 4 MiB chunks. Two guards matter more than the choice of cipher: Every chunk has a unique nonce, derived from a random per-version base with the chunk’s index in a fixed field. Reusing a nonce under this cipher does not weaken it, it breaks it — so reuse is made structurally impossible rather than merely unlikely. Every chunk is bound to its position: which version it belongs to, which index it is, and how many chunks there are in total. Encryption alone proves a chunk was not edited; it says nothing about whether it is the chunk that belongs here. Without this binding, the server could silently truncate a file, reorder two chunks, or splice in a chunk from another file — and every individual decryption would still succeed. All four of those attacks are covered by tests, along with decryption under the wrong key.

Keys in your browser

  • Keys are imported in a form the browser will not let scripts read back. Injected script could still use a key while your vault is open — unavoidable in a web app — but cannot copy it out.
  • Keys are never put in localStorage or sessionStorage. Those hold plain strings, and a string is exfiltrated in one line. “Trust this device” uses the browser’s key storage instead, the one place a key object can be kept without its bytes ever being available again.
  • Auto-lock after 30 minutes idle drops keys from memory rather than hiding the interface.

The content policy is part of the encryption

Browser-based encryption assumes the code in the tab is the code we shipped. Any origin that can inject a script into the page can read your master key while the vault is open. So Cloud’s content security policy names no host but its own, and every third-party convenience the main site enjoys is given up here: fonts are served from Cloud itself rather than a font CDN, the design system is served from this origin, and there is no analytics, no CDN and no error reporter.

What the server can still see

Encryption hides contents. It does not hide the shape of what is stored, and pretending otherwise would be dishonest. Not visible: file contents, file names, MIME types, thumbnails, folder names, workspace names, message bodies.
The mention list is the one deliberate exception in chat. Everything a message says is ciphertext, but the user ids it tags are stored in the clear — an unread badge has to be countable server-side, and the alternative is downloading and decrypting every message in every workspace to find out whether there is anything new.

Workspaces

A workspace is a folder whose key is wrapped separately for each member, using the same mechanism as sharing with a named person. Its chat is encrypted under a key derived from that same folder key — so exactly the people who can read the files can read the messages, by construction rather than by a permission check.
Removing a member cannot un-know a key they already had. Their wrapped copy is deleted and the server stops serving them immediately, so they lose everything from that point on. But anything they downloaded while a member stays readable to them, and no key management reaches a file already on someone’s disk.Re-keying the workspace on removal would close this, at the cost of re-wrapping for everyone remaining. It is not built.

Sharing with a named person

The file’s key is wrapped to the recipient’s public key. Only their private key opens it, and the server sees only the wrapped result. The weak point is key distribution, not the cryptography. The server hands out the recipient’s public key — so a malicious or compromised server could substitute its own and read everything shared afterwards. Nothing in the protocol prevents this. What the product does instead is make it detectable:
  • Fingerprints are shown in the share dialog and on the Encryption page.
  • A recipient’s fingerprint is pinned at the moment you share.
  • A later change is surfaced loudly.
If you are relying on this against Mauvely itself rather than against an outside attacker, verify a fingerprint out of band. Key transparency is the only thing that closes this properly, and it is not built.

What this does not protect against

Stated plainly, because a threat model that omits these is not one.
The fundamental limit of encryption delivered by a browser. Mauvely could ship a build that captures your password on the next unlock. Nothing in this design prevents that, and no web application can.The mitigations are the strict content policy, no third-party origins, and the fact that such a build would be visible in the code the browser downloads. A native client with a signed binary is a genuinely stronger position, and is planned.
Malware on your machine with the vault open reads everything. Encryption at rest does not help here.
Covered above: detectable via fingerprints, not prevented.
The vault opens for anyone who can supply the password and holds a session. Two-factor authentication on mauvely.com gates the session, and Cloud refuses a session that has not cleared its second factor — but the password itself is the last line.
File sizes, timings and access patterns are visible to anyone who can see the traffic reaching the server, and to the server itself.
Revocation stops future access. It cannot un-know a key someone already holds, and cannot delete what they already downloaded.