In this module

AD2.5 SPF: Declaring Who Can Send as Your Domain

5-6 hours · Module 2 · Free
Operational Objective
Without SPF (Sender Policy Framework), anyone in the world can send an email that appears to come from your domain. An attacker can send an email from your-ceo@northgateeng.com to a client, vendor, or employee — and the recipient's email system has no way to verify whether the email actually came from your mail server or from the attacker's. SPF fixes this by publishing a DNS record that lists every server authorized to send email as your domain. When a receiving mail server gets an email from @northgateeng.com, it checks your SPF record — if the sending server isn't on the list, the email fails SPF validation. This subsection walks you through creating, testing, and maintaining your SPF record — including the common mistakes that break email delivery.
Deliverable: A correctly configured SPF record for your domain that authorizes M365 and any other legitimate sending services, verified with DNS lookup tools and tested with email delivery checks.
Estimated completion: 25 minutes
SPF — HOW IT WORKS ATTACKER Sends email as ceo@northgateeng.com From: attacker's mail server IP: 198.51.100.99 Not your server RECEIVING SERVER Gets email from @northgateeng.com Looks up SPF record: nslookup -type=txt northgateeng.com SPF says: only M365 can send Attacker IP not in SPF → FAIL Email rejected or marked as spam LEGIT EMAIL From M365 → SPF pass ✓ Delivered normally SPOOFED EMAIL Not from M365 → SPF fail ✗ Rejected or junked With DMARC: blocked entirely YOUR SPF RECORD v=spf1 include:spf.protection .outlook.com -all This is the whole record

Figure AD2.5 — SPF validation. The receiving server checks whether the sending server's IP is authorized in your SPF DNS record. Legitimate email from M365 passes. Spoofed email from the attacker's server fails. The SPF record is a single TXT record in your domain's DNS.

Building your SPF record

For an M365 environment where Exchange Online is your only email sending service, the SPF record is simple:

v=spf1 include:spf.protection.outlook.com -all

This record says: "The only servers authorized to send email as @northgateeng.com are Microsoft's Exchange Online servers (spf.protection.outlook.com). Everything else should fail (-all)."

If your organization also sends email through other services — a marketing platform (Mailchimp, HubSpot), a CRM (Salesforce), a support ticketing system (Zendesk), or a scanner/copier that sends via SMTP relay — you need to include those services in the SPF record. Each service provides their SPF include value in their documentation. The record might look like:

v=spf1 include:spf.protection.outlook.com include:servers.mcsv.net include:_spf.salesforce.com -all

Important: SPF records have a 10-DNS-lookup limit. Each include: counts as one lookup. If you exceed 10 lookups, the entire SPF record fails — which means ALL your email fails SPF validation. Keep the record as simple as possible. If you're running into the lookup limit, some services offer IP-based SPF entries (ip4:x.x.x.x) that don't count against the lookup limit, or you can use SPF flattening services.

The -all vs ~all decision: -all (hard fail) tells receiving servers to reject email that fails SPF. ~all (soft fail) tells receiving servers to accept the email but mark it as suspicious. Start with ~all during initial deployment to avoid blocking legitimate email from services you forgot to include. After 2-4 weeks of monitoring with no delivery issues, switch to -all for stronger enforcement.

Adding the SPF record to DNS

