Skip to main content
Published on

Stop ending up in spam: configuring SPF, DKIM and DMARC on your domain

An explanatory guide to authenticating your email domain: understanding why Apple Mail is stricter than Gmail, putting SPF, DKIM and DMARC in place, and moving from a domain that spams to a domain people trust.

Your sign-in emails arrive perfectly well with your Gmail users… but land in spam for the ones using Apple Mail / iCloud. This guide explains why, and above all how to fix it properly — starting from a real case.

Recently, while putting an application into production, I ran into a classic: the transactional emails (“magic link” sign-in links) were going to spam on Apple Mail, while Gmail accepted them without flinching. Diagnosing and correcting it took me through the whole email authentication chain. Here it all is, explained in a way that anyone can reproduce.

The problem, concretely

You send emails “on behalf of” your domain (no-reply@mydomain.fr), generally through a sending supplier (Brevo, SendGrid, Mailgun, Postmark…). The recipient, for their part, does not know you. Their mail server asks itself a single question:

“This message that claims to come from mydomain.fr — was it really authorised by mydomain.fr? Or is it an impostor?”

Until the answer is a clear and verifiable yes, the message is suspect → spam folder. This is also the mechanism attackers exploit for phishing: impersonating your domain to deceive your customers or your staff. And not every provider sets the bar at the same height: Gmail is tolerant, Apple/iCloud is strict. Hence the “it gets through for some people, not for others” effect.

The good news: “proving that you really are yourself” is done with three DNS records. That is all.

The SPF / DKIM / DMARC trio, with an analogy

Imagine you are sending a parcel (the email) through a courier (Brevo, say). The recipient (the receiving server) wants to be sure that it really comes from you.

SPF — “the list of couriers I authorise”

SPF (Sender Policy Framework) is a list, published in your DNS, of the servers authorised to send mail for your domain. It is the equivalent of telling the doorman: “Only delivery drivers from such and such a company may leave a parcel in my name.”

In practice, a TXT record on your domain:

v=spf1 include:spf.brevo.com ~all

The receiving server looks at the IP delivering the message to it and checks that it is indeed in the list.

One single SPF record per domain. If you already have one, you merge the include: entries into the same line — you do not create a second one (two SPF records = an invalid SPF). This is a point often forgotten during an email migration: the new include: gets added without removing or merging the old one.

DKIM — “the tamper-proof wax seal”

DKIM (DomainKeys Identified Mail) adds a cryptographic signature to the message. The supplier signs each email with a private key; the corresponding public key is published in your DNS. The recipient recalculates the signature: if it matches, that is proof that the message really does come from your domain and has not been altered along the way.

It is the wax seal on the envelope: nobody can forge it without the private key.

In DNS, it looks like CNAME records (with Brevo, two keys):

brevo1._domainkey.mydomain.fr  →  b1.mydomain-fr.dkim.brevo.com
brevo2._domainkey.mydomain.fr  →  b2.mydomain-fr.dkim.brevo.com

DMARC — “the instructions + the check that the name matches”

DMARC (Domain-based Message Authentication, Reporting & Conformance) does two things:

  1. It gives the receiving server an instruction: “If a message claiming to come from me fails the checks, what should you do with it?” → do nothing (none), put it in spam (quarantine), or reject it (reject).
  2. It enforces alignment — and this is the key concept that many people miss.

A TXT record on _dmarc.mydomain.fr:

v=DMARC1; p=quarantine; rua=mailto:reports@mydomain.fr

The concept that changes everything: alignment

You can have SPF and DKIM both “passing”… and still fail DMARC. Why? Because SPF and DKIM check technical things that do not necessarily concern the domain displayed in the From: field.

  • The From: that the user sees (no-reply@mydomain.fr) is what counts for them.
  • But the technical return address (the Return-Path, used by SPF) is often the supplier’s (bounces-xxx@sender-sib.com for Brevo).

DMARC alignment means checking that the domain proven by SPF or DKIM does match the domain in the From:. It is enough for one of the two to be aligned.

In my real case, analysing the headers gave:

