Kage Security Lab

Email security setup guide

Step-by-step DNS records to stop spoofing of your domain and secure mail delivery: SPF, DKIM, DMARC, MX, MTA-STS, TLS-RPT, BIMI, DNSSEC and CAA.

Before you start

Run the free Email security check on your domain. Its Suggested records section gives you the exact values for your domain; this guide explains what each record does and where to put it.

All records are added at your DNS provider, for example Cloudflare → your domain → DNS → Records → Add record. In most providers, the Name field takes the part before your domain (_dmarc, not _dmarc.example.com).

StepRecordEffortWhy this order
1TLS-RPT2 minutesStarts sending reports, no risk
2DKIM10 minutesNeeded before DMARC can be enforced safely
3SPF5 minutesLists every service that sends as you
4DMARC p=none → quarantine → reject2–6 weeksUse the reports to find legitimate senders first
5MTA-STS (testing → enforce)30 minutes + a few weeksNeeds a small HTTPS file
6BIMIOptionalOnly works once DMARC is enforced
7DNSSEC and CAA10 minutesProtects the DNS records themselves

MX: where your mail is delivered

MX records tell other servers where to deliver mail for your domain. Your mail provider gives you the value; you rarely change it.

ProviderTypeNameValuePriority
Microsoft 365MX@yourdomain-com.mail.protection.outlook.com0
Google WorkspaceMX@smtp.google.com1
Email gateway (Proofpoint, Mimecast…)MX@the hosts the vendor gives youas given
  • Keep only your provider's MX records and delete old ones.
  • MX records cannot be proxied (Cloudflare shows them as DNS only).
  • A domain that never receives mail should publish a null MX: 0 .
  • If a gateway sits in front of Microsoft 365, restrict Exchange Online to accept mail only from the gateway (an inbound connector), so attackers cannot bypass it.

SPF: who may send as you

One TXT record on the root of the domain.

TypeNameValue (Microsoft 365 example)
TXT@v=spf1 include:spf.protection.outlook.com -all
  • Add an include: for every service that sends as you: Google include:_spf.google.com, SendGrid include:sendgrid.net, Mailchimp include:servers.mcsv.net, Salesforce include:_spf.salesforce.com, and so on.
  • End with -all (others fail). Use ~all only while testing. Never +all or ?all.
  • Only one SPF record per domain, and no more than 10 DNS lookups in total. The email security check counts them for you.

DKIM: signing your mail

DKIM proves a message really came from you and was not changed. The key comes from your mail provider.

Microsoft 365

  1. Open the Microsoft Defender portal → Email & collaboration → Policies & rules → Threat policies → Email authentication settings → DKIM.
  2. Select your domain. It shows two CNAME records:

    TypeNameValue
    CNAMEselector1._domainkeyselector1-yourdomain-com._domainkey.<tenant>.onmicrosoft.com
    CNAMEselector2._domainkeyselector2-yourdomain-com._domainkey.<tenant>.onmicrosoft.com
  3. Add both at your DNS provider (DNS only, not proxied), wait a few minutes, then switch Sign messages for this domain with DKIM signatures on.

Google Workspace: Google Admin → Apps → Google Workspace → Gmail → Authenticate email → Generate new record → publish the TXT record at google._domainkey → Start authentication.

Other senders (marketing, CRM, helpdesk) each have their own DKIM setup page; enable it so their mail passes DMARC too.

DMARC: enforcing it

DMARC tells receivers what to do with mail that fails SPF and DKIM, and sends you reports.

StageTypeNameValueWhen
1. MonitorTXT_dmarcv=DMARC1; p=none; rua=mailto:dmarc@yourdomain.comDay 1
2. QuarantineTXT_dmarcv=DMARC1; p=quarantine; pct=100; rua=mailto:dmarc@yourdomain.comAfter 2–4 weeks of clean reports
3. RejectTXT_dmarcv=DMARC1; p=reject; rua=mailto:dmarc@yourdomain.comAfter 2–4 more weeks
  • Reports are XML files. A free reader makes them usable; on Cloudflare, Email → DMARC Management sets up the rua address and reads the reports for you.
  • Before each step, check that every legitimate sender in the reports passes SPF or DKIM.
  • Only one DMARC record. p=none does not stop spoofing; it only monitors.

MTA-STS: require encrypted delivery

