Platform
ScaiWave ScaiGrid ScaiCore ScaiBot ScaiDrive ScaiKey Models Tools & Services
Solutions
Organisations Developers Internet Service Providers Managed Service Providers AI-in-a-Box
Resources
Support Documentation Blog Downloads
Company
About Research Careers Investment Opportunities Contact
Log in

DKIM, SPF, DMARC

Email authentication is three protocols working together. DKIM signs your messages so recipients know they came from you. SPF tells recipients which servers are allowed to send for your domain. DMARC tells recipients what to do when the other two disagree.

ScaiSend handles DKIM signing automatically. SPF and DMARC are DNS records you publish. Both are generated for you when you add a sender domain — this page explains what they do so you know what you're publishing.

DKIM#

What it is#

DKIM (DomainKeys Identified Mail, RFC 6376) is a cryptographic signature over the message body and selected headers. The signer has a private key; the verifier fetches the public key from DNS and checks the signature.

If the signature verifies, the receiver knows:

  • The message body wasn't modified in transit.
  • The sender genuinely has control of the private key.

The DNS record#

ScaiSend generates an RSA-2048 keypair per sender domain. The public key is published as a TXT record at:

scdoc
1
scaisend._domainkey.<your-domain>

Value:

text
1
v=DKIM1; k=rsa; p=<base64-encoded-public-key>

scaisend is the selector — the first label of the record path. Multiple keys can coexist under different selectors (e.g., during rotation, scaisend and scaisend2 can both be valid).

Signing#

When the SMTP service is about to deliver a message, it:

  1. Canonicalizes the headers and body (simple or relaxed canonicalization; ScaiSend uses relaxed).
  2. Computes an SHA-256 hash of the canonical body.
  3. Signs the hash plus a selected set of headers (From, To, Subject, Date, Message-ID, MIME-Version, Content-Type) with the private key.
  4. Adds the signature as a DKIM-Signature: header.

A typical header looks like:

css+lasso
1
2
3
4
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mail.example.com;
 s=scaisend; t=1713888000; bh=base64body hash;
 h=From:To:Subject:Date:Message-ID;
 b=base64signature

Verifying on the receiving side#

When a recipient MX gets the message, it:

  1. Parses the DKIM-Signature header.
  2. Fetches s._domainkey.d (the selector at the domain).
  3. Decodes the public key.
  4. Recomputes the canonicalization and hash.
  5. Verifies the signature.

If any of these fail, the DKIM check fails. The receiver won't bounce just for that (typically; depends on DMARC policy) but your deliverability takes a hit.

Rotation#

Rotate keys annually or whenever compromise is suspected. ScaiSend generates a new keypair under a new selector, publishes the new public key, and switches signing over once DNS has propagated:

bash
1
2
curl -X POST https://scaisend.scailabs.ai/api/admin/domains/dom_01HXYZ/rotate-dkim \
  -H "Authorization: Bearer $SCAISEND_JWT"

The old selector stays live until you explicitly remove it. Leaves a window where in-flight mail signed with the old key can still be verified.

SPF#

What it is#

SPF (Sender Policy Framework, RFC 7208) is a TXT record at the sending domain listing which mail servers are authorized to send for it. It's a simple IP/hostname allowlist.

The DNS record#

ScaiSend uses include: to delegate:

teratermmacro
1
example.com TXT "v=spf1 include:scaisend.scailabs.ai ~all"

Or, for a subdomain sender:

teratermmacro
1
mail.example.com TXT "v=spf1 include:scaisend.scailabs.ai ~all"

Meaning:

  • v=spf1 — this is an SPF record (version 1).
  • include:scaisend.scailabs.ai — trust the SPF rules published at scaisend.scailabs.ai for the ScaiSend-operated outbound IPs.
  • ~all — soft-fail anything else. Most receivers treat soft-fail as a quarantine signal.

If you already have an SPF record#

You can't have two SPF records. Merge:

Existing:

scdoc
1
example.com TXT "v=spf1 include:_spf.google.com ~all"

After adding ScaiSend:

scdoc
1
example.com TXT "v=spf1 include:_spf.google.com include:scaisend.scailabs.ai ~all"

