Modern email can be built from borrowed parts | Andros Fenollosa
Let's design the successor to email on top of HTTP, fixing the design flaws SMTP has been dragging along for 40 years. Piece by piece. The goal is not to replace the current mail system, heaven forbid!, but to learn, have fun and discover current technologies to swap out every element: sending, receiving, gateway, keys, and so on. The system will never talk to Gmail or any classic email provider: it only talks to itself. The only thing we are going to keep is the shape of the addresses, user@domain. Everything else gets reinvented.
Since it is a mail system over HTTP, a good name for the protocol would be HMTP: Hypertext Mail Transfer Protocol (the S for Simple in SMTP gives up its seat to the H for HTTP).
Now it's time to prepare the tech stack: HTTP, TLS, WebFinger, ActivityPub, Webmention, Ed25519, HPKE, sigchains, etc.
The bill of materials
This design doesn't invent a single technology: everything already exists.
Problem<br>Existing technology<br>Who uses it today
Transport and status codes<br>HTTP<br>The whole web
Transport encryption<br>TLS + Let's Encrypt<br>The whole web
User discovery<br>WebFinger (RFC 7033)<br>Mastodon and the Fediverse
Message delivery<br>POST to an inbox<br>ActivityPub
Sender verification at the source<br>The Webmention and DKIM pattern<br>IndieWeb, all of email
Signatures<br>Ed25519<br>SSH, Signal
Content encryption<br>HPKE (RFC 9180)<br>MLS, TLS ECH
Identity that survives key rotation<br>Sigchains<br>ATProto (Bluesky), Keybase
Reading and synchronization<br>JMAP (RFC 8620)<br>Fastmail
Push notifications<br>SSE / WebPush<br>Every browser
First-contact consent<br>Message requests<br>Signal, Instagram
Attachments by reference with hashes<br>Content addressing<br>Git, IPFS, Matrix
Every piece we are going to use is standardized, deployed and battle-tested at scale by millions of people; the only new thing is the assembly.
Choosing HTTP is not just pragmatism. It solves, right out of the gate, several things any new protocol would have to build at some point:
TLS, virtual hosting and SNI : for free.
Status codes : the catalog a mail protocol needs already exists in HTTP. 202 Accepted (queued for delivery), 429 Too Many Requests + Retry-After (rate control), 404/410 (mailbox unknown/gone), 3xx (mailbox moved), 413 (too large). Even paid anti-spam has had a code reserved since 1997: 402 Payment Required.
Existing infrastructure : proxies, load balancers, Nginx, libraries in every language. The protocol stops being a new server and becomes a convention over HTTP, like Webmention or Micropub.
Let's move to the next level: how do we discover a user, verify their identity, deliver the message, sign it and encrypt it, all over HTTP?
1. Discovery and delegation (a better MX)
Delegation is solved with a static document:
GET https://example.com/.well-known/hmtp/ana<br>"inbox": "https://mail.migadu.example/hmtp/inbox/ana",<br>"keys": { ... },<br>"devices": [ ... ]<br>The inbox can live on another host: that is the MX record, but without touching DNS. A static blog on GitHub Pages can delegate its mail to a provider by serving a JSON file. And it allows something MX never did: per-user delegation (each mailbox of a domain on a different provider). We wouldn't even need to invent the route: WebFinger (RFC 7033) does exactly this, and Mastodon has already proven it scales.
2. Identity that survives key rotation
Identity cannot be a key (they get lost, they expire); it has to be something that keys back. A proposal with two anchors:
Cryptographic continuity : the discovery document publishes the current key and a chain of rotations, where each new key is signed by the previous one. Anyone who knew you with key N can verify key N+1 without trusting anybody. It's a sigchain, what ATProto does with DIDs or what Keybase used to do.
Domain control as a fallback : if you lose the key without a signed rotation (your laptop gets stolen), the domain declares a new key without a chain, with a mandatory announcement period (say 30 days) during which the servers that knew you show the warning "identity re-anchored by domain, not by signature".
However, domain-anchored identity has its own Achilles heel: a domain is not owned, it is rented. If you stop paying, it expires and someone registers it, the new owner publishes their keys in your .well-known and from that moment on they receive your mail and sign as you. Nobody can tell the legitimate heir from the squatter. It's the problem ATProto tries to solve by separating identity from the domain with DIDs, at the price of another piece of infrastructure. We know it's a real problem with a known solution. Now let's move on.
3. Delivery with a queue (store-and-forward)
Delivery is a POST to the recipient's inbox:
POST /hmtp/inbox/ana HTTP/1.1<br>Host: mail.migadu.example<br>Content-Type: application/hmtp+json<br>The key is not the request, it's who makes it. Your client doesn't deliver directly to the recipient, but to your own server (an authenticated POST...