Thinking What an Encrypted Server Can and Cannot Know
A plain account of the line between message content and metadata in an end-to-end encrypted messenger, from the operator's side of the console.
"End-to-end encrypted" is a strong claim, and users are right to ask what it leaves out. Running the servers for OvateChat gives me a precise answer, because I can see exactly what our operations console can and cannot show me. This article is that answer, without marketing.
What the server cannot know
Message content, in any form. Text, voice notes, photos, documents up to a gigabyte, reactions, edits: each is encrypted end to end on the sender's device, using keys that were generated on the device and never left it. What arrives at the server is an opaque blob and a destination. The server cannot decrypt it, and neither can I with full access to the database. There is no escrow, no recovery key, no "lawful access" build. When a message has been acknowledged by every device it was addressed to, the ciphertext is deleted; the server does not keep even the unreadable copy.
What the server must know
To deliver a message it must know which account and which devices are the recipients, and that the sender is who they say they are. To keep the service honest it must know which accounts exist, when they signed in, and from where, because without that a breach could never be noticed. This is metadata, and I would rather name it than pretend it does not exist.
Calls: an example of the boundary
A call is a stream of small encrypted signalling messages between two phones: invite, ring, accept, the offer and answer that set up the media path, a trickle of network candidates, hang up. The server relays all of them without reading one. What it can see is their timing and their count. So our console can tell me that a call ran for thirty-one seconds and took thirteen signals, and that one with three signals over fourteen seconds rang out unanswered. It cannot tell me whether a call was declined or simply missed, who spoke, or what was said, because those facts exist only inside the ciphertext. I find that a useful test: if your operator can describe your conversation, it was not end-to-end encrypted.
Designing with the boundary, not around it
Every feature request arrives with a tempting shortcut that needs the server to read something. Search across chats, server-side backups, link previews fetched for you, a contact graph. Each one is possible on the client instead, and each one took us longer that way. The discipline is to treat the boundary as fixed and move the work, not the boundary. A product that respects it ends up with less in its database, which is the point: what you never store cannot be lost, leaked or demanded.
A note on trust
None of this asks you to trust me. It asks you to trust mathematics that has been public for a decade and a client you can inspect on your own device. The job of the operator in this design is small by construction, and that is the best thing I can say about it.