DKIM / SPF / DMARC Reference

Email Authentication & Domain Policy Engineering

A protocol-level reference for engineers operating production mail infrastructure. Covers SPF, DKIM, DMARC, ARC, BIMI, MTA-STS, and DANE — from DNS record syntax to verification logic, alignment semantics, failure taxonomy, and operational runbooks.

RFC 7208 SPF RFC 6376 DKIM RFC 7489 DMARC RFC 8617 ARC RFC 8461 MTA-STS RFC 8460 TLSRPT

1. How the Pieces Fit Together

SPF, DKIM, and DMARC are independent protocols that combine into a layered authentication framework. Each solves a different piece of the sender-identity problem. DMARC is the policy layer that ties SPF and DKIM to the human-visible From: header domain.

SPF

Answers: "Is this IP authorized to send for this envelope domain?"

  • Operates on the envelope MAIL FROM (return-path), not the From: header.
  • DNS TXT record on the domain, checked at the receiving MTA.
  • Breaks on forwarding (new sending IP not in original SPF).

DKIM

Answers: "Was this message actually sent by the claimed signing domain, unmodified?"

  • Cryptographic signature over selected headers and body.
  • Survives forwarding as long as signed content is not modified.
  • Key published as DNS TXT record under selector._domainkey.domain.

DMARC

Answers: "What should receivers do if SPF and DKIM both fail to align with the From: domain?"

  • Policy record at _dmarc.domain.
  • Requires alignment: SPF domain or DKIM d= must match From:.
  • Provides aggregate (rua) and forensic (ruf) reporting.

2. SPF — Sender Policy Framework

SPF is a DNS-based authorization list for sending IPs. The receiving MTA checks the MAIL FROM domain's TXT record against the connecting IP. Simple concept, subtle operational pitfalls.

Record Syntax

SPF record anatomyDNS TXT on domain apex
example.com. IN TXT "v=spf1 ip4:203.0.113.0/24 ip6:2001:db8::/32 include:_spf.google.com include:spf.protection.outlook.com mx a:relay.example.com -all"
                     │      │                  │                 │                       │                                  │  │                   │
                     │      │                  │                 │                       │                                  │  │                   └─ hard fail everything else
                     │      │                  │                 │                       │                                  │  └─ allow A record of relay.example.com
                     │      │                  │                 │                       │                                  └─ allow domain's MX hosts
                     │      │                  │                 │                       └─ include O365 SPF
                     │      │                  │                 └─ include Google Workspace SPF
                     │      │                  └─ allow this IPv6 block
                     │      └─ allow this IPv4 CIDR
                     └─ version (required, must be first)

Mechanisms

MechanismSyntaxWhat It MatchesDNS Lookups
ip4ip4:203.0.113.0/24Connecting IP in CIDR range0
ip6ip6:2001:db8::/32Connecting IPv6 in range0
aa or a:host.example.comIP matches A/AAAA record of domain1
mxmx or mx:example.comIP matches an MX host of domain1 + 1 per MX
includeinclude:_spf.google.comDelegate to another SPF record1 + recursive
redirectredirect=_spf.example.comReplace entire policy with another record1 + recursive
existsexists:%{i}._spf.example.comTrue if A record exists for macro-expanded name1
all-all / ~all / ?allMatch everything (catch-all at end)0

Qualifiers

QualifierMeaningDMARC EffectRecommendation
+ (Pass)Authorized (default if omitted)SPF passImplicit on mechanisms
- (Fail)Explicitly unauthorizedSPF failUse for production -all
~ (SoftFail)Unauthorized but transitionalSPF fail for DMARCOnly during rollout / testing
? (Neutral)No assertionSPF fail for DMARCRarely useful

The 10-lookup limit is real and ruthless. SPF evaluation must not cause more than 10 DNS lookups (includes include, a, mx, redirect, exists — but NOT ip4/ip6). Exceeding it returns permerror, which DMARC treats as a fail. Nested include chains from SaaS providers are the #1 cause.

SPF Flattening