spf=pass    smtp.mailfrom=bounces-...@sender-sib.com   ← SPF pass, but the supplier's domain (not aligned)
dkim=pass   header.d=mydomain.fr                     ← DKIM pass AND aligned with my domain
dmarc=pass  header.from=mydomain.fr                  ← so DMARC passes thanks to DKIM

Lesson: it is DKIM aligned with your domain that saves the day in a setup that goes through a supplier. Hence the importance of getting the DKIM keys right.

Diagnose before acting: read the headers

Before touching DNS, you need to look at what is actually happening. Open an email you have received and display its full headers:

  • Apple Mail: View → Message → All Headers (⌘⇧H)
  • Gmail: ⋮ menu → “Show original”
  • Thunderbird: View → Headers → All (or Ctrl+U / ⌘U for the message source)

The same instinct applies to other email clients.

Look for the Authentication-Results line:

Authentication-Results: dmarc.icloud.com; dmarc=pass header.from=mydomain.fr
Authentication-Results: ...; dkim=pass header.d=mydomain.fr
Authentication-Results: ...; spf=pass smtp.mailfrom=...

And Received: tells you the route the message actually took (from gx.d.sender-sib.com = sent through Brevo).

That is what allowed me to understand that, in my case, authentication was already perfect: the spam problem did not come from there, but from reputation. Without reading the headers, I would have “corrected” a problem that did not exist.

Golden rule: you do not configure blind. You read the headers first.

The winning architecture: separate your domains

Here is the choice that simplifies everything else, and the one I recommend:

Domain Use Sent through
mydomain.fr Transactional & marketing emails (notifications, sign-in links, newsletters) A single supplier (Brevo)
mydomain.com Human emails (your work mailbox) Your provider

Why this is powerful:

  • Reputation isolation: if a marketing campaign damages the reputation, it does not affect your business emails, and vice versa.
  • Risk-free DMARC: since mydomain.fr sends only through Brevo, 100% of its traffic is aligned. You can therefore tighten the DMARC policy as far as reject without ever blocking a legitimate email. That is the key point: a single-channel domain is a domain you can lock down.
  • Clarity: each domain has one role, its own dedicated DNS configuration, and simple diagnostics.
  • Less vendor lock-in on a single mixed channel: if you change sending supplier, you do not break human email, and vice versa.

This point complements an email migration: SPF, DKIM and DMARC must be in place from the moment the MX records are switched over, otherwise the new sends go to spam.

The configuration, step by step

Step 1 — Authenticate the domain with your supplier

In Brevo (Senders, Domains & Dedicated IPs → Domains), add your domain. The supplier provides you with the exact records to put in place:

  • a verification code (TXT on @) to prove that the domain is yours;
  • two DKIM keys (CNAME brevo1._domainkey and brevo2._domainkey);
  • possibly a reminder about SPF and DMARC.

Step 2 — Put the records in your DNS

At your registrar / DNS host, create:

# Ownership verification
@                       TXT     brevo-code:xxxxxxxxxxxxxxxxxxxx

# DKIM (both keys)
brevo1._domainkey       CNAME   b1.mydomain-fr.dkim.brevo.com
brevo2._domainkey       CNAME   b2.mydomain-fr.dkim.brevo.com

# SPF (if you do not already have one — only ONE SPF record per domain!)
@                       TXT     v=spf1 include:spf.brevo.com ~all

Go back to the supplier and click “Verify”. DNS propagation can take anywhere from a few minutes to a few hours.

You can check for yourself from the command line (see also the Linux commands cheat sheet):

dig +short CNAME brevo1._domainkey.mydomain.fr
dig +short TXT   _dmarc.mydomain.fr
dig +short TXT   mydomain.fr | grep spf1

Step 3 — DMARC: ramping up gradually

Never go straight to reject. You get there in stages.

Stage 1 — Observe (p=none)

v=DMARC1; p=none; rua=mailto:reports@mydomain.fr

No impact on deliverability: you are simply collecting reports (rua) to check that all your legitimate sends are properly aligned. Stay there for a few days up to two weeks.