Without MTA-STS, an attacker on the network path can downgrade mail delivery to unencrypted. MTA-STS tells sending servers to deliver to you only over verified TLS. It needs two things: a policy file served over HTTPS, and a TXT record.

1. The policy file

It must be served at exactly https://mta-sts.yourdomain.com/.well-known/mta-sts.txt with a valid certificate:

version: STSv1
mode: testing
mx: *.mail.protection.outlook.com
max_age: 86400
  • mx: lines must match your MX hosts. Microsoft 365: *.mail.protection.outlook.com. Google Workspace: smtp.google.com (older setups: aspmx.l.google.com and *.aspmx.l.google.com). Gateways: one line per MX host.
  • Start with mode: testing. Reports arrive through TLS-RPT, but delivery is never blocked.

2. Hosting the file

Option A: Cloudflare Worker (free, no server). Cloudflare → Workers & Pages → Create → Worker, name it mta-sts, replace the code with the snippet below and Deploy. Then open the Worker → Settings → Domains & Routes → Add → Custom domain → mta-sts.yourdomain.com.

const POLICY = `version: STSv1
mode: testing
mx: *.mail.protection.outlook.com
max_age: 86400
`;

export default {
  fetch(request) {
    const url = new URL(request.url);
    if (url.pathname === '/.well-known/mta-sts.txt') {
      return new Response(POLICY, { headers: { 'content-type': 'text/plain; charset=utf-8' } });
    }
    return new Response('Not found', { status: 404 });
  },
};

Option B: any static host (GitHub Pages, Azure Static Web Apps, Netlify, your web server). Create the file at /.well-known/mta-sts.txt, connect the host to mta-sts.yourdomain.com and make sure HTTPS works.

Check it: open https://mta-sts.yourdomain.com/.well-known/mta-sts.txt in a browser. You should see the four lines, with no redirect and no certificate warning.

3. The TXT record

TypeNameValue
TXT_mta-stsv=STSv1; id=20261031

The id can be any short value; using today's date is easiest. Change it every time you edit the policy file, or senders keep the old policy.

4. Enforce

After 2–4 weeks of TLS-RPT reports without failures, change the file to mode: enforce and max_age: 604800 (one week), then update the id in the TXT record.

TLS-RPT: delivery reports

TLS-RPT sends you a daily report when other servers have trouble delivering to you securely. Set it up together with MTA-STS.

TypeNameValue
TXT_smtp._tlsv=TLSRPTv1; rua=mailto:tls-reports@yourdomain.com

Use a mailbox you read. Reports are JSON files from Google, Microsoft and others; "successful sessions" with no failures means you are ready to enforce MTA-STS.

BIMI: your logo in the inbox

BIMI shows your logo next to your messages in mail apps that support it. It is optional and only works once DMARC is p=quarantine (with pct=100) or p=reject.

  1. Create a square SVG Tiny PS logo: version="1.2" baseProfile="tiny-ps", a <title>, a solid background, no scripts, images or links, under 32 KB.
  2. Host it over HTTPS, for example https://yourdomain.com/bimi.svg.
  3. Add the record:

    TypeNameValue
    TXTdefault._bimiv=BIMI1; l=https://yourdomain.com/bimi.svg; a=
  • Yahoo shows the logo with just this.
  • Gmail and Apple Mail also need a certificate: a VMC (requires a registered trademark) or a CMC, from DigiCert or Entrust. Put the certificate's .pem URL after a=.
  • Outlook / Microsoft 365 does not show BIMI logos for most mailboxes.

DNSSEC and CAA: protect the DNS itself

DNSSEC signs your DNS records so they cannot be forged in transit. On Cloudflare: DNS → Settings → Enable DNSSEC. If your domain is registered elsewhere, copy the DS record Cloudflare shows into your registrar's DNSSEC settings. If the registrar is Cloudflare, this is automatic.

CAA limits which certificate authorities may issue certificates for your domain.

TypeNameTagValue
CAA@iodefmailto:security@yourdomain.com
CAA@issuethe CA you use, e.g. letsencrypt.org

On Cloudflare with Universal SSL, Cloudflare automatically adds CAA records for the authorities it uses once you add your own, so its certificates keep renewing.

Check your progress

Run the Email security check after each step. A domain with SPF -all, DKIM, DMARC p=reject, MTA-STS, TLS-RPT and BIMI scores 100/100. The Security stack fingerprint shows what else your public DNS reveals.

Need help with a larger estate, several domains or third-party senders? Talk to an analyst.