SMTP가 가진 40년간의 설계 결함을 해결하기 위해, HTTP 기반의 차세대 이메일 프로토콜(HMTP)을 구성하는 방법을 다룬 글입니다. Mastodon, Signal, Git 등에서 이미 검증된 최신 웹 기술과 암호화 표준들을 조합하여, DNS 없이도 유연한 사용자 위임과 키 로테이션, 종단 간 암호화를 지원하는 시스템 구축 방식을 제안합니다.
번역된 본문
SMTP가 40년 동안 짊어져 온 설계 결함들을 수정하여 HTTP 기반에서 이메일의 후속작을 설계해 봅시다. 조각조각 뜯어보면서 말이죠. 목표는 (절대 그래선 안 되겠지만!) 현재의 메일 시스템을 대체하는 것이 아니라, 학습하고 즐기며, 전송, 수신, 게이트웨이, 키 등 모든 요소를 교체할 수 있는 현재의 기술들을 탐구하는 것입니다. 이 시스템은 Gmail이나 기존의 어떤 이메일 제공자와도 대화하지 않으며 오직 자기 자신과만 통신합니다. 우리가 유지할 유일한 것은 주소의 형태인 user@domain 뿐입니다. 나머지는 모두 새로 발명됩니다.
HTTP 기반의 메일 시스템이므로, 이 프로토콜의 좋은 이름은 HMTP(Hypertext Mail Transfer Protocol)가 될 것입니다. (SMTP에서 '단순함'을 뜻했던 S 자리를 HTTP의 H가 차지하게 됩니다.) 이제 기술 스택을 준비해 볼 시간입니다. HTTP, TLS, WebFinger, ActivityPub, Webmention, Ed25519, HPKE, sigchains 등이 필요합니다.
부품 명세서 (Bill of materials)
이 설계는 단 하나의 새로운 기술도 발명하지 않습니다. 모든 것이 이미 존재합니다.
문제점 / 기존 기술 / 오늘날 사용자
전송 및 상태 코드 / HTTP / 전체 웹
전송 암호화 / TLS + Let's Encrypt / 전체 웹
사용자 검색 / WebFinger (RFC 7033) / Mastodon 및 Fediverse
메시지 전달 / POST to an inbox (수신함으로 POST) / ActivityPub
출처에서의 발신자 검증 / Webmention 및 DKIM 패턴 / IndieWeb, 모든 이메일
해시를 이용한 참조 방식의 첨부 파일 / 콘텐츠 주소 지정 (Content addressing) / Git, IPFS, Matrix
우리가 사용할 각 부품은 표준화되어 있고 배포되었으며 수백만 명에 의해 대규모로 전장에서 시험(Tested)을 거친 것들입니다. 유일한 새로운 점은 이것들을 '조립(Assembly)'한 것뿐입니다.
HTTP를 선택한 것은 단순한 실용주의가 아닙니다. 이는 어떤 새로운 프로토콜이든 언젠가는 직면해야 할 여러 가지를 시작부터 해결해 줍니다. 가장 먼저 무료로 제공되는 것은 다음과 같습니다:
TLS, 가상 호스팅 및 SNI.
상태 코드(Status codes): 메일 프로토콜에 필요한 카탈로그가 이미 HTTP에 존재합니다. 202 Accepted (전달을 위해 대기 중), 429 Too Many Requests + Retry-After (속도 제어), 404 / 410 (메일함을 찾을 수 없음/삭제됨), 3xx (메일함 이동), 413 (너무 큼) 등입니다. 심지어 유료 안티 스팸 조차 1997년부터 402 Payment Required 라는 코드를 예약해 두었습니다.
기존 인프라: 프록시, 로드 밸런서, Nginx, 모든 언어의 라이브러리. 이 프로토콜은 더 이상 새로운 서버가 아니라 Webmention이나 Micropub처럼 HTTP 위의 규칙(convention)이 됩니다.
이제 다음 단계로 넘어가 봅시다. HTTP를 기반으로 사용자를 어떻게 검색하고, 신원을 확인하며, 메시지를 전달하고, 서명하고 암호화할까요?
1. 검색 및 위임 (더 나은 MX)
위임(Delegation)은 정적 문서 하나로 해결됩니다:
GET https://example.com/.well-known/hmtp/ana
{ "inbox": "https://mail.migadu.example/hmtp/inbox/ana", "keys": { ... }, "devices": [ ... ] }
수신함(inbox)은 다른 호스트에 존재할 수 있습니다. 이것이 바로 MX 레코드지만 DNS를 만질 필요가 없다는 점이 다릅니다. GitHub Pages의 정적 블로그조차도 JSON 파일을 제공함으로써 자신의 메일을 제공자에게 위임할 수 있습니다. 그리고 이는 MX가 결코 하지 못했던 것을 가능하게 합니다. 바로 '사용자별 위임(도메인의 각 메일함이 다른 제공자에 있는 것)'입니다. 우리는 이를 위해 경로조차 새로 발명할 필요가 없습니다. WebFinger (RFC 7033)가 정확히 이 역할을 하며, Mastodon은 이미 이것이 확장 가능함을 증명했습니다.
2. 키 로테이션에서 살아남는 신원 (Identity)
신원(Identity)은 키 자체가 될 수 없습니다. (키는 분실되고 만료되니까요). 신원은 키를 되돌려 확인할 수 있는 무언가(link back)여야 합니다. 두 가지 닻(anchor)을 활용한 제안이 있습니다:
암호학적 연속성: 검색 문서는 현재 키와 갱신(rotation) 체인을 게시합니다. 여기서 각각의 새로운 키는 이전 키에 의해 서명됩니다. 키 N으로 당신을 알던 사람은 누구든 제3자를 신뢰하지 않고도 키 N+1을 검증할 수 있습니다. 이것은 서명 체인(sigchain)으로, ATProto가 DID로 하는 일이거나 Keybase가 과거에 하던 일입니다.
폴백(대체책)으로서의 도메인 제어: 서명된 갱신 없이 키를 잃어버린 경우(예: 노트북 도난), 도메인은 체인 없이 새로운 키를 선언합니다. 단, 이 경우 당신을 알던 서버들이 "신원이 재설정되었습니다..."라는 경고를 표시하는 필수 공지 기간(예: 30일)을 거쳐야 합니다.
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 Existing technology Who uses it today Transport and status codes HTTP The whole web Transport encryption TLS + Let's Encrypt The whole web User discovery WebFinger (RFC 7033) Mastodon and the Fediverse Message delivery POST to an inbox ActivityPub Sender verification at the source The Webmention and DKIM pattern IndieWeb, all of email Signatures Ed25519 SSH, Signal Content encryption HPKE (RFC 9180) MLS, TLS ECH Identity that survives key rotation Sigchains ATProto (Bluesky), Keybase Reading and synchronization JMAP (RFC 8620) Fastmail Push notifications SSE / WebPush Every browser First-contact consent Message requests Signal, Instagram Attachments by reference with hashes Content addressing 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 { "inbox": "https://mail.migadu.example/hmtp/inbox/ana", "keys": { ... }, "devices": [ ... ] } 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 Host: mail.migadu.example Content-Type: application/hmtp+json 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 to your outbox), and it is your server that queues, retries with exponential backoff and honors Retry-After . It's admitting that SMTP's MUA/MSA/MTA separation was right. One of email's quiet strokes of genius is that if the destination server is down, your server retries for days and you forget about it. But let's add an improvement SMTP never had. Every message carries an ID that is the hash of its content, so retries are idempotent. The receiving server deduplicates by ID and the classic "duplicate email because the ACK failed" disappears by construction. The full cycle of a delivery, with the destination node down on the first attempt: sequenceDiagram autonumber participant Ana as Ana's client participant SA as Ana's server participant SB as Bob's server Ana->>SA: POST /outbox (signed message) SA-->>Ana: 202 queued SA->>SB: GET /.well-known/hmtp/bob SB-->>SA: Bob's inbox and keys SA->>SB: POST /hmtp/inbox/bob (envelope + sealed body) Note over SB: down: no response Note over SA: queue: retries with exponential backoff SA->>SB: POST /hmtp/inbox/bob (retry, same id) SB->>SA: GET /.well-known/hmtp/ana SA-->>SB: Ana's signing key Note over SB: signature verified, deduplicated by id SB-->>SA: 201 delivered Notice that the diagram contains the entire protocol: the two GETs to .well-known are discovery and verification, the POST is the delivery, and the queue lives where it should, on the sender's server. 4. Signing and encrypting with the keys we already have The message is a signed object, not loose text: { "id": "sha256:9f2c...", "from": "ana@example.com", "to": ["bruno@example.org"], "date": "2026-07-26T10:00:00Z", "in_reply_to": "sha256:11ab...", "subject": "Re: that idea", "body": { "type": "text/markdown", "content": "<encrypted>" }, "signature": "..." } This buys us a lot of things: Authenticity at rest : stored mail carries its cryptographic proof. A forward keeps the original signature. Forging the sender becomes impossible even through chains of forwards. Sender verification without DKIM : the receiving server GETs the .well-known of the from domain and checks that the key signs. It's the same move as Webmention verification. The proof is fetched at the source. E2E : the discovery document publishes encryption keys (X25519); the body is sealed with HPKE. The envelope (from, to, id, date) stays visible for routing and filtering; the content, only for the recipient. Threads : in_reply_to and references by content hash. Conversations reconstructed without heuristics. Attachments : outside the message. An attachment is {hash, url, size} pointing to the sender's server; the receiver downloads it on demand and their server can mirror it. No more base64 bloating mailboxes. 5. Layered anti-spam Like in any system, this is a complex problem that needs several layers of defense. With HMTP we could start with three: Identity cost : signing as ana@example.com requires serving the key document at example.com . Identity is anchored to a domain, and domains cost money. It's the sybil cost that self-signed identities don't have. However, a doma