Part 4: A server that cannot read your contact list
Part 4 of a series introducing Mesaĝkesto, a protocol for secure messaging between self-certifying identifiers.
A spam box
A box that accepts anything from anyone is not a mailbox, it's a spam funnel. Anyone who knows your identifier — and identifiers are public, that's their job — can fill your box with garbage, exhaust whatever you're paying for, and drown the messages you want.
So a box has to enforce a rule about who may write to you. And the moment you say that out loud, you appear to have conceded something enormous.
The concession you're expected to make
The obvious way to enforce "only my contacts may write to me" is to tell the box who your contacts are. Upload the list. The box checks the sender against it. Simple, and every system works this way.
Look at what you just handed over. Not the contents of your messages — those are encrypted, and we're all very proud of that. You handed over the social graph: who you know, who you talk to, when you started, when you stopped, how often. Ask an intelligence analyst which they'd rather have and they'll take the graph without hesitating. Contents tell you what was said in one conversation; the graph tells you who someone is — their employer, their doctor, their lawyer, their affair, their source, their organiser, their support group.
This is the piece end-to-end encryption structurally does not protect, and it is not an oversight. If the server is the one enforcing the rule, the server needs to know the rule. You can encrypt every message perfectly and still hand your provider the more valuable half of your privacy, because you asked them to keep the spammers out.
So the question for this post is whether that trade is actually necessary. It isn't.
Authorization without identification
Here's the reframe, and it's the whole post: the box does not need to know who you are in order to know that you're allowed.
Think about how a ticket works. The person at the door of a concert doesn't hold a guest list, doesn't ask for your name, and doesn't learn who came. They check that what you're holding is valid. Admission is decided by possession of something, not by identification of someone — and the venue ends the evening knowing how many people came and nothing whatsoever about who they were (unfortunately this becomes rarely the case as someone found a reason why we should know who you are where you going to a concert but we can change that as well).
That's the shape. Give your contacts tickets. Give the box the ability to check tickets. Don't give it a guest list, because it never needed one.
How it works
The mechanics are almost embarrassingly small. You derive a secret key from your own identity — one that lives on your devices and never leaves them. For each contact you're willing to hear from, you combine that secret with their identifier through a one-way function, which produces a short, random-looking token. Same secret plus same contact always gives the same token; different contact gives a completely unrelated one; and nobody without the secret can go backwards from a token to a contact, or forwards from a contact to their token.
You hand the box the set of tokens. Just the values — no names attached, because there's nothing to attach. To the box it's a bag of random 32-byte strings. Then, when you and a contact introduce yourselves to each other, you give them their token along with everything else you exchange. They attach it to messages they send you. The box checks one thing: is this token in the bag?
Yes, accept. No, refuse.
That's it. Writes are authorized. The graph never left your device. Consider what the box now cannot do, even with full access to its own storage, even under legal compulsion, even if the operator is actively hostile:
It cannot list your contacts. It has hashes of them under a key it doesn't have.
It cannot check a guess. Suspecting a specific person is one of your contacts doesn't help — verifying the suspicion still requires your secret.
It cannot correlate you across boxes. Your token for Ewa and Ewa's other correspondent's token for Ewa are derived from different secrets and look entirely unrelated.
It cannot see the shape of your life. It knows how many tokens you uploaded.
That's the extent of it. The rule is enforced. The knowledge was never transferred. Those turn out to be separable, and almost nothing separates them today.
The sender disappears too
There's an obvious loose end: the message still has to say who it's from, doesn't it?
No. The sender's identity goes inside the encrypted payload, where only the recipient can read it. The envelope the box handles carries the destination and the token, and nothing else about the parties. So the box performs a genuinely strange act: it authorizes a write it cannot attribute. It knows the writer is permitted; it does not know who the writer is. The recipient decrypts, finds the sender's identifier and signature inside, and verifies it against that sender's log from Part 2 — which is where authenticity was always going to be settled anyway.
Two layers, cleanly separated, and it's worth stating them side by side because people conflate them constantly:
The token gates the relay. It answers "may these bytes be stored here?"
The signature settles authorship. It answers "who wrote this?", and only the recipient's client ever asks it.
The box participates in the first question and is deliberately absent from the second. It's a bouncer, not a witness.
The same trick, everywhere
Once you have the pattern, it generalises further than you'd expect. Groups. Give a group's members a shared token derived from something only members hold. Every member computes the same token; the relay checks it before storing a message; the relay hosts a group it cannot enumerate. It knows there is a conversation and how much traffic it carries — not who is in it.
Your other devices. Your laptop is a delegated identity, distinct from your phone (Part 2). Under a name-based rule it would have to be separately enrolled everywhere, forever. Under a token rule, it derives the same token from the same identity secret and is simply allowed. Adding a device becomes a local act.
Drop points. Publish a token deliberately — on a website, on a business card — and you have an address strangers can write to without you publishing a list, without an account, and without the box learning who responded. Revoking it later is one entry removed from a bag.
Presence. Even "who can see that I'm online" is a set of tokens. The box routes the signal without knowing whom it's hiding you from. Same primitive each time: a set the box can test membership in, and nothing else.
What this does not do
The uncomfortable part, in full, because a capability is not a magic wand. A token authorizes whoever holds it. It proves permission, not identity. Hand your token to someone else and they can write to me as far as the box is concerned — though not as you, because the signature inside is still yours or isn't. It's the same exposure as giving someone your phone number: bounded, recoverable, and a fair trade for the box learning nothing.
Which means the token must be unguessable. If a token is computed from values that aren't really secret — an identifier here, a group name there — then anyone who learns those values can compute it too, and you've built a lock whose key is written on the door. The secret in the derivation has to be a genuine secret, held only by the people the permission is for. This is easy to get subtly wrong, and it's the detail worth being pedantic about.
Revocation is the hard part. Removing a name from a list is instant. Retiring a capability is not: the holder still has it, so you rotate the underlying secret and everyone still authorized re-derives. Between the removal and the rotation there's a window, and closing it properly needs the box's cooperation — dropping the retired entry the moment it's told to. Doable, but it's real work, and any honest description of capability systems says so.
Volume is still visible. The box can't see who writes to you, but it counts what arrives. Traffic analysis doesn't need names to be informative.
Why it's worth the trouble
Because the alternative is a promise, and promises are the wrong tool. A provider who holds your contact list may be entirely trustworthy today. They still hold it during the acquisition, during the change of jurisdiction, during the breach, during the subpoena, and during the quarter when the business model changes. Every safeguard around it is a policy — reviewable, revisable, overridable — protecting data that didn't have to exist.
A provider who holds a bag of one-way tokens has nothing to hand over when asked, nothing to lose in a breach, and nothing to monetise in a pivot. Not because they're admirable, but because the protocol never gave them the option. That's the difference between trusting infrastructure and merely surviving it — and it's the same move as Part 2, where verification stopped requiring an authority. Take the knowledge out of the system and no one has to be good.
Next: Channels without a platform — how direct chats, groups and public broadcast feeds all fall out of two questions, and why a channel's name is a hash of the event that created it.