Working out who actually sent that message

An agent reading a message has a question no human consciously asks: is this person who they say they are. People answer it with context and instinct, badly but often well enough. An agent needs it answered explicitly, because it will act on the answer.

4 min read

Three signals about a sender, none of them conclusive alone
The header is a claim. These are the checks that qualify it.

What authentication actually proves

Inbound messages carry an Authentication-Results header from the receiving side, and it is worth being precise about what each result means.

SPF pass means the sending server was authorised for the envelope domain. It says nothing about the visible From address.

DKIM pass means a domain signed the message and it was not modified in transit. It proves the signing domain, which may not be the From domain.

DMARC pass means one of those aligned with the From domain. This is the one that matters, and it proves exactly one thing: the message really came from that domain.

What none of them prove is that the *person* is who they claim. A message can pass DMARC beautifully and come from a domain registered yesterday specifically to look like your supplier, per when someone sends email pretending to be you.

SignalProvesDoes not prove
DMARC passThe domain is genuineThe domain is the right one
Known contactYou have corresponded beforeThe account is not compromised
Thread historyThis continues a real conversationThe latest message is legitimate
Display nameNothing at allAnything at all

Check against what you already know

The most useful verification is not cryptographic, it is relational, and the agent already has the material.

Is this address in the contact record? A first-time sender claiming to continue a relationship is worth a second look.

Does the domain match the thread? A conversation that suddenly continues from a slightly different domain is the classic supplier-impersonation shape, and it is invisible unless something compares.

Does the claim match the record? Someone writing as a company you have never dealt with, about an invoice you have no record of, is answerable without any security theory at all.

Those three checks are cheap, run entirely on data the agent has already fetched, and catch the attacks that actually happen. Escalate the mismatches rather than answering them.

Identity never authorises an action

The rule that makes all of the above safe to rely on: verification informs, it does not authorise.

Even a perfectly authenticated message from a known contact must not be able to trigger a privileged action on the strength of who sent it, because accounts get compromised and a genuine address is exactly what an attacker wants. Bank detail changes, credential requests, access grants, and payment redirections are escalations regardless of how legitimate the sender looks, per prompt injection by email.

What the agent should do with each verdict

Everything checks out. Proceed normally, which is the overwhelming majority of mail.

Authentication fails. Treat with suspicion and do not act on any claim in it. Depending on your setup this mail may not arrive at all, since a strict inbound policy rejects it upstream.

Domain is new to this thread. Continue but flag, and escalate anything with consequences. This one catches real attacks.

Sender unknown, claim significant. Escalate. An unknown sender asking about an existing relationship is either a mistake or an attempt.

Anything about money, credentials, or access. Escalate regardless of verdict.

A mismatch between thread history and sender domain routed to a person
The check that catches the real attack costs one comparison.

Reduce the surface where you can

For agents whose correspondents are known, the strongest control is not verification at all: it is whitelist mode, so a stranger's message never reaches the model. That is available per identity, and it suits recruiting coordinators, billing agents, internal helpdesks, and test identities, per deciding what reaches your agent.

Where the inbox must be open, the checks above plus alerting on first contact from new domains give you most of the remaining value, per what to monitor in production.

Do not build a display-name blocklist

A tempting and useless control: blocking messages whose display name matches your executives' names. It fails on the first variation, catches legitimate mail from people who share a name, and gives a false sense of coverage.

Spend the same effort on the relational checks and on making sure no message can authorise an action. Those work against attacks nobody has thought of yet, which is the property you actually want.

Questions

Can an agent verify who sent a message?
It can verify the sending domain through DMARC, and compare the sender against contact records and thread history. It cannot verify the person, and no email system can.
What does a DMARC pass prove?
That the message genuinely came from the domain in the From address. Not that the domain is the right one, and not that the account behind it is uncompromised.
What is the most useful check?
Comparing the sender's domain against the thread history and contact record. A conversation continuing from a slightly different domain is the classic impersonation shape.
Should a verified sender be able to trigger actions?
No. Accounts get compromised, and a genuine address is exactly what an attacker seeks. Money, credentials, and access escalate regardless of the verdict.
Is a display-name blocklist worth building?
No. It fails on the first variation and blocks legitimate people who share a name, while providing false confidence.
What if my agent only talks to known parties?
Use whitelist mode, so a stranger's message never reaches the model at all. That removes the entire anonymous surface rather than checking it.

Give your agent an address it can answer from.

Create an inbox