Authentication · MachineMail Docs

What each check means

The From header is free text: anyone can write billing@stripe.com in it. Authentication is how a receiver learns whether the sending domain actually stood behind the message. The trust report summarizes it in four fields:

{"authentication": { "spf": "pass", "dkim": "pass", "dmarc": "pass", "aligned": true }}

SPF or DKIM passing on its own proves only that some domain sent the message. A phisher can pass SPF for paypa1-security.com while writing From: PayPal <service@paypal.com>. That is why alignment matters.

Where the results come from

MachineMail does not re-run DNS lookups or signature checks. It uses the results recorded by the mail service that received the message for MachineMail, and nothing the sender could have written:

  1. Verdicts reported by the receiving provider. When the inbound provider reports SPF, DKIM and DMARC results alongside the message, they win. The reasons then include Authentication verdicts from <provider>.
  2. The Authentication-Results header added by our receiving server. Only the topmost header carrying our receiving server’s identifier counts.
  3. Nothing else. Any other Authentication-Results header, ARC-Authentication-Results and Received-SPF is ignored, because a sender can add them to a message before it reaches us. A forged header that claims dmarc=pass gets no credit.

If none of this is available, every field is none, never pass.

Results are mapped to the report’s values:

Field pass fail other values
spf pass fail, hardfail, permerror softfail and neutral are kept as such; anything else is none
dkim any signature passed a signature failed (fail, neutral, policy, permerror) and none passed none
dmarc pass fail, quarantine, reject, permerror none

When no trusted results are found, every field is none and the reasons say No trusted authentication results. If the message carried Authentication-Results headers from other servers, the reasons also say how many were ignored. A DKIM-Signature header with no verification result is noted in the reasons but does not count as a pass.

authentication_results on the message

Every inbound message (and the message.received webhook payload) also carries the results themselves as authentication_results, the field AgentMail clients read. It comes from the same sources as the summary above, but keeps more detail:

{"authentication_results": {
  "spf": "pass", "spf_domain": "mail.linear.app",
  "dkim": "pass", "dkim_domain": "linear.app",
  "dmarc": "pass", "dmarc_domain": "linear.app"
}}

Alignment

aligned is true when a passing DKIM d= domain, or the SPF domain when SPF passed, has the same organisational domain as the From address. A DMARC pass reported by the receiving provider also counts as aligned, since DMARC itself requires alignment. The organisational domain is the registrable part: mail.acme.com aligns with acme.com, and suffixes such as co.uk are handled, so a.example.co.uk and b.example.co.uk align but example.co.uk and other.co.uk do not.

The reasons list says which domain passed and whether it aligned:

{"reasons": [
  "SPF passed for mail.linear.app",
  "DKIM passed for linear.app",
  "DMARC passed",
  "Authenticated domain aligns with From domain linear.app"
]}

How authentication feeds the verdict

Authentication affects the trust report in four places.

Level.

Score. The authentication component carries 25% of the score:

Result Component
DMARC pass and aligned 1.0
SPF or DKIM pass, aligned 0.8
a pass, not aligned 0.5
nothing passed 0.3
anything failed 0

Classifier. Failures raise the phishing and spam probabilities (DMARC fail most, then DKIM, SPF and SPF softfail), no passing authentication raises them a little, and an aligned DMARC pass lowers them. Mail that claims to come from your own domain without passing SPF or DKIM is flagged as spoofing.

Labels. If DMARC failed, or SPF and DKIM both failed, the message gets the UNAUTHENTICATED label and a message.received.unauthenticated event. It keeps the INBOX label, but message lists hide UNAUTHENTICATED mail unless you pass include_unauthenticated=true. The MCP wait_for_message tool does not wake for it.

Mail injected through the API

Messages posted to POST /inbound/raw (which needs a key with the explicit inbound_raw permission) carry whatever headers the caller wrote. MachineMail ignores all of them: authentication is always none, so injected mail is never verified or known. The message gets received_via: "raw" and the reason Injected via API (/inbound/raw); authentication results not verified. Use it for tests and fixtures.

Common patterns

What you see Usually means
spf: pass, dkim: pass, dmarc: pass, aligned: true Real mail from the domain in From.
spf: pass, dkim: none, dmarc: none, aligned: false Sent through a provider that signs with its own domain, or a lookalike domain. Check sender.domain.
dkim: fail The message was modified in transit, often by a forwarder or mailing list, or the signature is forged.
everything none No trusted results: the receiving server recorded none, or the mail was injected through the API.
dmarc: fail The domain owner says this message is not theirs. Treat it as spoofed.