ItsBingMyBusiness

Developer Guides

Sending on behalf of your customers, correctly

If your product sends mail that appears to come from your customers, you are running a multi-tenant sending platform whether or not you planned to.

The decisions that matter get made early and are expensive to revisit.

Verify the domain

A customer who can send as any domain they type can send as anyone's. Verification — a token in DNS, proving control — is the minimum, and it has to happen before the first message, not as a later tidy-up.

Re-verify periodically. Domains change hands.

A DKIM key per customer domain

Sign with a key published under the customer's domain, so d= matches the From domain and DMARC aligns.

Signing everything with one shared key is simpler and wrong. It means every customer's mail authenticates as you, which fails alignment for all of them — see the alignment problem — and it means one compromised key affects everyone.

Generate per domain, store the private half encrypted, and give each customer a CNAME rather than a TXT value where you can. A CNAME lets you rotate the key without the customer touching DNS again, which is the difference between rotating keys on schedule and never rotating them.

Suppression per customer

Suppression lists are customer data. Merging them leaks who is on whose list, and a shared list means one customer's complaint stops another customer's mail.

Per customer, enforced at send time, across all of that customer's streams.

IP pools and the noisy neighbour

Everyone starts on a shared pool, which means one bad customer degrades delivery for all of them. This is the central operational risk of the model.

Three things make it survivable:

  • Per-customer rate limits from day one, sized to their plan. A compromised customer account should hit a ceiling in minutes.
  • Per-customer complaint monitoring, with automatic throttling above a threshold. Finding out from a blocklist is too late.
  • Pool segmentation — new and unverified customers on a different pool from established ones, so the blast radius of a new signup is contained.

Abuse handling is a feature

You will get customers who send things they should not. Some deliberately; more often a legitimate customer whose own account was compromised.

Build the ability to suspend sending for one customer immediately, without a deploy, and to see what they sent. If finding and stopping a bad sender takes an hour of engineering, the damage is done before you start.

Publish an abuse address, read it, and act on it. Blocklist operators and large providers will contact you before they act, if there is somewhere to write.

What the customer should see

Their own delivery data: per-message status, the remote response verbatim, their suppression list with reasons, and their authentication state per domain.

This is not generosity. A customer who can see that their DKIM record is missing fixes it in two minutes. A customer who cannot files a ticket, and you diagnose it for them.

Data boundaries

Scope every query by tenant at the data layer, not in the controller. A missing WHERE customer_id in a reporting endpoint is how one customer sees another's recipients, and reporting endpoints are exactly where that check gets forgotten.

Ready to send authenticated mail?

DKIM signing, SPF alignment and DMARC are set up the moment you verify a domain.

Get started