# Email that leaves only from those entitled to send it.

> An SPF record isn't enough if it doesn't match who really sends. For several clients we set out who may send email, from where and for which domain, and made it stick.

- Sector: Cross-sector
- Practice: Security
- Year: 2026
- URL: https://cloudfactory.it/en/work/email-enforcement-spf-dkim-dmarc/

## In brief

On a hosting environment with 23 WordPress sites sending through Amazon SES, after an SMTP credential was used without authorisation we rotated keys and gave each site a policy allowing it to send only from its own domain and only from 11 server IPs. For a laboratory group we took DMARC up to p=reject. For a newsletter with about 89,500 blocks in one day we aligned sending through SendGrid. And we stopped an SPF record that would have shut out a legitimate sender.

- **23** WordPress sites with a dedicated SES policy
- **11** static server IPs on the allowlist
- **~89,500** messages blocked in one day on a newsletter
- **1,933** hard bounces removed from the list

## Context

SPF, DKIM and DMARC are often set up once and then forgotten. Meanwhile sending providers, servers and newsletter platforms change. We run email and DNS for several clients, and in 2026 we worked on all of these fronts.

## The problem

Email mistakes are silent in both directions. A permission that's too broad lets the wrong people send in your name: on a hosting environment, an SMTP credential was used for unauthorised bulk sending. A rule that's too strict, or unaligned sending, blocks legitimate mail: a newsletter saw about 89,500 blocks on 27 May 2026, 97.7% of them DMARC rejections.

## What we did

1. **One policy per site.** Keys rotated, 39 out of 41 were overdue for rotation, and unused users removed. Each site has its own IAM user with a restrictive policy: sending only from its own domain and only from an allowlist of 11 static IPs, everything else explicitly denied.
2. **Two subtle bugs, found during rollout.** The configuration-set permission was being dropped, and SES checks permission on the exact sender address, not just the domain. Both fixed, with event publishing through a bounce-tracking configuration set and CloudTrail checks on denied attempts.
3. **Staged DMARC.** For a laboratory group's domains, following an external security rating: p=none, then quarantine, then reject. Domains that never send email get v=spf1 -all and p=reject, so nobody can use them to spoof a sender.
4. **A newsletter realigned.** The blocks came from SendGrid sending that wasn't aligned with the domain. SendGrid domain authentication with 3 CNAME records, SPF cleaned up to stay under the 10 DNS-lookup limit, 1,933 hard bounces removed from the list.
5. **Check before applying.** A proposed SPF record, applied as written under p=reject, would have shut out a legitimate sender. We stopped it before it went live.

## How it went

On the domains we look after, who may send is written in DNS and in policies, and it holds. A key taken from one site can't send mail for the others, a non-sending domain can't be spoofed, and a newsletter passes checks because it is signed by the domain that sends it.

## Tools

Amazon SES, IAM, CloudTrail, SendGrid, SPF, DKIM, DMARC, WordPress, WP Mail SMTP

## FAQ

### Why not go straight to p=reject?

Because with p=reject every forgotten sender is rejected. You start at p=none, read the reports, align the senders and only then move to quarantine and reject.

### What is the 10-lookup SPF limit?

Evaluating an SPF record may take at most 10 DNS queries. Beyond that the check fails and legitimate mail risks rejection: every extra include has to earn its place.

### What does v=spf1 -all do on a domain that doesn't send?

It tells everyone that domain never sends email. Together with DMARC p=reject, it stops anyone using it to spoof a sender.

---

Cloudfactory S.r.l., Rome. Contact: hello@cloudfactory.it