before flattening (6 lookups from includes alone)danger zone
v=spf1 include:_spf.google.com include:spf.protection.outlook.com include:sendgrid.net include:spf.brevo.com mx -all
# _spf.google.com itself chains 3 more includes = total ~9-10 lookups
after flattening (0 lookups, all resolved to CIDRs)safe but requires maintenance
v=spf1 ip4:209.85.128.0/17 ip4:74.125.0.0/16 ip4:64.233.160.0/19 ip4:108.177.8.0/21
       ip4:172.217.0.0/16 ip4:40.92.0.0/15 ip4:40.107.0.0/16 ip4:52.100.0.0/14
       ip4:167.89.0.0/17 ip4:149.72.0.0/16 -all
# WARNING: Provider IPs change. Automate re-flattening on a schedule or use a dedicated subdomain per provider.

Better approach: subdomain delegation. Instead of flattening, send via subdomains with isolated SPF: marketing.example.comv=spf1 include:sendgrid.net -all, transactional.example.comv=spf1 include:_spf.google.com -all. Each subdomain stays well under 10 lookups and DMARC alignment still works with relaxed mode.

SPF and Forwarding

3. DKIM — DomainKeys Identified Mail

DKIM adds a cryptographic signature to outbound messages. The receiving MTA retrieves the public key from DNS and verifies the signature over the specified headers and body hash. Unlike SPF, DKIM survives forwarding as long as the signed content is not modified.

DKIM-Signature Header Anatomy

DKIM-Signature headereach tag explained
DKIM-Signature: v=1;                          # Version (always 1)
    a=rsa-sha256;                              # Algorithm (rsa-sha256 or ed25519-sha256)
    d=example.com;                             # Signing domain (DMARC aligns against this)
    s=s2026;                                   # Selector (DNS lookup: s2026._domainkey.example.com)
    c=relaxed/relaxed;                         # Canonicalization: header/body
    q=dns/txt;                                 # Query method
    t=1739620800;                              # Timestamp (Unix epoch, signing time)
    x=1740225600;                              # Expiration (optional, 7 days later here)
    h=from:to:subject:date:message-id:         # Signed headers (order matters)
      mime-version:content-type;
    bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=;  # Body hash (SHA-256)
    b=LjIGMtqFkFqJCZ9sdoMcyBPuv...               # Signature (Base64)

DNS Key Record

DKIM DNS TXT recordat selector._domainkey.domain
# RSA 2048-bit key
s2026._domainkey.example.com. 3600 IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2K4PavXoNY8eGK2u..."

# Ed25519 key (much shorter, gaining adoption)
s2026ed._domainkey.example.com. 3600 IN TXT "v=DKIM1; k=ed25519; p=11qYAYKxCrfVS/7TyWQHOg7hcvPapiMlrwIaaPcHURo="

# Key with testing flag (t=y means verifiers should treat failures leniently)
stest._domainkey.example.com. 3600 IN TXT "v=DKIM1; k=rsa; t=y; p=MIIBIjAN..."

# Revoked key (empty p= signals key is no longer valid)
sold._domainkey.example.com. 3600 IN TXT "v=DKIM1; p="

Canonicalization Modes

ModeHeadersBodyRecommendation
simple/simple No changes allowed Only trailing empty lines ignored Strictest, breaks on any modification
relaxed/relaxed Lowercased, whitespace folded Whitespace normalized, trailing lines removed Use this. Tolerates common MTA reformatting
relaxed/simple Relaxed Strict Compromise; rarely needed

Which Headers to Sign

Must Sign

  • From — required by RFC 6376, DMARC alignment key
  • To, Subject, Date — core identity/content
  • Message-ID — traceability
  • MIME-Version, Content-Type — body interpretation

Should Sign

  • Reply-To, Cc — prevents tampering
  • In-Reply-To, References — threading integrity
  • List-Unsubscribe — anti-phishing
  • Do not sign Received or relay-added headers — they change in transit

Key Rotation Strategy

