How email authentication works: SPF, DKIM and DMARC explained with real records
Three DNS records decide whether your mail is trusted. Each one answers a different question. Here they are, one at a time, using the exact records Mailbay generates for a new domain.
By Mailbay team, 6 min read
On this page (8)
The problem: anyone can write From
SMTP, the protocol mail servers speak, was designed in 1982 for a network where everyone trusted everyone. Nothing in it stops a server from claiming to send as billing@yourbank.com. Three later standards, all published as DNS records by the domain owner, close that gap. Each answers one question:
- SPF: is this server allowed to send mail for this domain?
- DKIM: was this message signed by the domain, and has it been changed since?
- DMARC: does either of those checks actually vouch for the domain in the From address the reader sees, and what should happen if not?
Since 2024, Gmail and Yahoo require SPF or DKIM from everyone and all three from bulk senders, so these records are no longer optional for an app that sends email.
The records for one domain
When you add acme.com to Mailbay, it generates this plan. These are the real values from our DNS planner, with the DKIM key shortened:
| Type | Name | Value | What it is for |
|---|---|---|---|
| MX 10 | acme.com | mx1.mailbay.dev | Where mail for acme.com is delivered |
| MX 20 | acme.com | mx2.mailbay.dev | The second MX, in case the first is down |
| TXT | acme.com | v=spf1 include:_spf.mailbay.dev ~all | SPF: servers allowed to send for acme.com |
| TXT | mb1._domainkey.acme.com | v=DKIM1; k=rsa; p=MIIBIjANBgkq…IDAQAB | DKIM: the public key that checks signatures |
| TXT | _dmarc.acme.com | v=DMARC1; p=none; rua=mailto:dmarc@mailbay.dev | DMARC: the policy, and where reports go |
| CNAME | bounce.acme.com | bounce.mailbay.dev | Return path: bounces come back to us, SPF aligns |
Here is what each one does, in the order a receiving server uses them.
SPF: who may send
Every SMTP conversation starts with an envelope: MAIL FROM, the address bounces go back to, also called the return path. It is not the From line you see in your mail app. The receiving server takes the domain of the envelope sender, fetches its SPF record and checks whether the connecting IP address is on the list.
acme.com. TXT "v=spf1 include:_spf.mailbay.dev ~all"v=spf1marks the record as SPF. A domain must have exactly one; two SPF records is an error and fails every check.include:_spf.mailbay.devsays “whatever that record allows, I allow”. We list our sending IPs there, so we can add an IP without you touching DNS.~allis a soft fail for everyone else: treat it as suspicious rather than reject outright (-all). With DMARC in place, the soft fail is the safer default while you are still finding every service that sends as you.
Merging, not replacing
Most domains already have an SPF record, for Google Workspace, a CRM or a newsletter tool. Adding a second record breaks both, so Mailbay merges its include into yours, just before the all mechanism and leaving everything else as it was:
before "v=spf1 include:_spf.google.com ~all"
after "v=spf1 include:_spf.google.com include:_spf.mailbay.dev ~all"include costs at least one. A record that already includes five or six services can tip over the limit, which turns every check into a permanent error. If you are close, drop services you no longer use before adding another.One more detail: Mailbay sends with an envelope sender like bounces+eml_01m4…@bounce.acme.com. bounce.acme.com is a CNAME to bounce.mailbay.dev, so SPF is checked against our record there, and the bounce comes back to us with the message id in the address. That is why the return path record is in the plan.
DKIM: was it changed
SPF says nothing about the message itself, and it breaks when mail is forwarded, because the forwarding server's IP is not on your list. DKIM fills that gap with a signature. Before sending, Mailbay hashes the body and a list of headers and signs the result with your domain's private key. The signature travels in a header:
DKIM-Signature: v=1; a=rsa-sha256; d=acme.com; s=mb1;
h=From:To:Subject:Date:Message-ID:...;
bh=<hash of the body>; b=<the signature>The receiver reads d= (the signing domain) and s= (the selector), fetches the public key from mb1._domainkey.acme.com, and verifies. If anyone changed a signed header or a byte of the body on the way, verification fails.
- Each domain gets its own 2048 bit RSA key. The private half is encrypted at rest in our database and decrypted only by the signing path.
- The selector is why two providers can coexist: Google signs with
google._domainkey, Mailbay withmb1._domainkey, and both records sit side by side. - We sign with
d=set to the domain in your From address, which matters for the next step.
DMARC: tie it to the From
Here is the gap the first two leave. A spammer can send from their own server with their own envelope domain and their own DKIM key, pass both checks for spammer.example, and still put From: you@acme.com in the message. DMARC closes it by requiring that a passing check is for the same domain the reader sees.
_dmarc.acme.com. TXT "v=DMARC1; p=none; rua=mailto:dmarc@mailbay.dev"p=is the policy for mail that fails:none(deliver and report),quarantine(spam folder) orreject.rua=is where receivers send daily aggregate reports: which IPs sent as your domain, and whether they passed.
Mailbay starts new domains at p=none, so turning on DMARC never blocks your own mail while you find every service that sends as you. When the reports show only mail you recognise, move to quarantine, then reject. If your domain already has a DMARC record, we keep your policy and add our address next to your existing rua. A domain that publishes p=reject; rua=mailto:reports@example.net ends up with p=reject; rua=mailto:reports@example.net,mailto:dmarc@mailbay.dev.
Alignment, the part people miss
DMARC passes when at least one of SPF and DKIM passes and is aligned: its domain matches the From domain. By default alignment is relaxed, which means the same organisational domain is enough, so bounce.acme.com aligns with acme.com. Strict alignment (aspf=s, adkim=s) needs an exact match.
This is why a common setup fails in confusing ways: SPF passes, DKIM passes, and DMARC still fails, because the service signed with its own domain and used its own envelope domain. Neither check was about you. With Mailbay, DKIM always aligns, and SPF aligns too once the return path record is published, so DMARC holds even when one of them breaks, such as SPF after forwarding.
MX and the return path
The two MX records are not about authentication. They tell other servers where to deliver mail for your domain: the lower number is tried first. If your domain already receives mail at Google or iCloud, Mailbay suggests putting its MX on mail.acme.com instead, so your existing mail keeps flowing; see support@ on your own domain.
Check your own domain
Any terminal can show you what the world sees:
dig +short TXT acme.com # SPF (and other TXT records)
dig +short TXT mb1._domainkey.acme.com # DKIM public key
dig +short TXT _dmarc.acme.com # DMARC policy
dig +short MX acme.com # where mail is delivered
mailbay domain verify acme.com # every record, live; exits 1 until all passFor mail you receive, Mailbay runs the same three checks and stores the results on each message as auth_results, so an agent can refuse to act on a “reset your password” email whose DMARC failed. The record by record setup is in the Domains docs.
Read next
- support@ on your own domain, without Google WorkspaceMost small SaaS products need two or three shared addresses, not a seat per person. Here is how to run support@ on your domain, keep the mail you already have, and answer from a shared inbox or Apple Mail.
- DomainsThe DNS records Mailbay needs, one click setup and verification.
- Why we run our own mail serversMost email APIs are a layer over someone else's sending service. We chose to run the mail path ourselves. Here is what that means, what it costs, and why we think it is worth it.
Join the beta
Mailbay is in private beta and free while the beta runs: inboxes, sending, your own domains and MCP. We invite people in small batches and read every note on the form.