Log into your DNS hosting provider (Cloudflare, GoDaddy, Azure DNS, Route 53, or wherever your domain's DNS is managed). Create a new TXT record:

Type: TXT Name: @ (or your domain name — some providers use the @ symbol, others require the full domain) Value: v=spf1 include:spf.protection.outlook.com -all TTL: 3600 (1 hour) or your provider's default

Important: You can only have ONE SPF record per domain. If an SPF record already exists, edit it to add the M365 include — don't create a second TXT record starting with v=spf1. Multiple SPF records cause validation failures because receiving servers don't know which one to use.

Verifying the SPF record

After creating the record, verify it with a DNS lookup. Open a command prompt or terminal:

nslookup -type=txt northgateeng.com

You should see your SPF record in the output. If you see two records starting with v=spf1, you have duplicate SPF records — remove the incorrect one.

For a more detailed validation, use MXToolbox (mxtoolbox.com/spf.aspx) — it checks the record syntax, counts the DNS lookups, and flags common errors. Run this check after every SPF change.

To verify SPF is working for outbound email, send a test email from your M365 tenant to an external email address (a personal Gmail or Outlook.com account). In the received email, check the message headers. Look for spf=pass in the Authentication-Results header. If you see spf=pass, your outbound email is SPF-authenticated. If you see spf=fail or spf=none, the SPF record isn't configured correctly — recheck the DNS entry.

Compliance Myth: "SPF alone prevents email spoofing"
SPF only validates the envelope sender (the MAIL FROM in SMTP), not the display FROM address that users see in their email client. An attacker can still send an email with a display FROM of "ceo@northgateeng.com" while using a different envelope sender that passes SPF for a different domain. To prevent this, you need DMARC, which aligns the display FROM with the SPF and DKIM validation domains. SPF is the foundation. DKIM adds message-level authentication. DMARC enforces alignment between them. All three are needed for complete email authentication — and all three are covered in this module.

Common SPF mistakes

Mistake 1 — Multiple SPF records. Two TXT records both starting with v=spf1. This causes SPF validation to fail for ALL email because the receiving server doesn't know which record to use. Fix: merge both records into a single TXT entry.

Mistake 2 — Exceeding 10 DNS lookups. Each include: in your SPF record triggers a DNS lookup. More than 10 lookups means SPF validation fails entirely. Fix: remove unnecessary includes, use ip4/ip6 directives for services that support them, or use SPF flattening.

Mistake 3 — Forgetting a legitimate sending service. You add the M365 include but forget that your marketing platform also sends email as your domain. Those marketing emails start failing SPF. Fix: audit all services that send email as your domain before publishing the SPF record. Ask your team: what services send email that looks like it comes from us?

Mistake 4 — Using +all instead of -all. +all means "everyone is authorized to send as our domain" — this defeats the entire purpose of SPF. Always use -all (hard fail) or ~all (soft fail during initial deployment).

Auditing all services that send as your domain

Before publishing your SPF record, you need to know every service that sends email as your domain. Miss one and its emails start failing SPF. Here's how to audit systematically.

Check Exchange Online message trace for the last 90 days. In PowerShell:

Connect-ExchangeOnline
$start = (Get-Date).AddDays(-90)
Get-MessageTrace -StartDate $start -EndDate (Get-Date) -Status "Delivered" |
    Where-Object { $_.SenderAddress -like "*@northgateeng.com" } |
    Group-Object SenderAddress |
    Sort-Object Count -Descending |
    Select-Object Name, Count -First 30

This shows every email address on your domain that sent email in the last 90 days. If you see addresses you don't recognize (marketing-noreply@northgateeng.com, support@northgateeng.com, scanner@northgateeng.com), investigate which service sends from each address.

Ask each department. Email is a surprisingly decentralized service. Marketing may use Mailchimp, HubSpot, or Constant Contact. Support may use Zendesk, Freshdesk, or ServiceNow. Sales may use Salesforce or HubSpot CRM. Finance may have an invoicing system that sends as your domain. Operations may have scanners or multifunction printers configured for email. Each of these needs to be in your SPF record.

Check your DNS for existing SPF. If someone previously configured SPF (perhaps a previous admin or a managed service provider), check what's already there:

Resolve-DnsName -Name northgateeng.com -Type TXT | Where-Object { $_.Strings -like "*spf*" }

If an SPF record exists, don't replace it — update it. If it doesn't exist, you're starting fresh. Either way, the audit of sending services comes first.

Validate with an SPF lookup count. After constructing your record, verify the DNS lookup count doesn't exceed 10. Use mxtoolbox.com/spf.aspx or the spf-tools open-source validator. Each include: counts as 1 lookup, and nested includes count recursively. A record like v=spf1 include:spf.protection.outlook.com include:servers.mcsv.net include:_spf.salesforce.com -all uses 3 lookups at the top level, but each include may resolve to additional includes internally. The total across all levels must stay under 10.

Monitoring SPF health after deployment

SPF isn't a set-and-forget control. Your SPF record needs updating whenever your organization changes email sending services — which happens more often than you'd expect. Marketing switches platforms, support moves to a new ticketing system, a new office scanner sends email. Each change potentially breaks SPF for the new service.

Build a simple SPF monitoring check into your quarterly review. Run this verification:

# Check your SPF record resolves correctly
Resolve-DnsName -Name northgateeng.com -Type TXT |
    Where-Object { $_.Strings -like "*spf*" } |
    Select-Object -ExpandProperty Strings

# Verify outbound email SPF status via a test
# Send a test email to check-auth@verifier.port25.com
# This service replies with your authentication results including SPF

The Port25 verifier service (check-auth@verifier.port25.com) is a free email authentication testing tool. Send an email to this address from your M365 account. Within minutes, you'll receive an automated reply showing your SPF result, DKIM result, and DMARC result — with detailed diagnostics for any failures. This is the fastest way to verify all three authentication mechanisms in one check.

Also monitor your DMARC reports (AD2.7) for SPF failures from your domain. If a legitimate service starts failing SPF because you forgot to add it during a service migration, the DMARC aggregate report shows the source IP and failure count — alerting you to fix the SPF record before delivery issues escalate.

Decision point

You've created your SPF record with v=spf1 include:spf.protection.outlook.com -all. Two days later, the marketing team reports that their monthly newsletter (sent through Mailchimp) is being rejected by some recipients. You check and confirm Mailchimp is not in your SPF record. What do you do?

Option A: Remove the SPF record until you can audit all sending services.

Option B: Change -all to +all to allow all senders temporarily.

Option C: Add Mailchimp's SPF include to your existing record: v=spf1 include:spf.protection.outlook.com include:servers.mcsv.net -all

The correct answer is Option C. Add the missing service. Don't remove the SPF record (that removes all protection) or change to +all (that removes all enforcement). Adding the missing include is targeted, immediate, and maintains protection for all other email. Run the audit of all sending services now to prevent future surprises — check with marketing, HR, IT, facilities, and any department that might use a third-party email service.

nslookup -type=txt yourdomain.com
Try it: Check and configure your SPF record

First, check your current SPF record:

Look for a record starting with v=spf1. If it exists, note the current includes. If it doesn't exist, your domain has no SPF protection — creating one is your immediate priority.

If you have an SPF record, verify it includes spf.protection.outlook.com for M365. If it doesn't, you need to add it.

Run a validation check at mxtoolbox.com/spf.aspx — enter your domain and check for errors (duplicate records, too many lookups, syntax errors).

Send a test email from your M365 account to a personal Gmail address. In Gmail, open the email, click the three dots menu → "Show original." Search for "spf=" in the headers. You should see spf=pass. If you see spf=fail, your SPF record needs fixing.

Your SPF record is `v=spf1 include:spf.protection.outlook.com -all`. An attacker sends an email spoofing your CEO's address from their own mail server. The recipient's email system checks SPF. What happens?
The email is delivered normally because SPF only checks the domain, not the sender address — Partially correct on the mechanics but wrong on the outcome. SPF checks the envelope sender domain. If the attacker uses your domain as the envelope sender, SPF checks and fails because the attacker's server isn't in your SPF record. The `-all` directive causes a hard fail.
SPF validation fails because the attacker's server IP is not authorized in your SPF record — the email is rejected or marked as spam depending on the recipient's configuration — Correct. Your SPF record lists only M365 servers as authorized senders. The attacker's server isn't on the list. With `-all`, the receiving server should reject the email. In practice, some receiving servers mark it as spam rather than outright rejecting it — which is why DMARC (AD2.7) adds enforcement on top of SPF.
The email passes SPF because the attacker can set any envelope sender they want — No. The attacker can set any envelope sender, but SPF checks whether the SENDING SERVER is authorized for that domain. The attacker's server will never be in your SPF record.
SPF blocks the email completely and the recipient never sees it — Depends on the recipient's mail server. SPF provides a PASS/FAIL signal. What the receiving server does with that signal varies — some reject, some junk, some deliver with a warning. DMARC (AD2.7) tells receiving servers what action to take on SPF failures.

You're reading the free modules of M365 Security: From Admin to Defender

The full course continues with advanced topics, production detection rules, worked investigation scenarios, and deployable artifacts.

View Pricing See Full Syllabus