Week 0: Publish new
Add s2026b._domainkey TXT record with new public key. Old key still active.
Week 1: Dual-sign
Configure MTA to sign with both selectors. Receivers cache DNS; dual-sign bridges propagation.
Week 2: Switch primary
Change MTA to sign only with new selector s2026b. Old signatures still verify against old DNS key.
Week 4: Revoke old
Set old key record to p= (empty). Messages with stale cached old key now fail DKIM (which is fine — they're old).
Week 6+: Cleanup
Optionally remove old selector record entirely. Document rotation in ops calendar.

RSA key size matters. 1024-bit RSA keys are considered weak and will be rejected by some receivers. Use 2048-bit minimum. Note: 2048-bit keys exceed the 255-byte TXT string limit — split across multiple strings in the TXT record (most DNS providers handle this automatically).

Ed25519 is the future. Much smaller keys (~44 bytes vs ~400 for RSA-2048), no TXT splitting needed, faster to sign/verify. Support is growing but not universal. Consider dual-signing with both RSA and Ed25519 during transition.

4. DMARC — Domain-based Message Authentication, Reporting & Conformance

DMARC is the policy and reporting layer. It checks whether SPF or DKIM results align with the From: header domain, and tells receivers what to do on failure. Without DMARC, SPF and DKIM results are advisory — receivers decide independently what to do.

Record Syntax

DMARC DNS TXT recordat _dmarc.domain
# Monitoring only (start here)
_dmarc.example.com. IN TXT "v=DMARC1; p=none; rua=mailto:dmarc-agg@example.com; ruf=mailto:dmarc-forensic@example.com"

# Quarantine policy with strict DKIM, relaxed SPF
_dmarc.example.com. IN TXT "v=DMARC1; p=quarantine; sp=quarantine; adkim=s; aspf=r; pct=100; rua=mailto:dmarc-agg@example.com; fo=1"

# Full reject (target state for mature domains)
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; sp=reject; adkim=s; aspf=s; rua=mailto:dmarc-agg@example.com; ruf=mailto:dmarc-forensic@example.com; fo=1"

Tag Reference

TagValuesDefaultPurpose
vDMARC1requiredVersion identifier (must be first tag)
pnone / quarantine / rejectrequiredPolicy for domain
spnone / quarantine / rejectfalls back to pPolicy for subdomains
adkimr (relaxed) / s (strict)rDKIM alignment mode
aspfr (relaxed) / s (strict)rSPF alignment mode
pct0100100% of messages subject to policy (for gradual rollout)
ruamailto:addrnoneAggregate report destination (daily XML)
rufmailto:addrnoneForensic/failure report destination (per-message)
fo0 / 1 / d / s0Failure reporting options: 0=both fail, 1=either fails, d=DKIM fail, s=SPF fail
riseconds86400Aggregate report interval (most receivers ignore this)

Alignment: Relaxed vs Strict

Relaxed (default)

Organizational domain match. Subdomains of the From: domain are accepted.

  • From: user@mail.example.com
  • DKIM d=example.comaligned
  • SPF pass on bounce.example.comaligned

Strict

Exact domain match required. No subdomain tolerance.

  • From: user@mail.example.com
  • DKIM d=example.comnot aligned
  • DKIM d=mail.example.comaligned
  • Use strict when you need precise subdomain control.

DMARC Rollout Path

Phase 1: Monitor
p=none; rua=mailto:... — Collect reports for 2-4 weeks. Identify all legitimate senders.
Phase 2: Soft enforce
p=quarantine; pct=10 — Quarantine 10% of failures. Monitor rua reports for false positives.
Phase 3: Ramp up
p=quarantine; pct=50 then pct=100 — Gradually increase enforcement. Fix remaining senders.
Phase 4: Reject
p=reject; pct=25 then pct=100 — Hard reject unauthorized messages. Final target state.
Ongoing
Ingest aggregate reports continuously. Alert on unexpected source IPs or alignment failures. Audit on provider changes.

Aggregate Report (rua) Structure

DMARC aggregate report XMLdaily, from each receiver
<feedback>
  <report_metadata>
    <org_name>google.com</org_name>
    <date_range><begin>1739577600</begin><end>1739664000</end></date_range>
  </report_metadata>
  <policy_published>
    <domain>example.com</domain>
    <p>quarantine</p>
    <sp>quarantine</sp>
    <adkim>s</adkim>
    <aspf>r</aspf>
    <pct>100</pct>
  </policy_published>
  <record>
    <row>
      <source_ip>203.0.113.45</source_ip>
      <count>1482</count>
      <policy_evaluated>
        <disposition>none</disposition>
        <dkim>pass</dkim>
        <spf>pass</spf>
      </policy_evaluated>
    </row>
    <row>
      <source_ip>198.51.100.99</source_ip>
      <count>23</count>
      <policy_evaluated>
        <disposition>quarantine</disposition>
        <dkim>fail</dkim>
        <spf>fail</spf>
      </policy_evaluated>
    </row>
  </record>
</feedback>

Cross-domain rua reporting requires authorization. If your DMARC record sends reports to a different domain (rua=mailto:reports@monitoring.net), the target domain must publish a TXT record: example.com._report._dmarc.monitoring.net. IN TXT "v=DMARC1"

5. ARC — Authenticated Received Chain

ARC preserves authentication results across forwarding hops where SPF and DKIM would otherwise break. Each intermediary adds a set of three headers forming a verifiable chain of custody.

ARC Header Set (per hop)

  • ARC-Authentication-Results (AAR) — snapshot of auth results at this hop
  • ARC-Message-Signature (AMS) — DKIM-like signature of the message at this hop
  • ARC-Seal (AS) — signature over the chain of all previous ARC sets + this AAR

Each set is numbered (i=1, i=2, ...) forming an ordered chain.

When ARC Helps

  • Mailing list servers that modify Subject or body (breaks DKIM)
  • Email forwarding services (.forward, alias expansion)
  • Security gateways that re-wrap or add disclaimers
  • Receivers can trust ARC from known intermediaries to override DMARC failure
ARC headers after one forwarding hopi=1 chain
ARC-Seal: i=1; a=rsa-sha256; cv=none; d=forwarder.net; s=arc2026;
    b=dOdFEyhrk/...
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=forwarder.net; s=arc2026;
    h=from:to:subject:date:message-id;
    bh=2jUSOH9NhtVGCQWNr9BrI...;
    b=Kf8mMGUa7/...
ARC-Authentication-Results: i=1; forwarder.net;
    dkim=pass header.d=example.com header.s=s2026;
    spf=pass smtp.mailfrom=example.com;
    dmarc=pass header.from=example.com

# cv= values: "none" (first hop), "pass" (chain valid), "fail" (chain broken)

6. BIMI — Brand Indicators for Message Identification

BIMI displays a brand logo next to authenticated messages in supporting email clients. It requires DMARC p=quarantine or p=reject as a prerequisite.

BIMI DNS recordTXT at default._bimi.domain
# Basic (logo only, some providers require VMC)
default._bimi.example.com. IN TXT "v=BIMI1; l=https://example.com/brand/logo.svg"

# With Verified Mark Certificate (required by Gmail, Apple Mail)
default._bimi.example.com. IN TXT "v=BIMI1; l=https://example.com/brand/logo.svg; a=https://example.com/brand/vmc.pem"

Requirements

  • DMARC policy of quarantine or reject (not none)
  • Logo must be SVG Tiny PS format (specific profile)
  • Logo hosted on HTTPS with valid certificate
  • VMC (Verified Mark Certificate) required by Gmail — issued by DigiCert or Entrust

Supported Clients

  • Gmail — requires VMC
  • Apple Mail — requires VMC (iOS 16+, macOS Ventura+)
  • Yahoo/AOL — VMC optional
  • Outlook — limited/pilot support
  • Thunderbird — not yet supported

7. MTA-STS & DANE — Transport Security

SPF/DKIM/DMARC authenticate the sender. MTA-STS and DANE authenticate the transport channel, preventing TLS downgrade and man-in-the-middle attacks on SMTP connections.

MTA-STS (RFC 8461)

HTTPS-based policy that tells senders: "only deliver to my MX hosts over verified TLS."

  • DNS: _mta-sts.example.com. IN TXT "v=STSv1; id=20260215"
  • HTTPS: https://mta-sts.example.com/.well-known/mta-sts.txt
  • Policy specifies valid MX hostnames and mode (enforce/testing/none)
  • Change the id value whenever you update the HTTPS policy file
mta-sts.txt policy filehosted at well-known URL
version: STSv1
mode: enforce
mx: mx1.example.com
mx: mx2.example.com
mx: *.example.com
max_age: 604800

DANE / TLSA (RFC 7672)

DNSSEC-based certificate pinning for SMTP. Stronger than MTA-STS but requires DNSSEC.

  • Publishes certificate fingerprint or CA constraint as TLSA record
  • Requires full DNSSEC chain on the MX domain
  • No HTTPS dependency (unlike MTA-STS)
  • Used by Postfix, Exim, and other DANE-aware MTAs
TLSA record examplepins leaf certificate
# Usage=3 (DANE-EE), Selector=1 (SubjectPublicKeyInfo), Matching=1 (SHA-256)
_25._tcp.mx1.example.com. IN TLSA 3 1 1 (
    2bb183af2b1c057d0f256891c...
)
TLS-RPT recordreceive TLS failure reports
_smtp._tls.example.com. IN TXT "v=TLSRPTv1; rua=mailto:tlsrpt@example.com"

# Reports include:
# - Negotiation failures (certificate errors, protocol mismatches)
# - MTA-STS policy validation failures
# - DANE/TLSA validation failures

8. Validation & Debugging Toolkit

Always validate DNS records before and after changes. A single typo in an SPF record can cause permerror for your entire domain. These commands should be muscle memory.

DNS query toolkitdig-based validation
# SPF record
dig +short TXT example.com | grep spf

# DKIM public key (replace selector)
dig +short TXT s2026._domainkey.example.com

# DMARC policy
dig +short TXT _dmarc.example.com

# BIMI record
dig +short TXT default._bimi.example.com

# MTA-STS policy indicator
dig +short TXT _mta-sts.example.com

# TLS-RPT
dig +short TXT _smtp._tls.example.com

# MX records (for SPF mx mechanism validation)
dig +short MX example.com

# DANE/TLSA
dig +short TLSA _25._tcp.mx1.example.com

# Check for multiple TXT records (common misconfiguration)
dig TXT example.com +noall +answer | grep -c "v=spf1"
# Should return 1. Multiple SPF records = permerror.
reading authentication-results headersin received messages
Authentication-Results: mx.google.com;
    dkim=pass header.i=@example.com header.s=s2026 header.b=LjIGMt;
    spf=pass (google.com: domain of bounce@example.com designates 203.0.113.45 as permitted sender) smtp.mailfrom=bounce@example.com;
    dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=example.com

# Key fields to check:
# dkim=pass/fail    + header.d= (signing domain) + header.s= (selector)
# spf=pass/fail     + smtp.mailfrom= (envelope sender)
# dmarc=pass/fail   + header.from= (RFC5322 From) + dis= (disposition applied)
Tool / ServicePurposeNotes
dig / drillRaw DNS queriesEssential. Check TXT, MX, TLSA records directly.
opendkim-testkeyValidate DKIM key publicationopendkim-testkey -d example.com -s s2026 -vvv
spfquery / pyspfSPF record evaluationTest specific IP against domain's SPF policy
Mail-tester.comSend a test email, get full reportQuick deliverability and auth check
MXToolboxOnline DNS/SPF/DKIM/DMARC checkerGood for quick validation, shows lookup count
dmarcian / ValimailDMARC aggregate report analysisParses rua XML into dashboards
swaksSwiss Army Knife for SMTPswaks --to test@example.com --from me@example.com --server mx.example.com
Google Postmaster ToolsReputation and auth metrics for GmailDomain-level DKIM/SPF/DMARC pass rates

9. Common Failure Patterns & Root Causes

Most email authentication failures come from a small set of misconfigurations. Learn to recognize these patterns in aggregate reports and Authentication-Results headers.

SymptomAuth-ResultsRoot CauseFix
SPF permerror spf=permerror >10 DNS lookups, syntax error, or multiple SPF TXT records Flatten includes, remove duplicates, use subdomain delegation
SPF fail on forwarded mail spf=fail Forwarding server IP not in sender's SPF Implement SRS on forwarder, rely on DKIM + ARC for DMARC
DKIM fail: body hash mismatch dkim=fail (body hash did not verify) Message body modified in transit (footer added, encoding changed) Fix intermediary, use l= body length tag (risky), or ARC
DKIM fail: key not found dkim=fail (no key for signature) DNS key record missing, wrong selector, or propagation delay Verify dig TXT selector._domainkey.domain, wait for TTL
DMARC fail: alignment dmarc=fail, but spf=pass and/or dkim=pass SPF domain or DKIM d= doesn't match From: domain Sign with d= matching From: domain, or use relaxed alignment
DMARC fail: third-party sender dmarc=fail SaaS sends with your From: but no DKIM delegation Have vendor sign with your domain via CNAME'd DKIM selector
Sporadic DKIM temperror dkim=temperror DNS timeout for key lookup, often under receiver load Low TTL on key record, ensure nameserver reliability, add redundancy
SaaS SPF include bloat spf=permerror 5+ SaaS vendors each adding include: chains Dedicate subdomains per vendor, or flatten with automated tooling

10. Operational Runbooks & Hardening Checklists

Predefined runbooks for the most common authentication incidents. Separate immediate mitigation from root cause investigation.

Runbook: DMARC Reject Spike

  1. Pull latest DMARC aggregate reports (rua). Identify source IPs causing failures.
  2. Classify: is the failing source legitimate (SaaS vendor, internal system) or spoofing?
  3. If legitimate: add to SPF or configure DKIM delegation via vendor's CNAME setup.
  4. If spoofing: the policy is working correctly. No action needed. Monitor volume.
  5. If accidental policy change: revert DMARC/SPF/DKIM DNS records from version control.
  6. Temporarily set pct=0 if widespread legitimate breakage while fixing.

Runbook: DKIM Key Rotation

  1. Generate new keypair. Publish new selector DNS record with TTL=300.
  2. Wait for DNS propagation (2x TTL of old record).
  3. Configure MTA to dual-sign (old + new selector).
  4. Monitor DKIM pass rates in DMARC reports for 48-72h.
  5. Switch to new selector only. Keep old key published for 7 more days.
  6. Revoke old key: set p= (empty). Remove record after 30 days.

Runbook: New SaaS Email Vendor

  1. Assign a dedicated subdomain (e.g., mail.example.com) for the vendor.
  2. Add vendor's SPF include to the subdomain's SPF record (not the apex).
  3. Set up DKIM: create CNAME for vendor's selector under your _domainkey namespace.
  4. Publish DMARC on the subdomain (inherits from apex, or set explicitly).
  5. Send test messages and verify Authentication-Results shows all-pass.
  6. Monitor DMARC reports for 1 week before going live with production volume.

Hardening Checklist

domain authentication hardening baselineoperator reference
[ ] SPF record published with -all (hard fail), lookup count verified < 10
[ ] No duplicate SPF TXT records on same domain
[ ] DKIM signing enabled on all outbound paths with 2048-bit+ RSA or Ed25519
[ ] DKIM key rotation schedule documented (quarterly or on compromise)
[ ] All DKIM selectors verified via dig + opendkim-testkey
[ ] DMARC record at p=reject (or quarantine minimum) with rua configured
[ ] DMARC aggregate reports ingested and monitored (not just collected)
[ ] Subdomain policy (sp=) explicitly set, not relying on inheritance assumptions
[ ] SaaS vendors sending as your domain have DKIM CNAME delegation, not just SPF
[ ] ARC signing enabled on any forwarding/relay infrastructure you operate
[ ] MTA-STS policy published and mode=enforce for receiving domains
[ ] TLS-RPT record configured to receive transport failure reports
[ ] BIMI record published (if DMARC at reject and VMC obtained)
[ ] Null SPF on domains that don't send email: "v=spf1 -all"
[ ] Null DMARC on non-sending domains: "v=DMARC1; p=reject; sp=reject"
[ ] DNS records version-controlled with automated deployment

Don't forget non-sending domains. Every domain you own that does not send email should still have v=spf1 -all and v=DMARC1; p=reject to prevent spoofing. Attackers specifically target unprotected parked and legacy domains.

Complete DNS Record Set Example

production domain: example.comall authentication records
; === SPF ===
example.com.                      IN TXT "v=spf1 ip4:203.0.113.0/24 include:_spf.google.com -all"

; === DKIM ===
s2026._domainkey.example.com.     IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQE..."
s2026ed._domainkey.example.com.   IN TXT "v=DKIM1; k=ed25519; p=11qYAYKxCrfVS/7TyWQH..."

; === DMARC ===
_dmarc.example.com.               IN TXT "v=DMARC1; p=reject; sp=reject; adkim=s; aspf=r; fo=1; rua=mailto:dmarc-agg@example.com; ruf=mailto:dmarc-forensic@example.com"

; === BIMI ===
default._bimi.example.com.        IN TXT "v=BIMI1; l=https://example.com/.well-known/logo.svg; a=https://example.com/.well-known/vmc.pem"

; === MTA-STS ===
_mta-sts.example.com.             IN TXT "v=STSv1; id=20260215t1"

; === TLS-RPT ===
_smtp._tls.example.com.           IN TXT "v=TLSRPTv1; rua=mailto:tlsrpt@example.com"

; === Non-sending subdomain protection ===
parked.example.com.               IN TXT "v=spf1 -all"
_dmarc.parked.example.com.        IN TXT "v=DMARC1; p=reject"