Atmosphere Mail#
A cooperative email reputation layer for atproto. PDS operators pool sending volume and reputation through shared infrastructure, verified by a labeling service that checks DNS configuration and publishes signed attestations to the atproto network.
Starting with transactional email (verification codes, password resets, notifications) to build collective domain reputation, with the long-term goal of making self-hosted personal email viable again.
See atmosphere-mail-vision.md for the full proposal.
Status#
Alpha. The relay, labeler, and admin dashboard are live; the cooperative is accepting its first external members.
- Relay runs at
smtp.atmos.emailwith STARTTLS on 587 and inbound FBL/DSN on 25. - Labeler consumes the atproto firehose via Jetstream and issues
verified-mail-operator+relay-memberlabels. - Every outbound message is dual-signed (
d=<member-domain>for DMARC alignment,d=atmos.emailfor pool-level FBL) and carriesFeedback-ID+X-Atmos-Member-Didfor attribution. - Warming tier caps protect the shared IP during the first 14 days of a new member's lifetime.
- Pool-level FBL registrations: Gmail Postmaster verified, Microsoft
SNDS + JMRP registered, Yahoo CFL verified. Operator-classified
inbound (
postmaster@,abuse@,fbl@, …) forwards to an external inbox for provider authorization flows. See docs/operator-runbook.md for the live status table.
To enroll a new sending domain, visit the enrollment wizard on the relay's admin host. The flow handles atproto OAuth, DKIM keypair issuance, and the DNS records you need to publish.
How it works#
- A PDS operator publishes an
email.atmos.attestationrecord declaring their mail domain and DKIM selectors - The labeler watches the atproto firehose (via Jetstream) for these records
- For each attestation, it verifies:
- Domain control — the operator's DID handle matches the domain, or a
_atproto.<domain>TXT record points to the DID - MX — at least one MX record exists
- SPF — a
v=spf1record exists without+all - DKIM — every declared selector has a
v=DKIM1record - DMARC — a record exists at
_dmarc.<domain>with policy quarantine or reject
- Domain control — the operator's DID handle matches the domain, or a
- If all checks pass, the labeler signs and publishes
verified-mail-operator(and optionallyrelay-member) labels on the operator's DID - Labels are queryable via standard atproto XRPC endpoints (
com.atproto.label.queryLabels,com.atproto.label.subscribeLabels) - A scheduler re-verifies every 24 hours and negates labels if DNS degrades
Lexicons#
The NSID namespace is email.atmos.*, backed by atmos.email. See lexicons/README.md for schemas and open questions.
Building#
go build ./cmd/labeler
Running#
Initialize state directory and signing key:
./labeler -init
This creates ./state/config.json (if missing) and generates a secp256k1 signing key. The labeler's did:key is printed to stdout.
Start the labeler:
./labeler -config ./state/config.json
Configuration#
Copy config.json.example to ./state/config.json. All fields have defaults:
| Field | Default | Description |
|---|---|---|
listenAddr |
:8081 |
XRPC server bind address |
stateDir |
./state |
SQLite database and key storage |
jetstreamURL |
wss://jetstream1.us-east.bsky.network/subscribe |
Jetstream endpoint |
signingKeyPath |
./state/signing.key |
secp256k1 private key (hex) |
reverifyInterval |
24h |
Re-verification frequency |
Config files support comments and trailing commas (hujson).
Testing#
go test ./...
Docker#
docker build -t atmosphere-mail-labeler .
docker run -v ./state:/app/state -p 8081:8081 atmosphere-mail-labeler
Architecture#
cmd/labeler/ Entry point, wiring, graceful shutdown
internal/
config/ hujson config loading
store/ SQLite persistence (labels, attestations, cursor)
label/signer CBOR + secp256k1 label signing, did:key derivation
label/manager Verification orchestration, label create/negate
dns/ MX, SPF, DKIM, DMARC verification (injectable resolver)
domain/ DID-to-domain control verification
server/ queryLabels (HTTP) + subscribeLabels (WebSocket)
jetstream/ Firehose consumer with collection filtering
scheduler/ Periodic re-verification
License#
AGPL-3.0-or-later — see LICENSE
Author#
Scott Lanoue (@scottlanoue.com)