agentleFS
GoldenWing-360GoldenWing-360/claude-security-skills/email-deliverability-security/SKILL.md

email-deliverability-security

Skill16 starsChanged 6 months agoMITView on GitHub

Configure email authentication so legitimate mail lands and spoofed mail is blocked. Covers SPF, DKIM, DMARC (with the p=none → p=quarantine → p=reject migration path), MTA-STS, TLS-RPT, ARC, and BIMI. Invoke when launching a new sending domain, when domains are being spoofed, or when transactional email is landing in spam.

The file

We split this skill into the rules it gives an agent

6 rules. About 0 are common, 4 are distinctive, and 2 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈4

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    After a phishing wave that abused your domain

    line 19
  2. Very specific:

    10 DNS lookup limit: Every include: and a and mx mechanism counts.

    line 46
  3. Very specific:

    Add the records the ESP gives you, exactly.

    line 62
  4. Distinctive:

    Drop unused selectors: when you decommission an ESP — otherwise an attacker who somehow got the old key can keep signing.

    line 73
  5. Distinctive:

    If at any step the reports show a legitimate sender failing, pause and fix (add to SPF, get DKIM set up for that path) before advancing.

    line 112
  6. Distinctive:

    Look in reports for:

    line 125

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Email Authentication & Deliverability Security

