Back to Blog

Email Authentication 101: SPF, DKIM, and DMARC for Developers

Most developers first encounter email authentication when something breaks. A password reset email lands in spam. A transactional receipt never arrives. A client reports that your notification emails look "suspicious" in their inbox. The fix almost always involves three acronyms: SPF, DKIM, and DMARC.

These protocols are not just security measures. They directly determine whether your emails reach the inbox or get buried in spam. If you send any email from your application β€” and you almost certainly do β€” understanding how authentication works is not optional.

Why Developers Need to Care About Email Authentication

Email was designed in the 1980s with zero built-in authentication. Anyone can send an email claiming to be from any address. That is not a bug in your application β€” it is a fundamental property of SMTP.

SPF, DKIM, and DMARC were layered on top of SMTP to solve this. They let receiving mail servers verify that an email actually came from who it claims to come from. When these checks fail, your email gets flagged, quarantined, or silently dropped.

Google and Yahoo both enforce strict authentication requirements as of 2024. If you send more than 5,000 emails per day to Gmail users without proper SPF, DKIM, and DMARC records, expect significant delivery failures.

Even if you send a handful of transactional emails, authentication affects you. A single misconfigured DNS record can send every password reset email to spam.

SPF: Declaring Who Can Send On Your Behalf

Sender Policy Framework (SPF) is the simplest of the three. It is a DNS TXT record that lists which IP addresses and servers are authorized to send email for your domain.

How SPF Works

When a receiving server gets an email from [email protected], it looks up the SPF record for yourapp.com. If the sending server's IP is listed in that record, the SPF check passes. If not, it fails.

SPF Record Syntax

SPF records are published as DNS TXT records on your domain. Here is a typical example:

v=spf1 ip4:203.0.113.50 include:_spf.google.com include:sendgrid.net ~all

Breaking this down:

  • v=spf1 β€” Version identifier. Always required.
  • ip4:203.0.113.50 β€” Authorizes a specific IPv4 address.
  • include:_spf.google.com β€” Authorizes all IPs listed in Google's SPF record (for Google Workspace).
  • include:sendgrid.net β€” Authorizes SendGrid's sending infrastructure.
  • ~all β€” Soft fail for anything not listed. Use -all for a hard fail.

Common SPF Mistakes

Too many DNS lookups. SPF has a hard limit of 10 DNS lookups. Each include: counts as one. Nested includes count too. Exceeding this limit causes SPF to return permerror, which many receivers treat as a failure.

Check your lookup count:

dig +short TXT yourapp.com | grep spf
# Then recursively check each include
dig +short TXT _spf.google.com

Forgetting third-party senders. If you use SendGrid for transactional email and Mailchimp for marketing, both need to be in your SPF record.

Multiple SPF records. You can only have one SPF TXT record per domain. Multiple records cause authentication to fail entirely. Merge them into a single record.

# Wrong - two separate SPF records
v=spf1 include:sendgrid.net ~all
v=spf1 include:_spf.google.com ~all

# Correct - single merged record
v=spf1 include:sendgrid.net include:_spf.google.com ~all

DKIM: Cryptographically Signing Your Emails

DomainKeys Identified Mail (DKIM) uses public-key cryptography to prove that an email was not tampered with in transit and was authorized by the domain owner.

How DKIM Works

  1. Your sending server generates a hash of the email headers and body.
  2. That hash is encrypted with your private key and added as a DKIM-Signature header.
  3. The receiving server fetches your public key from DNS and decrypts the signature.
  4. If the decrypted hash matches the email content, the DKIM check passes.

Setting Up DKIM

Most email service providers handle key generation for you. They will give you a DNS TXT record to publish. It looks like this:

# DNS Record
Host: selector1._domainkey.yourapp.com
Type: TXT
Value: v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC...

The selector1 part is a selector β€” it allows you to have multiple DKIM keys for key rotation or different sending services.

If you manage your own mail server, you can generate DKIM keys with OpenSSL:

# Generate a 2048-bit RSA key pair
openssl genrsa -out dkim_private.pem 2048
openssl rsa -in dkim_private.pem -pubout -out dkim_public.pem

# Extract the public key for DNS (remove headers and newlines)
cat dkim_public.pem | grep -v "^-" | tr -d '\n'

Verifying DKIM Signatures

You can check DKIM signatures by inspecting email headers. Look for the DKIM-Signature header and the Authentication-Results header added by the receiving server:

Authentication-Results: mx.google.com;
    dkim=pass [email protected] header.s=selector1;

From the command line, query the DKIM record directly:

dig +short TXT selector1._domainkey.yourapp.com

DMARC: Tying It All Together

Domain-based Message Authentication, Reporting, and Conformance (DMARC) builds on SPF and DKIM. It tells receiving servers what to do when authentication fails and provides a reporting mechanism so you can monitor your email authentication health.

DMARC Policies

DMARC records are DNS TXT records published at _dmarc.yourapp.com:

v=DMARC1; p=none; rua=mailto:[email protected]; pct=100;

The p= tag defines your policy:

  • p=none β€” Monitor only. No action taken on failures. Start here.
  • p=quarantine β€” Failed emails go to spam.
  • p=reject β€” Failed emails are dropped entirely.

