SPF, DKIM and DMARC Explained, and How to Stop Email Spoofing
A developer-friendly walkthrough of SPF, DKIM and DMARC, why p=none still leaves you spoofable, and how to reach enforcement without breaking mail.
Want this checked continuously?
CompleteStatus grades your headers, SSL and email security 24/7 — free, commercial use allowed.
If your domain has no DMARC policy, or one set to p=none, anyone on the internet can send email that appears to come from you. Your customers see billing@yourcompany.com in the From line, and nothing in the message tells them it's a forgery. Exact-domain spoofing like this is a staple of phishing and business-email-compromise attacks.
The fix is three DNS records: SPF, DKIM and DMARC. They work together, and getting them right is an hour of work that pays off for years. They are also no longer optional for anyone sending in volume: Gmail and Yahoo have required SPF, DKIM and DMARC from bulk senders since February 2024, and Outlook.com followed in May 2025. Here's how each one works and how to deploy them without breaking your legitimate email.
SPF: which servers may send as you
SPF (Sender Policy Framework) is a DNS TXT record that lists the mail servers allowed to send email for your domain. When a receiving server gets a message claiming to be from you, it checks whether the sending server's IP is on your SPF list.
A minimal SPF record for a domain that sends through Google Workspace:
v=spf1 include:_spf.google.com ~all
include:_spf.google.compulls in Google's authorised servers.~all(soft-fail) means "anything not listed is suspicious." Use-all(hard-fail) once you're confident the list is complete.
Two rules people break: you may only have one SPF record per domain, and SPF is limited to 10 DNS lookups. Pile on too many include: mechanisms and SPF silently breaks.
DKIM: a cryptographic signature
SPF proves the sending server is authorised. DKIM (DomainKeys Identified Mail) proves the message content wasn't tampered with. Your mail server signs each outgoing message with a private key; the matching public key lives in DNS. The receiver verifies the signature.
A DKIM record is published at a selector subdomain, e.g. selector1._domainkey.yourdomain.com:
v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
You don't usually write this by hand: your email provider (Google Workspace, Microsoft 365, Postmark, SES, etc.) generates the key pair and gives you the record to publish. The critical part is actually enabling signing in the provider dashboard after you publish the record; a published key that isn't signing anything does nothing.
DMARC: the policy that ties it together
This is the piece most people miss. SPF and DKIM on their own don't tell receivers what to do when a message fails. DMARC (Domain-based Message Authentication, Reporting & Conformance) does two things:
- It sets a policy (none, quarantine or reject) for messages that fail authentication.
- It requests reports, so you can see who's sending as your domain.
A DMARC record lives at _dmarc.yourdomain.com:
v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com; fo=1
DMARC also enforces alignment: it's not enough for SPF or DKIM to pass; the domain they authenticate must match the domain in the visible From address. This is what actually stops spoofing, because attackers can pass SPF for their own domain but can't align it to yours.
Why p=none means you're still spoofable
The most important point in this article: p=none provides no protection. It tells receivers "authenticate my mail, send me reports, but deliver failures anyway." It's a monitoring mode, useful for the first couple of weeks so you can see your legitimate senders, but if you leave it there an attacker's forged mail still lands in the inbox.
Protection only begins at p=quarantine (failures go to spam) and is complete at p=reject (failures are refused outright). A large share of domains publish DMARC, feel protected, and never move past p=none.
Rolling out enforcement without breaking deliverability
Do it in stages, and don't skip the reporting phase:
- Publish SPF and DKIM first, and confirm your legitimate mail passes both.
- Publish DMARC at
p=nonewith arua=reporting address. Collect aggregate reports for one to two weeks. - Read the reports. They'll reveal every service sending as you (your CRM, your invoicing tool, your marketing platform), including some you forgot about. Add each legitimate one to SPF and enable DKIM for it.
- Move to
p=quarantine, optionally withpct=25to apply the policy to only a quarter of mail at first, then ramp to 100%. - Move to
p=rejectonce quarantine is clean.
Rushing to p=reject before step 3 is how teams accidentally send their own password-reset and invoice emails to spam.
The hard part is staying protected
Email authentication isn't set-and-forget. Selectors rotate, a new SaaS tool starts sending on your behalf, someone "simplifies" the SPF record and breaks alignment, or a well-meaning admin drops your DMARC policy back to p=none. Any of these silently reopens the spoofing hole, and you won't know until a customer forwards you a phishing email.
Standalone DMARC monitoring products typically charge $20–90/month for this. CompleteStatus includes SPF/DKIM/DMARC monitoring on every plan, Free included: it alerts if your SPF or DMARC record disappears and flags weak settings such as p=none or +all.
Check your domain right now with the free DMARC / SPF / DKIM checker, or start monitoring free so a dropped record doesn't go unnoticed.
Written with AI assistance and reviewed by the CompleteStatus team.
Get notified when CompleteStatus opens
New accounts are closed while we're in private beta. Leave your email and we'll send one message the moment sign-ups open — nothing else.