Email security has two faces — inbound (don't get phished) and outbound (don't get spoofed, don't land in spam). This skill is about the outbound posture: configuring SPF, DKIM, DMARC, and friends so your real mail authenticates and impostors are rejected.

Done right, this is a one-evening project per domain that pays off forever. Done wrong, your password reset emails land in junk and attackers send invoices to your customers from accounting@yourdomain.com.

When to invoke

  • Launching a new sending domain
  • Your domain is being spoofed (you see bounce reports for mail you didn't send)
  • Transactional mail (password reset, receipts) consistently lands in spam
  • Consolidating from multiple ESPs to one
  • An auditor asks about your DMARC posture
  • After a phishing wave that abused your domain

The pieces — what each record does

RecordPurposeRequired?
SPFLists which servers are allowed to send for the domainYes
DKIMSigns each message with a key in DNS; receiver verifies signatureYes
DMARCTells receivers what to do when SPF or DKIM fails, and where to send reportsYes
MTA-STSForces TLS between sending and receiving MTAsRecommended
TLS-RPTReceives reports of TLS failuresRecommended
BIMIShows your brand logo in supporting mail clientsOptional, requires DMARC enforcement + VMC
ARCPreserves auth state when mail passes through forwarders (mailing lists)Receiver-side mostly, set up if you forward

A "fully authenticated" sending posture needs at least SPF + DKIM + DMARC with a real policy.

Step 1 — SPF

SPF lists every IP / hostname / third-party allowed to send from your domain.

v=spf1 mx include:_spf.google.com include:mailgun.org include:sendgrid.net -all

Key rules:

  • -all (hard fail) is the goal. ~all (soft fail) is acceptable as a stepping stone but eventually move to -all.
  • 10 DNS lookup limit. Every include: and a and mx mechanism counts. Many ESPs publish records that chain dozens of include: and silently push you over the limit. Use dmarcian's SPF surveyor to count.
  • Flatten if needed: services like mxtoolbox, spfwizard, or your own automation can resolve the chain to IPs once and produce a flat record. Refresh periodically — the providers change theirs.
  • One SPF record per domain. Multiple TXT records starting with v=spf1 is a permanent fail.

Verify

dig +short TXT example.com | grep -i 'v=spf1'

# Send a test mail to a Gmail address you own, view "Show original" — SPF: PASS

Step 2 — DKIM

DKIM is per-ESP. Each sending service gives you a public key to put in DNS; the ESP signs outgoing mail with the private key.

Add the records the ESP gives you, exactly. Common selectors: default._domainkey, mailgun._domainkey, s1._domainkey, etc.

mailgun._domainkey.example.com.   TXT  "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQ..."

Rules:

  • 2048-bit RSA preferred. Some providers still default to 1024 — 2048 is the standard for new deployments.
  • One selector per ESP, never reuse keys across providers.
  • Rotate periodically (annual is fine for low-stakes; quarterly for high-stakes). Providers usually have a rotation flow.
  • Drop unused selectors when you decommission an ESP — otherwise an attacker who somehow got the old key can keep signing.

Verify

dig +short TXT mailgun._domainkey.example.com

# Test mail to Gmail → Show original → DKIM: PASS, domain alignment OK

Step 3 — DMARC

DMARC ties SPF + DKIM together and tells receivers what to do on failure. It also gives you reports about who is sending mail as you (legitimate or otherwise).

Start in monitoring mode (p=none) — don't break your own mail by going straight to reject:

_dmarc.example.com.   TXT   "v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com; ruf=mailto:dmarc-forensic@example.com; fo=1; adkim=s; aspf=s"

Fields:

  • p=none|quarantine|reject — action when both SPF and DKIM fail to align. Start at none, watch reports for 2–4 weeks.
  • rua= — daily aggregate reports. Receive these; they tell you who is sending as you.
  • ruf= — per-failure forensic reports (often disabled by receivers due to privacy concerns).
  • adkim=s|r — strict or relaxed DKIM alignment. s is stricter; most ESPs work with r.
  • aspf=s|r — same for SPF.
  • pct= — percent of mail to apply the policy to (used during migration; default 100).

Migration path

Week 1–2:   p=none, pct=100     — collect reports, identify all legitimate senders
Week 3–4:   p=quarantine, pct=25 — 25% of failing mail goes to spam
Week 5–6:   p=quarantine, pct=100
Week 7–8:   p=reject, pct=25
Week 9+:    p=reject, pct=100    — fully enforced

If at any step the reports show a legitimate sender failing, pause and fix (add to SPF, get DKIM set up for that path) before advancing.

Reading aggregate reports

DMARC reports are XML. Use a parser — handling them by hand does not scale.

Free / cheap options:

Look in reports for:

  • All your real ESPs passing → good
  • Random IPs passing SPF/DKIM → potentially a misconfigured legitimate forwarder, or a sender you forgot about, or your domain is leaked via an ESP that shouldn't have it
  • Random IPs failing → spoofing attempts. Once p=reject is live, these get bounced.

Step 4 — MTA-STS

MTA-STS forces TLS between mail servers. Without it, an attacker on the path between sending and receiving MTAs can downgrade to plaintext.

Two pieces:

  1. DNS TXT record:

    _mta-sts.example.com.   TXT   "v=STSv1; id=20260512000000;"
  2. Policy file at https://mta-sts.example.com/.well-known/mta-sts.txt:

    version: STSv1
    mode: enforce
    mx: *.example.com
    max_age: 86400

mode: testing first if you're cautious; mode: enforce once you're sure your MX is reachable over TLS.

Step 5 — TLS-RPT

Pair with MTA-STS to get reports on TLS failures.

_smtp._tls.example.com.   TXT   "v=TLSRPTv1; rua=mailto:tls-reports@example.com"

Step 6 — BIMI (optional, brand polish)

BIMI shows your brand logo in supporting mail clients (Gmail, Yahoo, Apple Mail). Requires:

  • DMARC at p=quarantine or p=reject (so not on day one)
  • SVG logo at a public URL (specific spec — square aspect, basic profile)
  • Verified Mark Certificate (VMC, ~$1500/year from DigiCert or Entrust) for Gmail / Apple Mail to display
default._bimi.example.com.   TXT   "v=BIMI1; l=https://example.com/logo.svg; a=https://example.com/vmc.pem"

Skip until everything else is enforced. Marketing rather than security.

Common patterns and pitfalls

Subdomains. Receivers don't apply your apex DMARC policy to subdomains automatically. Either:

  • Set sp= in DMARC (subdomain policy) to specify
  • Set explicit DMARC records on mail.example.com, notifications.example.com, etc.

For subdomains you never send from, v=DMARC1; p=reject; keeps attackers from spoofing them.

Apex CNAME problem. Some DNS hosts allow CNAME at the apex (example.com) via flattening. Most don't. If you can't put TXT at the apex, your DNS host is wrong for email.

Forwarders break SPF. When your user has set up auto-forward in their inbox, the forwarded mail comes from a different IP — your SPF won't authorize it. DKIM still passes because the signature travels with the message. This is why DKIM is more reliable than SPF for delivery-quality scoring.

Mailing lists break DKIM. Lists often rewrite the From header or modify the body, breaking the signature. ARC was designed to preserve auth state across hops; receivers that honor ARC can still trust the original auth result. If you operate or rely on mailing lists, look into ARC.

Cold-start a new ESP. New IP / domain pairs have no reputation. Warm up by ramping volume gradually over 2–4 weeks. Sudden bulk from a new domain → straight to spam.

Multiple SPF records. Two v=spf1 records is the most common configuration error in the wild. Merge into one.

Forgotten test/staging subdomains. A forgotten record for staging.example.com pointing to an old IP, with no DMARC, is a beautiful spoofing target. Audit all sending subdomains.

Verification commands

DOMAIN=example.com

dig +short TXT $DOMAIN | grep 'v=spf1'
dig +short TXT _dmarc.$DOMAIN
dig +short TXT default._domainkey.$DOMAIN    # adjust selector
dig +short TXT mailgun._domainkey.$DOMAIN
dig +short TXT _mta-sts.$DOMAIN
dig +short TXT _smtp._tls.$DOMAIN

# End-to-end test — send mail to your-test@gmail.com, then in Gmail → Show original
# Check "Authentication-Results" header for:
#   spf=pass, dkim=pass, dmarc=pass

Inbound — accept what you should, reject what you should

Most of this skill is about outbound, but a quick note on inbound:

  • Set up DMARC reporting on inbound too — if you receive mail at dmarc-reports@example.com, the reports themselves are inbound mail and need a place to land
  • Reject mail with failing DKIM/SPF/DMARC at your own MX — most receivers (Gmail, Outlook, hosted ESPs) do this for you
  • Phishing of your own staff — separate skill / training; the technical layer here just makes it harder for attackers to spoof your domain

Checklist

For a fully-authenticated sending domain:

  • One SPF record at apex, all senders enumerated, -all (or ~all as interim)
  • SPF DNS lookup count under 10
  • DKIM key per ESP, 2048-bit, correct selector in DNS
  • DMARC record exists with rua= for aggregate reports
  • DMARC reports are flowing into a parser (Postmark, dmarcian, parsedmarc)
  • DMARC policy at p=quarantine or p=reject (not stuck at p=none forever)
  • Subdomains have explicit DMARC (or sp= on apex)
  • Non-sending domains have v=DMARC1; p=reject; sp=reject; to prevent spoofing
  • MTA-STS configured, mode enforce
  • TLS-RPT pointed at a real mailbox
  • Test mail to Gmail shows dkim=pass spf=pass dmarc=pass
  • Unused old DKIM selectors removed
  • Audit of all sending subdomains, including forgotten staging/test

What this skill will not do

  • Help send spam, phishing, or mail from domains you do not own
  • Recommend staying at p=none indefinitely once monitoring is established
  • Replace ESP-specific deliverability guidance (Mailgun / SendGrid / Postmark have product-specific advice on top of this)

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.