Stage 2 — Quarantine (p=quarantine)

v=DMARC1; p=quarantine; sp=quarantine; adkim=r; aspf=r; pct=100; rua=mailto:reports@mydomain.fr

Messages sent unauthenticated “on behalf of” your domain go to spam at the recipient’s end. Since your legitimate traffic is aligned (DKIM), it is not affected. Bonus: this stage unlocks BIMI.

Stage 3 — Reject (p=reject)

v=DMARC1; p=reject; sp=reject; adkim=r; aspf=r; pct=100; rua=mailto:reports@mydomain.fr

The maximum trust signal: impersonations are refused before they even reach the mailbox. This is the end goal for a dedicated transactional domain.

Decoding the DMARC tags

Tag Role Advice
p The domain’s policy nonequarantinereject, in stages
sp Policy for subdomains Match it to p — otherwise your subdomains (mail., marketing.) remain open doors for spoofing
adkim DKIM alignment r (relaxed) is almost always right; s (strict) is more brittle
aspf SPF alignment same, r
pct % of messages the policy applies to 100
rua Where to send the aggregate reports essential for monitoring
ruf Where to send the detailed failure reports optional; without it, the “generate a report if a check fails” option has no effect

The classic trap: leaving sp=none. You protect mydomain.fr but let anyone impersonate anything.mydomain.fr. If no subdomain sends legitimate mail, set sp to the same level as pno risk, extra security.

Document these records in your IT estate inventory: it is a point often missing from IT audits, even though a bad DNS configuration breaks deliverability overnight.

Why Apple is tougher — and the factor everyone forgets

Even with perfect authentication, an email can still slip into spam. Two reasons, at Apple in particular.

The reputation of a brand-new domain

A domain created a few weeks ago has no history at all. Apple/iCloud, being very cautious, prefers to set it aside for as long as it takes to “observe” you. Reputation is built with:

  • time (allow 2 to 4 weeks of regular sending);
  • engagement: when a recipient takes your message out of spam or adds you to their contacts, it learns that quickly (in my headers, a message “rescued” that way already carried X-Apple-Movetofolder: INBOX);
  • consistency of volume (no sudden spike);
  • possibly a dedicated IP at the supplier, if your volume justifies it, so that you no longer suffer the pooled reputation of a shared IP.

BIMI: the trust bonus

BIMI (Brand Indicators for Message Identification) displays your logo next to your emails in the mailboxes that support it (including Apple Mail). This is not only cosmetic: it is a strong trust signal. But BIMI requires at least p=quarantine — which is why tightening DMARC pays off twice over. A bimi=skipped reason="insufficient dmarc" header simply means: “come back when you are at least on quarantine.”

Summary checklist

  • A dedicated domain for transactional/marketing mail, separate from the human domain
  • Domain authenticated with the sending supplier (verification code validated)
  • Two DKIM keys in place and verified (brevo1 / brevo2._domainkey)
  • A single SPF, including the supplier (include:spf.brevo.com)
  • DMARC in place, ramping up gradually none → quarantine → reject
  • sp matched to p (subdomains protected)
  • rua configured and the reports monitored
  • Diagnosis by reading the headers (Authentication-Results) before and after
  • Patience: let reputation build up (2-4 weeks) + encourage engagement
  • Bonus: BIMI once you are on quarantine / reject

In short

Email authentication is not black magic: it is three DNS records that answer a single question — “are you really who you claim to be?”. SPF lists your senders, DKIM signs them, DMARC arbitrates and enforces alignment. The rest — Apple being stricter, spam despite perfect authentication — comes down to reputation, which is built with time and engagement.

The best advice: separate your domains, read your headers before touching DNS, and tighten DMARC in stages. You will move from a suspect domain to a domain people trust — and your Apple users will finally receive your emails where they belong: in their inbox.

To go further on the same ground: migrating email in a crisis, ransomware / phishing prevention, avoiding vendor lock-in, and the monthly partnership to build these checks into the roadmap rather than dealing with them as emergencies.

Go further