DMARC Alignment

DMARC requires "alignment" β€” the domain in the From: header must match the domain authenticated by SPF or DKIM.

There are two alignment modes:

  • Relaxed (default): The organizational domain must match. mail.yourapp.com aligns with yourapp.com.
  • Strict: The exact domain must match.
# Relaxed alignment (default)
v=DMARC1; p=quarantine; aspf=r; adkim=r;

# Strict alignment
v=DMARC1; p=quarantine; aspf=s; adkim=s;

Rolling Out DMARC Safely

Never jump straight to p=reject. Follow this progression:

  1. Start with p=none and set up reporting. Monitor for 2-4 weeks.
  2. Move to p=quarantine; pct=10; to quarantine 10% of failing emails.
  3. Gradually increase pct to 25%, 50%, 100%.
  4. Switch to p=reject once you are confident all legitimate sending sources pass authentication.

DMARC Reporting

The rua tag specifies where aggregate reports are sent. These XML reports tell you which IPs are sending email on behalf of your domain and whether they pass or fail authentication.

v=DMARC1; p=none; rua=mailto:[email protected]; ruf=mailto:[email protected];
  • rua β€” Aggregate reports (daily summaries).
  • ruf β€” Forensic reports (individual failure details). Many providers do not send these due to privacy concerns.

Services like Postmark's DMARC monitoring tool or dmarcian can parse these reports into dashboards.

How SPF, DKIM, and DMARC Work Together

These three protocols form a chain:

  1. SPF verifies the sending server is authorized.
  2. DKIM verifies the message was not altered and was signed by the domain.
  3. DMARC checks that at least one of SPF or DKIM passes and is aligned with the From: domain, then enforces the policy.

An email passes DMARC if:

  • SPF passes and the SPF domain aligns with the From: domain, OR
  • DKIM passes and the DKIM domain aligns with the From: domain.

Both do not need to pass. One aligned pass is sufficient.

Testing Authentication in Development

When you are building and testing your application's email sending, you need to verify that authentication headers are correct before going to production. This is where an SMTP sandbox becomes essential.

With SendPit, captured emails preserve the full set of authentication headers. You can inspect the raw headers of any email sent to your sandbox mailbox and see exactly what SPF, DKIM, and DMARC results a receiving server would generate.

This lets you catch problems like missing DKIM signatures, SPF misalignment, or broken DMARC policies before they affect real users.

A practical development workflow:

  1. Configure your application to send through your real email provider (SendGrid, Postmark, SES) but route to a SendPit sandbox mailbox.
  2. Trigger a transactional email from your application.
  3. Open the captured email in SendPit and inspect the raw headers.
  4. Verify the DKIM-Signature header is present and the signing domain matches your From: domain.
  5. Check that the sending IP would pass your SPF record.

Common Failures and How to Debug Them

SPF Failure: "softfail" or "fail"

Authentication-Results: spf=softfail smtp.mailfrom=yourapp.com

Cause: The sending IP is not in your SPF record. This often happens when you switch email providers or add a new sending service.

Fix: Add the provider's include: to your SPF record. Check their documentation for the correct value.

DKIM Failure: "body hash did not verify"

Authentication-Results: dkim=fail (body hash did not verify)

Cause: Something modified the email body after signing. Common culprits: mailing list software, email forwarding services, or overly aggressive spam filters.

Fix: This is often outside your control for forwarded emails. Ensure your sending infrastructure signs the email correctly. Test with a direct send (not forwarded) to confirm.

DMARC Failure: "alignment failed"

Authentication-Results: dmarc=fail (p=none) header.from=yourapp.com

Cause: Neither SPF nor DKIM is aligned with the From: domain. For example, sending via SendGrid with default settings uses SendGrid's domain for SPF, which does not align with yourapp.com.

Fix: Set up authenticated sending domains with your provider. This typically involves adding CNAME or TXT records to your DNS so that SPF and DKIM align with your From: domain.

Tools for Checking Your Configuration

MXToolbox (mxtoolbox.com): Comprehensive DNS and email diagnostic tools. Check SPF, DKIM, and DMARC records, run blacklist checks, and validate record syntax.

# Quick command-line checks
dig +short TXT yourapp.com | grep spf
dig +short TXT _dmarc.yourapp.com
dig +short TXT selector1._domainkey.yourapp.com

Google Postmaster Tools: If you send to Gmail users, this shows your domain's reputation, authentication rates, and delivery errors.

mail-tester.com: Send a test email to their address and get a score with specific authentication feedback.

dmarcian.com: Free DMARC record analyzer and monitoring for aggregate reports.

Summary

Email authentication is infrastructure work. It is not glamorous, but it directly determines whether your users receive the emails your application sends. The setup is straightforward:

  1. Publish an SPF record listing all your authorized senders.
  2. Configure DKIM signing with your email provider and publish the public key.
  3. Add a DMARC record starting with p=none, monitor the reports, and gradually tighten the policy.
  4. Test your configuration using an SMTP sandbox like SendPit to inspect authentication headers before going live.

Get these three records right and your transactional emails will land where they belong: in the inbox.

N

Nikhil Rao

Creator of SendPit. Building developer tools for email testing and SMTP infrastructure.

About SendPit →

More from the blog