El email moderno se puede montar con piezas de otros
Vamos a diseñar el sucesor del email sobre HTTP, arreglando los fallos de diseño que SMTP arrastra desde hace 40 años. Pieza por pieza. El objetivo no es sustituir el sistema actual de correo, ¡Dios me libre!, sino aprender, divertirnos y descubrir tecnologías actuales para reemplazar cada elemento: enviar, recibir, pasarela, claves, etc. El sistema nunca se entenderá con Gmail ni con ningún proveedor de correo clásico: solo habla consigo mismo. Lo único que vamos a conservar es la forma de las direcciones usuario@dominio. Todo lo demás se reinventa.
Como es un sistema de correo sobre HTTP, un buen nombre para el protocolo sería HMTP: Hypertext Mail Transfer Protocol (la S de Simple de SMTP cede su sitio a la H de HTTP).
Ahora toca preparar el stack tecnológico: HTTP, TLS, WebFinger, ActivityPub, Webmention, Ed25519, HPKE, Sigchains, etc.
La lista de materiales
Este diseño no inventa una sola tecnología: todo existe ya.
| Problema | Tecnología existente | Quién la usa hoy |
|---|---|---|
| Transporte y códigos de estado | HTTP | Toda la web |
| Cifrado de transporte | TLS + Let's Encrypt | Toda la web |
| Descubrimiento de usuarios | WebFinger (RFC 7033) | Mastodon y el Fediverso |
| Entrega de mensajes | POST a un inbox | ActivityPub |
| Verificación del remitente en origen | El patrón de Webmention y DKIM | IndieWeb, todo el email |
| Firmas | Ed25519 | SSH, Signal |
| Cifrado del contenido | HPKE (RFC 9180) | MLS, TLS ECH |
| Identidad que sobrevive a rotar claves | Sigchains | ATProto (Bluesky), Keybase |
| Lectura y sincronización | JMAP (RFC 8620) | Fastmail |
| Notificaciones push | SSE / WebPush | Todos los navegadores |
| Consentimiento en primer contacto | Message requests | Signal, Instagram |
| Adjuntos por referencia con hash | Content addressing | Git, IPFS, Matrix |
Cada pieza que vamos a usar está estandarizada, desplegada y probada a escala por millones de personas; lo único nuevo es el ensamblaje.
Elegir HTTP no es solo pragmatismo. Resuelve de saque varias cosas que cualquier protocolo nuevo tendría que montar en algún momento:
- TLS, virtual hosting y SNI: gratis.
- Códigos de estado: el catálogo que necesita un protocolo de correo ya existe en HTTP.
202 Accepted(entregado a cola),429 Too Many Requests+Retry-After(control de ritmo),404/410(buzón inexistente/desaparecido),3xx(buzón mudado),413(demasiado grande). Hasta el anti-spam de pago tiene código reservado desde 1997:402 Payment Required. - Infraestructura existente: proxies, balanceadores, Nginx, librerías en todos los lenguajes. El protocolo deja de ser un servidor nuevo y pasa a ser una convención sobre HTTP, como Webmention o Micropub.
Pasemos al siguiente nivel: ¿cómo descubrir a un usuario, verificar su identidad, entregar el mensaje, firmarlo y cifrarlo, todo sobre HTTP?
1. Descubrimiento y delegación (un MX mejor)
La delegación se arregla con un documento estático:
GET https://example.com/.well-known/hmtp/ana
{
"inbox": "https://mail.migadu.example/hmtp/inbox/ana",
"keys": { ... },
"devices": [ ... ]
}
El inbox puede vivir en otro host: eso es el registro MX, pero sin tocar DNS. Un blog estático en GitHub Pages puede delegar su correo a un proveedor sirviendo un JSON. Y permite algo que MX no permite: delegación por usuario (cada buzón de un dominio en un proveedor distinto). De hecho no haría falta inventar ni la ruta: WebFinger (RFC 7033) hace exactamente esto y Mastodon ya demostró que escala.
2. Identidad que sobrevive a la rotación de claves
La identidad no puede ser una clave (se pierden, caducan); tiene que ser algo que las claves respaldan. Propuesta de dos anclas:
- Continuidad criptográfica: el documento de descubrimiento publica la clave actual y una cadena de rotaciones, donde cada clave nueva va firmada por la anterior. Quien te conocía con la clave N puede verificar la N+1 sin confiar en nadie. Es una sigchain, lo que hace ATProto con los DIDs o lo que hacía Keybase.
- Control del dominio como respaldo: si pierdes la clave sin rotación firmada (te roban el portátil), el dominio declara una clave nueva sin cadena, con un periodo de anuncio obligatorio (digamos 30 días) durante el cual los servidores que te conocían muestran la advertencia "identidad reanclada por dominio, no por firma".
Sin embargo la identidad anclada al dominio tiene su propio talón de Aquiles, y es que un dominio no se posee, se alquila. Si dejas de pagarlo, caduca y alguien lo registra, el nuevo dueño publica sus claves en tu .well-known y desde ese momento recibe tu correo y firma como tú. Nadie tiene forma de distinguir al heredero legítimo del okupa. Es el problema que ATProto intenta resolver separando la identidad del dominio con DIDs, al precio de otra pieza de infraestructura. Sabemos que es un problema real y tiene una solución conocida. Ahora sigamos.
3. Entrega con cola (store-and-forward)
La entrega es un POST al inbox del destinatario:
POST /hmtp/inbox/ana HTTP/1.1
Host: mail.migadu.example
Content-Type: application/hmtp+json
La clave no es la petición, es quién lo hace. Tu cliente no entrega directamente al destinatario, sino a tu propio servidor (un POST autenticado a tu outbox), y es tu servidor quien encola, reintenta con backoff exponencial y respeta los Retry-After. Es admitir que la separación MUA/MSA/MTA de SMTP era correcta. Una genialidad silenciosa del email es que si el servidor destino está caído, tu servidor reintenta durante días y tú te olvidas.
Pero añadamos una mejora que SMTP nunca tuvo. Cada mensaje lleva un ID que es el hash de su contenido, así que los reintentos son idempotentes. El servidor receptor deduplica por ID y el clásico "correo duplicado porque falló el ACK" desaparece por construcción.
El ciclo completo de una entrega, con el nodo destino caído en el primer intento:
sequenceDiagram
autonumber
participant Ana as Cliente de Ana
participant SA as Servidor de Ana
participant SB as Servidor de Bob
Ana->>SA: POST /outbox (mensaje firmado)
SA-->>Ana: 202 encolado
SA->>SB: GET /.well-known/hmtp/bob
SB-->>SA: inbox y claves de Bob
SA->>SB: POST /hmtp/inbox/bob (sobre + cuerpo sellado)
Note over SB: caído: sin respuesta
Note over SA: cola: reintenta con backoff exponencial
SA->>SB: POST /hmtp/inbox/bob (reintento, mismo id)
SB->>SA: GET /.well-known/hmtp/ana
SA-->>SB: clave de firma de Ana
Note over SB: firma verificada, deduplicado por id
SB-->>SA: 201 delivered
Fíjate en que el diagrama contiene el protocolo entero: los dos GET al .well-known son el descubrimiento y la verificación, el POST es la entrega, y la cola vive donde debe, en el servidor del emisor.
4. Firmar y cifrar con las claves que ya tenemos
El mensaje es un objeto firmado, no texto suelto:
{
"id": "sha256:9f2c...",
"from": "ana@example.com",
"to": ["bruno@example.org"],
"date": "2026-07-26T10:00:00Z",
"in_reply_to": "sha256:11ab...",
"subject": "Re: aquella idea",
"body": { "type": "text/markdown", "content": "<cifrado>" },
"signature": "..."
}
De este modo ganamos muchas cosas:
- Autenticidad en reposo: el correo almacenado lleva su prueba criptográfica. Un reenvío conserva la firma original. Falsificar el remitente se vuelve imposible incluso en cadenas de reenvíos.
- Verificación del remitente sin DKIM: el servidor receptor hace GET al
.well-knowndel dominio delfromy comprueba que la clave firma. Es el mismo movimiento que la verificación de Webmention. La prueba se busca en la fuente. - E2E: el documento de descubrimiento publica claves de cifrado (X25519); el cuerpo va sellado con HPKE. El sobre (from, to, id, fecha) queda visible para enrutar y filtrar; el contenido, solo para el destinatario.
- Hilos:
in_reply_toyreferencespor hash de contenido. Conversaciones reconstruibles sin heurísticas. - Adjuntos: fuera del mensaje. Un adjunto es
{hash, url, size}apuntando al servidor del remitente; el receptor lo descarga bajo demanda y su servidor puede espejarlo. Se acabó el base64 inflando buzones.
5. Anti-spam por capas
Como cualquier sistema, es un problema complejo que requiere varias capas de defensa. Con HMTP podríamos empezar con tres:
- Coste de identidad: firmar como
ana@example.comexige servir el documento de claves enexample.com. La identidad está anclada a un dominio, y los dominios cuestan dinero. Es el coste sybil que las identidades autofirmadas no tienen. Sin embargo, un dominio da subdominios y buzones infinitos, así que el coste frena la creación masiva de identidades independientes, no de direcciones. Trabajamos a nivel de raíz. - Consentimiento en primer contacto: un remitente desconocido no entra al buzón; entra a una bandeja de "solicitudes" con su primer mensaje visible (como los message requests de Signal). Aceptas y el hilo se abre para siempre. Un desconocido puede llamar a tu puerta, que es la propiedad esencial del correo, pero no puede llenarte el salón.
- Franqueo opcional para desconocidos: el servidor puede responder al primer contacto con
402. Configurable por buzón; el coste de spamear en frío deja de ser cero.
6. La lectura también se especifica
El email estandarizó el envío (SMTP) y la lectura (IMAP/POP) como mundos separados. Nosotros no necesitamos inventar nada: leer, sincronizar y buscar buzones sobre JSON/HTTP ya está resuelto y estandarizado por el IETF. Se llama JMAP. HMTP definiría la entrega; la lectura es JMAP con un tipo de objeto nuevo. Push al cliente con SSE o WebPush. El ciclo completo (enviar, entregar, leer, sincronizar) queda sobre HTTP.
La conclusión
Cada problema del correo tiene una solución desplegada y funcionando: el descubrimiento en Mastodon, la entrega en ActivityPub, la verificación en el IndieWeb, la identidad rotable en Bluesky, la lectura en Fastmail, el consentimiento en Signal. Una actualización del correo ya existe, pero nadie la ha ensamblado.
Solucionamos muchos problemas con soluciones elegantes y modernas:
- Reputación y permiso social (SPF, DKIM, DMARC, PTR inverso, listas negras, meses de calentar una IP): sustituido por verificación criptográfica en cada mensaje, una firma y un GET al
.well-knowndel remitente. Una propiedad que se verifica no necesita reputación. - Suplantación del remitente: imposible por construcción. El receptor comprueba la firma contra la clave publicada en el dominio del
from, y la firma viaja con el mensaje incluso reenviado. - Delegación del correo (el registro MX): un documento estático en
.well-known, con delegación por usuario y sin tocar DNS. - Privacidad del contenido (el PGP que nadie llegó a configurar): cifrado de extremo a extremo por defecto; el servidor receptor almacena un cuerpo que no puede leer.
- Spam (filtros estadísticos a posteriori): consentimiento en primer contacto (los desconocidos llaman a la puerta, no entran al buzón), identidad con coste anclada al dominio y franqueo opcional con
402. - Duplicados por reintento: el id del mensaje es el hash de su contenido, así que los reintentos son idempotentes y el receptor deduplica por construcción.
- Hilos reconstruidos con heurísticas:
in_reply_toapunta al hash del mensaje padre; la conversación es un grafo verificable. - Buzones ligeros: adjuntos por referencia (hash + URL), descargados bajo demanda.
- Infraestructura sencilla y conocida: todo viaja por HTTPS estándar, detrás del mismo Nginx y el mismo certificado que ya sirven tu web.
- Rotar claves (la pesadilla operativa de DKIM): un comando. Como nadie fija tu clave, la nueva es confiable al instante y la robada queda inservible igual de rápido.
Hablar es fácil, por ello he implementado un prototipo funcional en Python: github.com/tanrax/hmtp. Todo en un solo archivo. El prototipo cubre el transporte completo: entrega firmada, verificación en origen, cifrado de extremo a extremo, consentimiento en primer contacto, deduplicación, hilos, cola con backoff exponencial y rotación de claves en un comando. Deja fuera, a conciencia, las piezas de la periferia: la cadena de rotaciones firmadas (los receptores consultan tu clave en vivo en cada entrega en lugar de fijarla, así que solo empieza a pagarse cuando los nodos cacheen claves), el franqueo 402, los adjuntos por referencia y la lectura JMAP. El README trae el quickstart (tu primer correo en dos minutos, escribiéndote a ti mismo), una demo de dos nodos intercambiando correo cifrado en tu máquina y la guía de producción completa, del DNS al systemd. Recuerda que es un experimento de diseño con criptografía sin auditar; no lo uses para secretos de los que dependa nadie. Aunque podría ser un sistema ligero de comunicación para el ecosistema que te venga a la cabeza.
Espero que hayas disfrutado el paseo. Y si llegas a enviar tu primer correo con HMTP, me encantaría que me lo contaras.
- La lista de materiales
- 1. Descubrimiento y delegación (un MX mejor)
- 2. Identidad que sobrevive a la rotación de claves
- 3. Entrega con cola (store-and-forward)
- 4. Firmar y cifrar con las claves que ya tenemos
- 5. Anti-spam por capas
- 6. La lectura también se especifica
- La conclusión
This work is under a Attribution-NonCommercial-NoDerivatives 4.0 International license.
Will you buy me a coffee?
This is how I keep writing without ads or paywalls.
Sure, it's on me!
Comments
There are no comments yet.