Encrypting content is easy. Hiding who talks to whom is not.
Notes from designing Orbyte: why metadata is often more sensitive than message content, and the spectrum of defences between 'we encrypt messages' and actual metadata resistance.
This is an in-progress research note, written while building Orbyte. It is not a finished design and it is not advice — it is me working through a problem in public, with the specifics I am still unsure about left honestly marked.
The claim I do not want to make
"End-to-end encrypted" is doing an enormous amount of work in most messenger marketing, and it almost always refers only to message content. The metadata — who you messaged, when, how often, from where, in what pattern — is frequently stored in plaintext, because the server needs some of it to deliver messages at all.
For a lot of threat models, the metadata is the more sensitive half. That a journalist and a source exchanged encrypted messages at 2am, repeatedly, in the week before a story broke, can be damning without a single message body ever being read.
So the interesting design question is not "how do we encrypt the content" — established constructions do that. It is "how little can the server be allowed to know and still deliver a message".
A spectrum, not a checkbox
Metadata resistance is not a property you have or lack. It is a spectrum, and being honest about where a design sits on it matters more than claiming the far end.
- Level 0 — content encrypted, metadata plaintext. The server holds a readable social graph. Most mainstream messengers, whatever the marketing implies.
- Level 1 — identifiers decoupled from real identity. No phone number; accounts are keys. The graph is still visible, but it is a graph of pseudonyms rather than people. This is roughly where Orbyte is now.
- Level 2 — sender identity hidden from the relay. Sealed-sender-style designs, where the server routes a message without learning who sent it. The recipient is still visible to the server.
- Level 3 — both endpoints hidden from any single party. Mix networks, onion routing. Strong, and expensive in latency and complexity — the reason very few messengers actually operate here.
Each level costs something real: discoverability, latency, deliverability, or engineering complexity. Pretending a Level 1 system is Level 3 is worse than being Level 1 honestly, because it changes what users are willing to risk.
What "the server is the adversary" does to a schema
The design constraint I keep returning to is a single question asked of every table: what does a full dump of this reveal?
If the answer is "the complete communication graph with timestamps", the schema is wrong regardless of how well the content is encrypted. That question has already killed several of my own designs before they reached code — which is exactly what it is for.
Design review, every table, no exceptions:
1. If this database is dumped, what does an adversary learn?
2. Which of those columns does delivery *actually* require in the clear?
3. Can the rest move inside the encrypted envelope, or be dropped entirely?
4. What is the shortest retention that still lets delivery work?Retention is the cheapest win and the most overlooked. A queued message removed on delivery, and expired on a timer if never delivered, is data that simply is not there to be disclosed later. Storage you never kept cannot be subpoenaed, breached, or handed over.
Where I am stuck
The honest part. Sealed-sender designs move sender identity out of the relay's view, but they interact awkwardly with abuse prevention — if the server genuinely cannot tell who is sending, rate-limiting and blocking get much harder. There is real tension between metadata resistance and keeping the system usable, and I do not yet have a design I am happy with.
I also do not want to overstate what I am building. Orbyte is a learning project with a real target, not a tool anyone should trust with their life today. The value for me is that implementing it against a written threat model teaches the shape of these trade-offs in a way that reading about them never did.
The one rule I am sure of
Zero custom cryptography. Standard primitives, standard libraries, no invented algorithms. The interesting and hard problems here are key management and metadata — not the cipher — and inventing your own cipher is the single most reliable way for a project like this to fail quietly and completely.
Related
Building a CTF platform taught me more security than solving CTFs
Running code that is designed to be attacked forces a kind of threat modelling that solving challenges never does. Notes from building Hackuten.
- Web Security
- Research
- Docker
When being offline is the emergency: designing a reliable dead man's switch
Notes from Batelys on building a lone-worker alert system, where availability is a safety property and a missed check-in has to be as loud as a pressed button.
- Research
- Linux
- Architecture
Understand the application before you test it
Scanners find what they were told to look for. The bugs that matter live in the gap between what an application believes about itself and what it actually enforces.
- Web Security
- OWASP
- Methodology

