Okay, so….. I did a major oopsie and we’re gonna have to do a significant rewrite of the Cryptid spec as a result of that. I’m writing this post to explain what the problem is and what we’re doing to solve it.
The Problem
One of the fundamental principles of Cryptid is that we treat servers as adversaries. The whole protocol was designed around the idea that servers are just dumb pipes and they know close to nothing about the users connecting to them.
But there was a fundamental contradiction baked into the spec: we were using JWT’s for authentication. (Thanks to @randomscientist for pointing this out to me)
Every authenticated action (sending a message, rotating an address, etc) required a JWT tied to your device. That meant that every time you did anything, the server knew exactly who you were and that you were active. It didn’t matter how carefully we minimized the metadata footprint everywhere else. The authentication layer essentially gave everything up and pointed straight at your device identity. A server operator could trivially reconstruct a detailed picture of when you’re online, who you talk to, and how often you message — exactly the kind of thing we don’t want our servers to know.
This was an architectural mistake that arose from my inexperience with the privacy engineering required here and I reached for a familiar tool without fully thinking about the implications for our threat model. I’m sorry about that, but the good news is that it’s fixable!
What’s Changing
1. Authentication: JWTs → PrivacyPass
We’re replacing JWT-based authentication with PrivacyPass, a cryptographic token protocol that gives us unlinkable authentication. A server can now issue tokens to you and later verify that those tokens are legitimate without being able to link the redemption back to the original issuance.
In practice, this does mean that the server knows that a legitimate device registered and got tokens at some point, but when the tokens are spent to actually do anything, the server can’t tell which device is performing the action. Your activity cannot be linked to your identity.
This also does mean that the progressive trust rate limiting system is going to go away entirely because the server has no way of knowing who anyone is anymore. PrivacyPass token issuance becomes the rate limit now. We’ll need to tune the issuance policy carefully to get a good balance, but honestly, that’s something we can only really figure out once we start building and see how it behaves in practice.
2. Message Format: Double-Encrypted Envelopes
For messages, we’re moving to a double-envelope design:
- CryptidEnvelope (outer): This is all the server ever sees. It literally only contains the recipient’s delivery address and a ciphertext that was encrypted directly to the recipient device’s public key, so the server can’t read anything.
- InnerEnvelope (inner): This is what the recipient sees once they decrypt the outer layer. It contains additional routing context, metadata, and the actual MLS ciphertext.
The server’s job is now reduced to: “look at the address, send it an opaque blob, and forget about it”. It learns nothing about the content, nothing about the sender, and nothing about what kind of message it is.
3. Delivery Addresses: Mailbox Keypairs
The current address system has a problem when you replace JWTs with PrivacyPass: while the addresses are pseudonymous and rotatable, proving that an address belongs to you still ties back to your device identity in ways that a server can observe.
We’re replacing this with a Mailbox Keypair system. Each device generates a dedicated Mailbox keypair. Individual delivery addresses are then derived from that keypair (one keypair per address). This gives devices a way to cryptographically prove to a server that they own a mailbox and are entitled to its messages without the server learning which device that is, or being able to link addresses together.
What’s NOT Changing
A lot of the spec actually remains intact, because the problems were concentrated in the authentication and envelope layers, not the core protocol design:
- MLS remains our E2EE foundation. Nothing changes here.
- Two-layer identity (device identity + user identity) stays as-is.
- InfoPackages and the contact exchange model are unchanged.
- Federation protocol architecture is the same, though it will be updated to reflect the new envelope format.
- Moderation architecture stays the same.
- VDF for device announcements stays.
Timeline and What Happens to Existing Implementations
The rewrite will be reflected in the spec incrementally, but the authentication and envelope changes are breaking. I’ll be posting updates here as sections are revised. The first areas to land will be the new authentication model and the envelope format, since those are the foundation everything else rests on.
Thank you for bearing with me through this. Building a privacy protocol correctly is genuinely hard and I’d rather be honest about mistakes and fix them rather than just give it the ol’ landlord special.
The design coming out of this rewrite is going to be significantly stronger and actually deliver on the promises that the current spec makes.