BIMI
Puts your logo next to your mail in supporting clients. Requires DMARC at
quarantine or reject first, an SVG Tiny PS logo, and for Gmail/Apple a
paid Verified Mark Certificate.
Email authentication, without the hand-waving
Anyone in the world can type your address into the “From” box of an email. The protocol was designed in 1982 and it never asked for proof. SPF, DKIM and DMARC are the three records that bolt proof on afterwards. This page explains what they are, how to switch them on without breaking your own mail, what goes wrong when you rush, and exactly what to do the morning someone starts sending invoices in your name.
Everything on this page runs in your browser. Nothing you type is uploaded, except the one optional live DNS lookup that you have to click yourself.
A public list of the servers allowed to send mail for your domain. “Only these post offices may stamp my letters.”
v=spf1 include:_spf.google.com -all
A cryptographic signature added to every message; the public key sits in your DNS. “A wax seal nobody can forge, that also proves the letter was not edited.”
selector._domainkey → v=DKIM1; k=rsa; p=MIIB…
Ties SPF and DKIM to the address your reader actually sees, states the punishment, and mails you reports. “And if the seal is missing — burn the letter, then tell me.”
_dmarc → v=DMARC1; p=reject; rua=mailto:dmarc@…
The one thing to remember: SPF and DKIM on their own protect
nothing a human ever looks at. They validate hidden, technical addresses. Only DMARC
connects them to the From: line displayed in the mail client — and that connection is called
alignment. Alignment is the whole game.
You cannot reason about spoofing until you have seen that an email is really two things at once: an envelope handled by servers, and a letter read by humans. They contain different addresses, and nothing forces them to match.
Received:
header.
Authentication-Results:.
| Envelope sender | Header From | |
|---|---|---|
| Also called | MAIL FROM, Return-Path, bounce address, RFC5321.From, “envelope from” |
From:, RFC5322.From, “friendly from” |
| Who sees it | Servers and postmasters. Bounces go here. | Your reader. This is the name and address in the mail client. |
| Checked by | SPF | DMARC (and it is the only one that matters to a victim) |
| Typical mismatch | [email protected] |
[email protected] |
This gap is the entire attack. A criminal sets the envelope
to a domain they legitimately control (so SPF passes for their domain) and writes your address
in the From: header. Without DMARC, no one ever compares the two.
Authentication-Results: — the receiving server's verdict. Read this first, always. It
is written by the last trusted server, so only trust the copy added by your own provider.
Received: — one per hop, newest at the top. The bottom-most is where the message was
born (and is trivially forgeable; the top ones are not).Return-Path: — the envelope sender as recorded on delivery. Compare it with
From:.
DKIM-Signature: — contains d= (the signing domain — the important part),
s= (selector), bh= (body hash) and h= (which headers were
signed).
Reply-To: — where your answer really goes. A classic trick: a perfect
From: and a hostile Reply-To:.
Message-ID: — unique id; its domain part often betrays the real sending platform.ARC-Seal: / ARC-Authentication-Results: — a forwarder vouching that
authentication passed before it touched the message.List-Unsubscribe: / List-Unsubscribe-Post: — required by Gmail and Yahoo
for bulk senders since 2024; one-click unsubscribe.Want to read a real message? Paste it into the Email Header Analyzer next door — it decodes all of this for you.
A single DNS TXT record on your domain that lists which servers are allowed to send mail using your domain in the envelope. Defined in RFC 7208.
example.com. IN TXT "v=spf1 ip4:203.0.113.7 include:_spf.google.com include:sendgrid.net -all"
| Piece | Meaning | Watch out |
|---|---|---|
v=spf1 |
Version marker. Must be first, exactly once. | A record without it is not an SPF record. |
ip4: / ip6: |
A literal address or CIDR range that may send. | Costs zero DNS lookups. Cheapest mechanism. |
a / mx |
Whatever the domain's A record / MX hosts resolve to. | 1 lookup each (mx can cost far more). Your mail receiver is rarely
your sender — mx is usually lazy, not correct. |
include: |
“Also trust whatever this domain's SPF record says.” How you authorise a provider. | 1 lookup plus everything nested inside it. The main cause of the 10-lookup blow-up. |
redirect= |
“Use that domain's record instead of mine.” Only meaningful without an
all. |
Easy to confuse with include. Rarely what you want. |
ptr |
Reverse-DNS match. | Deprecated. Never use it. Slow and unreliable. |
exists: |
Macro-based conditional match. | Advanced; costs a lookup. You almost certainly do not need it. |
-all |
Fail — anyone not listed is forged. The goal. | Only after you are certain the list is complete. |
~all |
Softfail — suspicious but accept. The safe starting point. | Fine for weeks, not forever. |
?all |
Neutral — “no opinion”. Equivalent to having no policy. | Pointless in practice. |
+all |
“Everyone on earth may send as me.” | Catastrophic. If you find this, remove it today. |
v=spf1 TXT records on the same
domain is a permanent error and SPF stops working entirely. Merge them into one.include, a, mx, ptr, exists and
redirect. Exceed it and the result is permerror — which most receivers
treat as “no SPF”. Flattening tools help but freeze provider IPs; prefer removing unused providers.
SPF-type record. DNS record type 99 was retired in
2014. It is a TXT record.Void lookups: there is a second, less-known limit — at most
2 mechanisms may resolve to nothing (NXDOMAIN/empty). Stale include: lines for a provider
you left behind are the usual culprit.
Your outgoing server hashes selected headers plus the body and signs them with a private key. The matching public key lives in DNS, so any receiver can verify it. Defined in RFC 6376.
<selector>._domainkey.<your-domain>. The
selector is just a label, so you can hold several keys at once — that is how rotation works without
downtime.DKIM-Signature: header naming the domain
(d=) and the selector (s=).selector1._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; t=s; p=MIIBIjANBgkqhki…"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; s=selector1;
h=from:to:subject:date:message-id; bh=Wm9…=; b=Hs4…=
| Tag | Where | Meaning |
|---|---|---|
d= |
signature | The signing domain. This is what DMARC compares to your
From:. If it says your provider's domain instead of yours, DKIM passes but
DMARC still fails.
|
s= |
signature | Selector — tells the receiver which DNS record holds the key. |
h= |
signature | Which headers were signed. Should include at least from, and ideally
subject, date, to.
|
bh= / b= |
signature | Body hash and the signature itself. Change one byte of the body and
bh no longer matches.
|
c= |
signature | Canonicalisation, e.g. relaxed/relaxed — tolerates trivial whitespace
rewrites in transit. simple/simple is brittle. |
p= |
DNS | The public key. An empty p= means “this key is revoked”.
|
t=s |
DNS | Strict: the key may not be used by subdomains. Optional. |
t=y |
DNS | Test mode: “ignore my failures”. Great for a week, dangerous for a year — remove it when you go live. |
p=.p=.DMARC (RFC 7489) adds the missing question: does the domain that passed SPF or DKIM match the domain your reader sees in the From line? Then it publishes what to do when the answer is no, and asks receivers to report back.
A message passes DMARC if at least one of these is true:
SPF passed and the envelope domain matches the From: domain.
MAIL FROM: bounce@example.com
From: sales@example.com ✅
A DKIM signature verified and its d= matches the From:
domain.
d=example.com
From: sales@example.com ✅
Your newsletter tool signs and bounces with its own domain. Both SPF and DKIM pass — and DMARC still fails, because neither matches what the reader sees.
d=mailtool.net ·
MAIL FROM: mailtool.net
From: news@example.com ❌
Relaxed vs strict: by default (adkim=r, aspf=r) a subdomain
counts as a match — mail.example.com aligns with example.com. With
adkim=s / aspf=s the domains must be identical. Start relaxed; strict is for
organisations that have finished the job.
| Tag | Values | What it does |
|---|---|---|
v |
DMARC1 |
Required, must be first. |
p |
none · quarantine · reject |
Required, must be second. Monitor only / send to junk / refuse at the door. |
sp |
same values | Policy for subdomains. If you omit it, subdomains inherit p. Set
it explicitly — attackers love invoices.yourdomain.com. |
rua |
mailto:… |
Where daily aggregate XML reports go. This is the useful one. |
ruf |
mailto:… |
Forensic/failure reports — copies of failing messages. Few providers send them, and they can contain personal data. Think before enabling. |
fo |
0 · 1 · d · s |
When to generate failure reports. fo=1 = any underlying failure, the most
informative. |
pct |
1–100 |
Apply the policy to only this share of failing mail — your safety valve when ramping up.
Ignored at p=none. |
adkim / aspf |
r · s |
Relaxed or strict alignment, as above. |
ri |
seconds | Requested aggregate report interval; 86400 (daily) is the only value anyone honours. |
Reports arrive as gzipped XML, once a day, from every large receiver. Each
<record> is one sending IP over one day, and tells you: how many messages, whether
SPF and DKIM passed, whether they aligned, and what the receiver did about it. Your job is to
put every source into one of four buckets:
Free and paid analysers turn that XML into a dashboard. If you prefer to keep it in-house, a
shared mailbox plus a parser is enough — but do not point rua at a personal inbox
and then never look at it. An unread report is the same as no report.
External reporting addresses need permission. If
rua points at a different domain than the one being reported on, that domain must publish
an authorisation record such as
example.com._report._dmarc.reporter.net TXT "v=DMARC1", or the reports are silently never
sent. This trips up almost everyone using a third-party analyser.
SPF, DKIM and DMARC are the core. These are the records that surround them — worth knowing, mostly worth doing, none of them a substitute for the big three.
Puts your logo next to your mail in supporting clients. Requires DMARC at
quarantine or reject first, an SVG Tiny PS logo, and for Gmail/Apple a
paid Verified Mark Certificate.
A policy file at https://mta-sts.<domain>/.well-known/mta-sts.txt plus a
_mta-sts TXT record, telling senders “always use TLS to reach me, and here are my
valid MX hosts”. Stops downgrade and interception attacks on incoming mail.
_smtp._tls TXT record asking senders to report failed TLS connections to you. The
companion to MTA-STS: without it you never learn the policy is broken.
Authenticated Received Chain. Lets a forwarder or mailing list record “this passed authentication when I got it”, so the final receiver can forgive a broken SPF/DKIM. You do not configure it; your provider either supports it or does not.
If you run your own mail server, its IP must resolve back to a hostname that resolves forward to the same IP, and the HELO/EHLO name should match. Missing PTR is an instant reputation penalty.
For a domain that receives no mail: MX 0 ".". Senders fail immediately and cleanly
instead of queueing for days.
Signs your DNS zone. Without it, every record on this page can in principle be forged in transit by an attacker who can tamper with DNS answers.
Pins your mail server's certificate in DNSSEC-signed DNS. Stronger than MTA-STS, but requires DNSSEC and is mostly used by mail-heavy operators in Europe.
Since Feb 2024 Gmail and Yahoo require bulk senders to have SPF, DKIM and DMARC,
one-click List-Unsubscribe, and a spam-complaint rate under 0.3%. Microsoft
followed in 2025.
Ten steps, in this order. The order matters more than the speed: every step exists to make the next one safe. A small organisation can do this in a month; a large one should budget a quarter. Nobody should do it in an afternoon.
Goal — know every system on earth that sends mail using your domain.
Do: Get administrative access to your DNS zone and to every mail platform. Then write the list: mailbox provider, newsletter tool, CRM, invoicing/ERP, ticketing/helpdesk, e-commerce platform, HR and payroll, appointment reminders, website contact forms, monitoring and backup alerts, the scanner in the corridor that emails PDFs, and anything a department signed up for on a credit card.
Verify: ask Finance, Marketing, HR and IT separately — they will each name a
tool the others forgot. Read your current SPF record for stale
include: lines.
Risk if skipped: you will discover the forgotten sender on the day you switch to enforcement, and the thing that stops working will be payroll or invoices.
Goal — one correct SPF record that fails soft.
Do: create a single TXT record on the domain apex listing every provider from
step 0, ending in ~all. Use the record builder below.
Prefer include: tokens from your vendor's documentation over hand-typed IP
addresses.
Verify: exactly one record starts with v=spf1; the recursive lookup
count is ≤10; a test message shows spf=pass in
Authentication-Results.
Wait: one TTL (lower the TTL to 300 s a day before you make changes, then raise it again afterwards).
Risks: two SPF records or >10 lookups →
permerror and SPF is effectively off; going straight to -all with an
incomplete list → legitimate mail rejected immediately; using mx out of habit
authorises your inbound servers, which is not what you meant.
Goal — every legitimate message carries a signature with
d=yourdomain.
Do: in each platform, enable DKIM / “authenticate your domain” / “branded sending”. It will give you either a TXT record or one or more CNAMEs. Publish them, wait, then press the platform's “verify” button, then enable signing.
Verify: send a test to a Gmail address and to a Microsoft 365 address; the
header must show dkim=pass and header.d=yourdomain.com. If
d= shows the vendor's domain, you have enabled their shared signing, not yours —
find the “custom/branded domain” setting.
Wait: propagation, typically minutes to a few hours.
Risks: enabling signing before DNS resolves → every message
fails DKIM; leaving t=y test mode on forever; 1024-bit keys where 2048 was
available; forgetting one platform, which then becomes the thing that breaks at step 6.
Goal — start collecting evidence. Nothing changes for anyone.
Do: add a TXT record at _dmarc.yourdomain.com:
v=DMARC1; p=none; rua=mailto:[email protected]; fo=1;
Verify: the record resolves; the mailbox exists and is monitored; reports start arriving within 24–72 hours.
Risk: essentially zero — p=none changes no
delivery decision. The only real mistakes are pointing rua at a mailbox nobody
reads, or at an external analyser without its authorisation record (see the DMARC section), so
the reports never arrive at all.
Goal — a complete inventory of who sends as you, from the data rather than from memory.
Do: feed the XML into an analyser (or a spreadsheet). Sort every source IP into the four buckets from the DMARC section. Chase down every unknown source until you can name it.
Verify: you can account for >98% of your volume, and the remainder is low-volume noise you have consciously decided to ignore.
Wait: at least one full monthly cycle if you have monthly processes — invoicing, payroll and annual renewals only show up when they run.
Risk of hurrying: a sender that only fires once a month is invisible in a two-week window, and you will block your own invoices in step 7.
Goal — every source in bucket 2 either aligns or is retired.
Do: for each failing-but-legitimate source, one of:
d= becomes yours.bounce.yourdomain.com) so SPF aligns too.
news.yourdomain.com, billing.yourdomain.com) — this isolates
reputation and makes each stream easy to reason about.Verify: the source appears as aligned in the next aggregate report.
Risk: this is where projects stall for a year. Assign an owner per sender with a date, or nothing will move.
Goal — failing mail goes to junk instead of the inbox, gradually.
Do: tighten SPF from ~all to -all first, then step the
DMARC policy over two to four weeks:
v=DMARC1; p=quarantine; pct=25; rua=mailto:[email protected]; fo=1;
… then pct=50 … then pct=100
Verify: after each increase, check reports and your helpdesk queue for two to three days before increasing again.
Tell people first: warn IT support and department heads that some mail may land in junk, and give them a single place to report it.
Risks: legitimate mail junked (recoverable — the user can
still find it); auto-forwarded mail failing SPF but usually saved by DKIM or ARC; mailing lists
that rewrite subjects breaking DKIM. pct is your dimmer switch — use it.
Goal — nobody can send mail as your domain. This is the actual protection.
v=DMARC1; p=reject; sp=reject; rua=mailto:[email protected]; fo=1;
Do: move to p=reject once a full reporting cycle at
quarantine; pct=100 is clean. Set sp=reject explicitly. Consider
adkim=s; aspf=s only if every stream is exactly aligned.
Verify: reports show near-zero failures from your own sources; spoofed traffic
now shows disposition reject.
Risks: failing mail is now bounced, not junked — unrecoverable. A newly onboarded vendor added after step 4 will break loudly. Some old-fashioned mailing lists will mangle messages beyond DKIM's tolerance; the mature ones rewrite the From address to their own domain precisely to avoid this.
Have a rollback ready: dropping back to p=quarantine is one DNS
edit plus a TTL. Keep the TTL low during the ramp.
Goal — parked, legacy and typo-defence domains cannot be abused either.
Do: on each non-sending domain publish:
@ TXT "v=spf1 -all"
_dmarc TXT "v=DMARC1; p=reject; sp=reject; rua=mailto:[email protected];"
*._domainkey TXT "v=DKIM1; p="
@ MX 0 .
Verify: a test message from an external tool to that domain is refused, and the records resolve.
Risk if skipped: forgotten domains are the favourite launch pad for invoice fraud, because they still carry your brand name. Also remember the domains you bought defensively and never configured.
Goal — the surrounding controls, now that identity is solved.
Do: enable DNSSEC at the registrar; publish MTA-STS in
testing mode plus TLS-RPT, then move MTA-STS to enforce; fix reverse
DNS if you run your own server; add BIMI if the marketing value justifies a VMC. Add
List-Unsubscribe and one-click support to all bulk mail.
Risk: MTA-STS in enforce with a wrong MX list
will make incoming mail fail. Always run it in testing first and read the
TLS reports.
Goal — the configuration decays without maintenance.
Risk if skipped: silent drift. The record still says
p=reject, but a stale include pushed you past ten lookups six months ago and SPF
has been in permerror ever since.
Tick what you use and copy the records out. Everything is computed locally — nothing
is sent anywhere. Always cross-check the include: value against your provider's own
documentation before publishing; vendors do change them.
Paste an SPF, DMARC, DKIM, BIMI or MTA-STS record and get it back in plain English, with the problems flagged. Parsing happens in your browser.
This is the only feature on the page that leaves your browser. When you press the button, the domain name you type is sent to a public DNS-over-HTTPS resolver (Cloudflare, falling back to Google) to read its public TXT records. Nothing else is transmitted, and nothing happens automatically. Some corporate networks block DNS-over-HTTPS entirely — if the lookup fails, that is usually why.
Almost every email authentication outage in the world is one of these. The symptom is what a user reports; the cause is what you will actually find.
| Symptom | Cause | Fix |
|---|---|---|
| All outbound mail suddenly rejected after a DNS change | -all published with an incomplete sender list, or a typo in an
include: |
Revert to ~all immediately, fix the list, re-test, re-tighten |
SPF reported as permerror; receivers behave as if you have no SPF |
More than 10 DNS lookups, or two v=spf1 records on one name |
Merge records; drop unused includes; replace mx/a with
ip4:; last resort, flatten |
| Marketing mail lands in junk while normal mail is fine | The bulk platform signs with its own d= — DMARC-unaligned |
Enable the vendor's custom DKIM domain and custom return-path |
| DKIM fails on every message right after enabling it | Signing switched on before the DNS key propagated, or the key was truncated by the DNS panel | Re-check the record character-for-character; long values must be split into ≤255-char quoted strings |
| Mail fails only when a recipient forwards it | SPF cannot survive forwarding; the forwarder is not the authorised sender | Nothing to fix — this is why DKIM alignment and ARC exist. Do not weaken your policy for it |
Mailing-list posts bounce after p=reject |
The list edits the subject or appends a footer, invalidating DKIM | Ask the list to enable From-rewriting or ARC; or post from a subdomain with a looser policy |
| No DMARC reports ever arrive | rua is on a different domain without the
_report._dmarc authorisation record — or the mailbox does not exist |
Publish the authorisation record on the reporting domain; verify the mailbox accepts mail |
| Everything passes, yet fraud still happens | Display-name spoof, lookalike domain, or a compromised real mailbox | DMARC cannot help here — see the what-if section. Training and out-of-band verification are the controls |
A subdomain is being spoofed although the apex is at p=reject |
An explicit sp=none, or a separate DMARC record on the subdomain that
overrides the parent |
Set sp=reject; audit for stray _dmarc records on subdomains
|
| Personal data ends up in a third party's system | ruf= forensic reports contain message content; rua pointed at
an external analyser |
Treat this as a processing decision: check your privacy notice and DPA before enabling
ruf |
| Spoofing resumes months after the project “finished” | A new vendor was added to SPF, pushing lookups past 10 — SPF silently died | Quarterly audit; automated monitoring of the record's lookup count |
| Someone else's mail is signed as you | A leaked or shared DKIM private key, or a hosting provider's shared signing domain | Rotate the key, revoke the old selector with an empty p=, review who has
platform admin |
+all found in the record |
Copy-pasted from a bad tutorial, or a “fix” for a delivery problem | Remove it now. It authorises the entire internet to send as you |
| Incoming mail stops after enabling MTA-STS | The policy file lists the wrong MX hosts, or the certificate does not match | Set mode: testing, read TLS-RPT, only then move to enforce
|
| Changes take a day to appear | A long TTL, or resolvers caching an NXDOMAIN | Lower the TTL to 300 s before a change window; raise it again afterwards |
| An old domain you forgot about is sending invoices | A parked or expired-project domain with no SPF/DMARC at all | Step 8 — lock every non-sending domain down |
A customer forwards you an email. It has your logo, your signature and your name — and a bank account that is not yours. Here is how to tell what actually happened and what to do about it, in order.
They look identical to a victim, and they need completely different responses.
From: [email protected] — genuinely your domain, not sent by you.
Tell-tale: dmarc=fail or spf=fail in the headers; the
sending IP is unknown to you; it appears in your DMARC reports as an unaligned source.
You can stop this completely. DMARC at
p=reject makes it undeliverable to every serious mail provider.
From: "Your Company Billing" <[email protected]>
Tell-tale: everything authenticates — for gmail.com. Phones show only the friendly name, which is why this works so well.
DMARC cannot help. Mitigations: an external-sender banner, an inbound rule flagging your own executives' names arriving from outside, and training.
yourdornain.com, your-domain.com,
yourdomain.co, yourdomain-invoices.com
Tell-tale: perfect authentication for a domain registered eleven days ago. Check the registration date.
DMARC cannot help — it is not your domain. Response: registrar abuse report, hosting abuse report, blocklist submissions, and an inbound filter rule for near-miss variants of your name.
A real-looking From: with
Reply-To: [email protected].
Tell-tale: the reply address only becomes visible when you press Reply. Often combined with types 2 and 3.
Mitigation: a rule that flags a Reply-To whose domain differs
from From, plus the habit of checking before answering anything about money.
The mail really was sent from your account. SPF, DKIM and DMARC all pass, because it is authentic.
Tell-tale: the message appears (or suspiciously does not appear) in Sent Items; unfamiliar sign-in locations; a hidden inbox rule moving replies to RSS Feeds or Deleted Items; a mail thread that quotes real internal history.
The worst case, and the most common in real fraud. Treat it as an active incident, not an email problem — go to the account recovery steps below.
Authentication-Results and the From, Return-Path
and Reply-To fields. That determines which of the five types you have.
Paste it into the header analyzer if you want it decoded.p=none, this is the moment the risk calculus changes — move to
quarantine at minimum, and to reject if your reports are clean. If you
have no DMARC at all, publish p=none with rua today and start the
ramp.
The honest limit: you cannot stop a stranger from typing your name into a From field, registering a similar domain, or writing a convincing letter. What you can do is make your real domain impossible to forge, make lookalikes short-lived, and make sure that no single email can move money. Everything above serves one of those three.
Hand this part to colleagues. No jargon required.
yourbank.com.secure-login.xyz/… is
secure-login.xyz. Look for swapped letters (rn/m, l/I, 0/O) and extra hyphens.
In Gmail: ⋮ → Show original. In Outlook: File → Properties, or open the message and use … → View → View message source. Look for one line:
Authentication-Results: mx.example.net;
spf=pass smtp.mailfrom=sender.com;
dkim=pass header.d=sender.com;
dmarc=pass header.from=sender.com
dmarc=pass means only that the message really came from the domain shown. It
does not mean the domain is trustworthy — spammers pass DMARC on their own domains
all day long.dmarc=fail on a message claiming to be from a big brand is close to proof of
forgery.Authentication-Results at all usually means the message never left your own
organisation — or that you are looking at a header the attacker wrote.header.from with smtp.mailfrom and
header.d. Three different domains deserve suspicion.
Never trust these as proof: a logo, a real signature block, a padlock on the linked site, a correct invoice number, or the fact that the message is a reply inside a real thread. All of them are copied or stolen routinely.
Ticks are stored in this browser only, so you can close the tab and come back.
From:. Without it, SPF and DKIM prove nothing to a reader.
none, quarantine
or reject. Shown in DMARC reports.MAIL FROM address used during the SMTP conversation; where bounces go. Checked
by SPF, invisible to readers.include: with the IP addresses they currently resolve to, to stay under
the 10-lookup limit. Works, but you now own a list that your provider will change without
telling you.selector1 in
selector1._domainkey.example.com.
~all — “this probably isn't us, but accept it anyway”. The safe intermediate
state.sp= in DMARC. Governs everything under your domain, which is where attackers go
when the apex is locked.All three. SPF alone validates an address nobody sees and breaks on forwarding. DKIM alone proves
integrity but tells receivers nothing about what to do when it fails. DMARC is what connects either
of them to the visible From: and states a policy. One or two out of three is a very
common configuration and it stops approximately no fraud.
Done properly, the opposite: aligned, authenticated mail is treated better everywhere, and Gmail,
Yahoo and Microsoft now require it from bulk senders. Done in a hurry — jumping to
p=reject before fixing alignment — it will absolutely bounce your own mail. The ramp
exists for a reason.
-all and skip DMARC?No. -all constrains the envelope only. An attacker simply uses their own domain in the
envelope — SPF passes for that domain — and puts yours in the header. Nothing in SPF looks at the
header.
The DNS edits take an afternoon. The discovery takes weeks, because you have to see a full business cycle of your own mail in the reports. Small organisation: 4–6 weeks. Enterprise with dozens of senders: a quarter or more. Rushing does not compress the discovery — it just moves the discovery to the day you break something.
They inherit p unless you set sp, and a DMARC record published directly on
a subdomain overrides everything the parent says. Audit for stray _dmarc records, set
sp=reject explicitly, and give bulk mail its own subdomain so its reputation stays away
from your invoices.
Then check the d= value on a real message. If it is their domain, DMARC does
not align and their signature protects their reputation, not yours. Ask for custom/branded domain
signing — every serious platform offers it.
The records themselves are free — they are DNS entries. Report analysis tools cost money above a free tier, and a BIMI VMC is a genuine annual expense. Nothing about SPF, DKIM or DMARC itself requires a purchase.
Small companies are the preferred target for invoice fraud, precisely because they have no policy and no verification procedure. For you the entire job is roughly: turn on DKIM in your mail provider, publish two DNS records, and agree out loud that bank details are never changed by email. That is an hour of work against the most common financial crime you will face.
The specifications, if you want the primary sources: RFC 7208 (SPF),
RFC 6376 (DKIM), RFC 7489 (DMARC), RFC 8617 (ARC),
RFC 8461 (MTA-STS), RFC 8460 (TLS-RPT), RFC 7505
(Null MX), RFC 5321/5322 (SMTP and the message format). Vendor
include: values and DKIM selectors change over time — always confirm them in your
provider's current documentation rather than in any guide, including this one.