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
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.
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
localStorageorsessionStorage. 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.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.
What this does not protect against
Stated plainly, because a threat model that omits these is not one.A malicious server serving malicious JavaScript
A malicious server serving malicious JavaScript
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.
A compromised computer
A compromised computer
Malware on your machine with the vault open reads everything. Encryption at rest does not help
here.
Public-key substitution when sharing
Public-key substitution when sharing
Covered above: detectable via fingerprints, not prevented.
A guessed or phished password
A guessed or phished password
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.
Traffic analysis
Traffic analysis
File sizes, timings and access patterns are visible to anyone who can see the traffic reaching
the server, and to the server itself.