Skip to content

A 30-minute email authentication audit for your domain

A timed checklist to audit SPF, DKIM, DMARC and transport security on any domain, with the commands to run and what a passing answer looks like.

Koltrix Team4 min read
Items being checked off a paper checklist
Photo by Jakub Żerdzicki on Unsplash
On this page(9 sections)
  1. Before you start (2 minutes)
  2. Minutes 0 to 5: SPF
  3. Minutes 5 to 10: DKIM
  4. Minutes 10 to 15: DMARC
  5. Minutes 15 to 20: the test message verdict
  6. Minutes 20 to 25: transport and infrastructure
  7. Minutes 25 to 30: the domains you forgot
  8. Turning findings into a plan
  9. Key takeaways

You do not need a consultant or a paid scanner to find out whether a domain's email authentication is in good shape. Half an hour, a terminal and one test message will surface nearly every problem worth fixing.

Here is the audit we run, broken into timed blocks, with what a passing answer looks like at each step.

Before you start (2 minutes)

Gather three things:

  • The domain you are auditing, plus any subdomains you know send mail (bounce domains, marketing subdomains).
  • A recent message from each system that sends as the domain, saved with full headers. If you do not have one, trigger a password reset or a notification to yourself.
  • A terminal with dig, curl and openssl.

Write down findings as you go in three buckets: broken (fix this week), weak (fix this quarter), and fine.

Minutes 0 to 5: SPF

dig +short TXT example.com | grep -i 'v=spf1'

Check:

  1. Exactly one record. Two or more is a permerror on every check. Broken.
  2. Ends in ~all or -all. +all or ?all is broken; a missing all is weak.
  3. Nothing after all. Terms after it are never evaluated.
  4. Lookup count. Walk each include: and tally include, a, mx, ptr, exists and redirect across the tree. Over ten is broken; eight to ten is weak, because the next vendor will push it over.
  5. No dead includes. An include that returns no record wastes a lookup and counts toward the two-void-lookup limit.

Repeat for every bounce subdomain you know about.

Minutes 5 to 10: DKIM

Open each saved message and find the DKIM-Signature headers. Note the d= domain, the s= selector and the a= algorithm. Then:

dig +short TXT k1._domainkey.example.com

Check:

  1. The key exists at the selector. No answer is broken.
  2. The d= domain is yours or a subdomain of yours. A vendor's own domain means the signature cannot align for DMARC. Weak now, broken once you enforce DMARC.
  3. The algorithm is rsa-sha256 (or ed25519-sha256 as an additional signature). rsa-sha1 is broken.
  4. The key is at least 2048 bits. A short p= value, about 216 characters, suggests 1024-bit. Weak.
  5. No l= tag in the signature. Its presence lets content be appended to signed mail. Weak to broken.

To check key length precisely, decode the key with openssl, as covered in our post on publishing 2048-bit keys.

Minutes 10 to 15: DMARC

dig +short TXT _dmarc.example.com

Check:

  1. A record exists and starts with v=DMARC1. Missing is broken if you send any volume to Gmail or Yahoo, since both require DMARC from bulk senders.
  2. The policy. p=none is acceptable while you are monitoring, but it provides no protection; note how long it has been there. quarantine or reject is the goal.
  3. Subdomain coverage. Does sp=none leave subdomains exposed? Is np set for non-existent subdomains?
  4. Reporting. Is there a rua=mailto: address, and is someone actually reading the reports? An unread report mailbox is weak.
  5. Obsolete tags. pct, rf and ri were removed in RFC 9989. Harmless but worth cleaning up.

If rua points to another domain, check the authorization record at example.com._report._dmarc.<that-domain>.

Minutes 15 to 20: the test message verdict

Read the Authentication-Results header that your own mailbox provider added to each saved message.

Authentication-Results: mx.receiver.example;
  spf=pass smtp.mailfrom=bounce.example.com;
  dkim=pass header.d=example.com header.s=k1;
  dmarc=pass header.from=example.com

For each sending system, confirm dmarc=pass, and identify which mechanism provided the aligned pass. A message passing DMARC only through SPF is fragile, because forwarding breaks SPF. Every stream should ideally have aligned DKIM.

Also look for:

  • spf=permerror or temperror with a reason in parentheses.
  • dkim=fail (body hash did not verify), which means something modifies messages after signing.
  • One-click unsubscribe headers on marketing mail: List-Unsubscribe with an HTTPS URL plus List-Unsubscribe-Post: List-Unsubscribe=One-Click, which Gmail and Yahoo require for bulk marketing and subscribed mail.

Minutes 20 to 25: transport and infrastructure

dig +short MX example.com
dig +short TXT _mta-sts.example.com
dig +short TXT _smtp._tls.example.com
dig +short -x 192.0.2.25

Check:

  1. MX records resolve to hostnames with address records. A domain that never receives mail should have a null MX (0 .).
  2. MTA-STS exists, and the policy at https://mta-sts.example.com/.well-known/mta-sts.txt lists the current MX hosts. Missing is weak; a policy that lists old MX hosts in enforce mode is broken.
  3. TLS-RPT exists, so TLS failures get reported to you.
  4. Reverse DNS. For any IP you operate that sends mail, the PTR hostname resolves back to the same IP. If you only send through providers, they handle this.

Minutes 25 to 30: the domains you forgot

List every domain the organization owns, including old brands and defensive registrations. For each one that should never send mail, check for the lockdown set:

Record Expected value
MX 0 .
SPF v=spf1 -all
DMARC v=DMARC1; p=reject

Missing lockdown records on a parked domain is weak; those domains are attractive for spoofing because they genuinely belong to you.

Turning findings into a plan

Sort the findings by bucket and assign owners:

  • Broken items usually take minutes to fix once found: merge a duplicate SPF record, publish a missing DKIM key, remove +all.
  • Weak items are projects: rotating to 2048-bit keys, moving vendors to aligned DKIM, rolling DMARC toward enforcement, deploying MTA-STS.
  • Fine items go on a quarterly re-check list.

Repeat the audit every quarter and after any change to sending vendors, mailbox providers or DNS hosting. It gets faster each time because the inventory already exists.

Key takeaways

  • Thirty minutes covers SPF, DKIM, DMARC, a real-message verdict, transport security and parked domains.
  • Real message headers are essential; DNS alone cannot tell you which selectors and envelope domains are in use.
  • Classify each finding as broken, weak or fine, and fix broken items immediately.
  • Every sending stream should pass DMARC through aligned DKIM, not only SPF.
  • Re-run the audit quarterly and after any vendor or DNS change.

Start with Koltrix

Your domain, one inbox, and an API that sends.

A team inbox where AI sorts and drafts (nothing is sent without your click), plus the transactional API and SMTP relay your product sends with. 7 days free, no card.

SharePost on XLinkedIn
More in Guides →