Skip to content

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:

TypeNameValueWhat it is for
MX 10acme.commx1.mailbay.devWhere mail for acme.com is delivered
MX 20acme.commx2.mailbay.devThe second MX, in case the first is down
TXTacme.comv=spf1 include:_spf.mailbay.dev ~allSPF: servers allowed to send for acme.com
TXTmb1._domainkey.acme.comv=DKIM1; k=rsa; p=MIIBIjANBgkq…IDAQABDKIM: the public key that checks signatures
TXT_dmarc.acme.comv=DMARC1; p=none; rua=mailto:dmarc@mailbay.devDMARC: the policy, and where reports go
CNAMEbounce.acme.combounce.mailbay.devReturn 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=spf1 marks the record as SPF. A domain must have exactly one; two SPF records is an error and fails every check.
  • include:_spf.mailbay.dev says “whatever that record allows, I allow”. We list our sending IPs there, so we can add an IP without you touching DNS.
  • ~all is 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"
SPF allows at most 10 DNS lookups while it is evaluated, and every 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 with mb1._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) or reject.
  • 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

Which part of a message each check looks at, and how DMARC ties them to the From addressIn the messageThe receiver looks upMAIL FROM (envelope)bounces+…@bounce.acme.comSPFTXT at bounce.acme.comDKIM-Signature headerd=acme.com; s=mb1DKIMTXT at mb1._domainkeyFrom headernoreply@acme.comDMARCTXT at _dmarc.acme.comDMARC passes if either is true:SPF passes and bounce.acme.com aligns with acme.comDKIM passes and d=acme.com aligns with acme.com
Each check reads a different part of the message and a different DNS record. DMARC passes when SPF or DKIM passes for a domain that aligns with the From address.

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 pass

For 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.

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.