Email Authenticity Check
Judge whether a Gmail message is genuine or phishing — the same forensic checks as the phishing-check job, but deterministic Python instead of AI. Zero LLM tokens, zero per-run cost, identical answer every time for the same headers.
Why no AI works here
The reliable signals are facts in the headers, not judgment calls about tone:
- SPF / DKIM / DMARC — Google already verified these on receipt and recorded the result in the
Authentication-Resultsheader. The tool reads them; it doesn't re-derive them. - Identity alignment — it compares the visible
Fromdomain againstReturn-Path,Reply-To, and the DKIM signing domain (d=). A bank email whoseReply-Tois a free webmail address is a classic tell. - Link domains — it extracts the URL domains from the body and flags shorteners and domains that don't match the sender.
Because every input is a discrete header fact, a fixed rule set reproduces what the AI was doing — without the cost or variability.
Input
| Field | Required | Description |
|---|---|---|
messageJson |
yes | The JSON from gmail get <id> --format full (JSON output) — must include the raw headers (message.payload.headers) and decoded body. Typically piped from a google_workspace fetch task. |
A raw Gmail API Message resource (payload.headers at the top level) is also accepted.
Output (published fields)
verdict (GENUINE / SUSPICIOUS / PHISHING), confidence (high/medium/low), spf, dkim, dmarc, fromDomain, returnPathDomain, replyToDomain, dkimDomain, linkDomains, reasons, recommendedAction, authentic (true/false), and report — a ready-to-send text summary (checks table + reasoning + recommended action).
Verdict rules (transparent, in order)
- Any auth check explicitly fails (
dkim=fail/dmarc=fail/spf=fail) → PHISHING. - No
Authentication-Resultsheader at all → SUSPICIOUS (low confidence — nothing to verify). - Auth passes and the From domain aligns with DKIM
d=or Return-Path and no Reply-To mismatch / shortener → GENUINE (high if both DKIM and DMARC pass). - Auth passes but a Reply-To mismatch (free webmail) or a URL shortener is present → SUSPICIOUS.
- Anything else → SUSPICIOUS (low confidence).
The recommended action never tells you to click a link — if an action is legitimate, it tells you to navigate to the provider directly.
Use it in a job
Pair it with a google_workspace fetch and a message/notify step — the AI-free counterpart of the phishing-check job:
{
"tasks": [
{
"name": "fetch",
"tool": "google_workspace",
"credential": "<<GOOGLE_WORKSPACE_CREDENTIAL>>",
"properties": {
"service": "gmail",
"operation": "get",
"args": "<<MESSAGE_ID>> --format full",
"outputFormat": "json"
}
},
{
"name": "assess",
"tool": "email-authenticity-check",
"properties": {
"messageJson": "{{fetch.output}}"
}
},
{
"name": "notify",
"tool": "message",
"properties": {
"subject": "Authenticity check \u2014 {{assess.verdict}}",
"body": "{{assess.report}}",
"userNames": "<<NOTIFY_USER>>"
}
}
]
}
Read-only Gmail scope is sufficient — the tool only reads headers and reports.
What it won't do
- Open or fetch links — it analyzes link domains from the body text; it never visits them.
- Catch an auth-passing email from a compromised legitimate account — if a real account is hijacked, SPF/DKIM/DMARC all pass. The tool still flags Reply-To/link inconsistencies, but an auth-passing takeover is the hardest case for any header-based check (the AI version has the same blind spot). When auth passes but signals are inconsistent it returns SUSPICIOUS rather than GENUINE.
- Parse non-Gmail formats — it targets the gog
gmail get --format fullJSON shape. Other providers' raw MIME would need a different parser.
Publishes
The keys a later task may reference as {{taskName.key}}. Referencing anything not listed here resolves to nothing at run time.
authenticconfidencedkimdkimDomaindmarcfromDomainlinkDomainsreasonsrecommendedActionreplyToDomainreportreturnPathDomainspfverdict
Input Properties
Every property this tool accepts, from its own tool.iml.
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
messageJson |
string | yes | — | The Gmail message JSON from gmail get <id> --format full (JSON output) — must include the raw headers (message.payload.headers) and decoded body. Typically piped from a google_workspace fetch task. |