SPF alignment#

DMARC requires the SPF-authenticated domain to align with the From: header domain. If your From: is hello@mail.example.com and SPF authorizes mail.example.com, they align. If From: is hello@example.com but SPF is on mail.example.com, relaxed DMARC still counts that as aligned (shared organizational domain).

DMARC#

What it is#

DMARC (Domain-based Message Authentication, Reporting, and Conformance, RFC 7489) tells receivers what to do when both SPF and DKIM fail to align with the From: domain. It's the policy that gives SPF and DKIM teeth.

The DNS record#

ScaiSend generates a DMARC TXT record when you add a domain:

tsql
1
_dmarc.mail.example.com TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@example.com"

Meaning:

  • v=DMARC1 — this is a DMARC record.
  • p=quarantine — if a message fails both SPF and DKIM, put it in spam. (Alternatives: none for no action, reject for bounce.)
  • rua=mailto:... — send aggregate reports here.

Policies: which to use#

Policy When
none Starting out. Monitoring-only. Reports flow in; nothing is blocked.
quarantine Confirmed clean setup. Failures go to spam. Reasonable default.
reject Established reputation. Failures are outright rejected.

Start with none. Watch the rua reports for a couple of weeks. Look for:

  • Mail from your domain that you didn't send (spoofing).
  • Mail that you did send but fails DKIM or SPF (misconfigured service).

Once the only things failing are actual spoofs, graduate to quarantine. Later, if you're confident, to reject.

Subdomain policy#

sp= specifies a policy for subdomains. If you want strict enforcement on mail.example.com but no policy on login.example.com, publish the DMARC record at _dmarc.example.com with sp=none:

scdoc
1
_dmarc.example.com TXT "v=DMARC1; p=quarantine; sp=none; rua=mailto:..."

DMARC alignment#

DMARC considers SPF-aligned OR DKIM-aligned as a pass. Either authentication getting the From: domain right is sufficient. Since ScaiSend always DKIM-signs, alignment is straightforward as long as your DKIM record is published for the same domain that appears in From:.

How they fit together#

A message arrives at a recipient MX:

  1. SPF check. The connecting IP is compared against the SPF record at the envelope-sender domain. Result: pass, neutral, softfail, fail.
  2. DKIM check. The DKIM-Signature header is validated against the public key at s._domainkey.d. Result: pass or fail.
  3. DMARC alignment. The From: header domain is compared against the domains that SPF and DKIM authenticated. If either aligns AND that check passed, DMARC passes. Otherwise DMARC fails.
  4. DMARC policy. If DMARC fails, the receiver consults the DMARC policy (p=). quarantine → spam folder; reject → bounce.

For a well-configured ScaiSend deployment sending from hello@mail.example.com:

  • SPF: the connecting IP is one of ScaiSend's outbound IPs → listed via include:scaisend.scailabs.ai → pass.
  • DKIM: signed with the key at scaisend._domainkey.mail.example.com → verifies → pass.
  • Alignment: both SPF and DKIM identify mail.example.com, same as From:. → aligned.
  • DMARC pass.

Verifying#

Use a mail-test service or send a test message to a Gmail account and check Show original. You should see:

text
1
2
3
SPF: PASS with IP ...
DKIM: PASS with domain mail.example.com
DMARC: PASS

If any fails, the errors[] on POST /api/admin/domains/{id}/verify tells you which DNS record is missing or wrong.

Common failure modes#

"DKIM: PASS with domain scaisend.scailabs.ai, but DMARC fails."

Your DKIM is publishing under the wrong domain — most likely because you didn't publish the key at scaisend._domainkey.<your-domain> and the verifier is falling back to something generic. Republish.

"SPF: PERMERROR / too many DNS lookups."

SPF has a 10-lookup limit. If you have a deep chain of include: directives, you hit the cap. Flatten the SPF record — replace includes with explicit IPs if necessary.

"DMARC: FAIL (policy: none)."

The message failed alignment but your policy is none so nothing happens. Check the rua report to diagnose why alignment failed. Fix SPF/DKIM, then graduate policy.

Updated 2026-05-17 01:33:27 View source (.md) rev 1