HERALD
read the headers

See where an email really came from.

An offline reader for e-mail headers: it redraws the route a message took, reports the authentication the receiving server recorded, and grades what it finds — without ever calling a message safe.

Python 3.10+PyQt6 network never158 testsMIT

Why

A phishing e-mail is a confidence trick played on one line: the name in the From field. People read that name, recognise it, and stop reading — which is exactly what the rest of the headers are there to catch.

Every server that touches a message stamps its own line onto it. Those stamps say where it really came from, whether anyone authenticated it, and whether its route agrees with its claims. Herald reads them and explains them in plain words.

What it draws. The itinerary — the Received chain redrawn as the journey it was, origin at the top, the real IP under each hop, internal hand-offs hollow and external jumps solid, and the measured delay on every leg.
Herald reading two samples

The reader on two of its bundled samples.

What it checks

SignalWhat trips it
SPFfailed, soft-failed, or no usable policy
DKIMsignature failed, present but unverified, or absent
DMARCfailed alignment, or no policy published
EnvelopeFrom and Return-Path on different registrable domains
Reply-Toreplies routed to a domain that is not the sender
Display namea name hiding a different real address
Look-alikea punycode domain, or digit-for-letter spelling

The honest part

Herald reads the verdict the receiving server already wrote down. It fetches no DNS key, re-checks no signature, and never sees your own filtering. A message with no authentication at all is capped at C and labelled unknown, rather than waved through.

Install

git clone https://github.com/at0m-b0mb/Herald-Email-Headers.git
cd Herald-Email-Headers
python3 -m pip install -r requirements.txt

python3 -m herald                      # the window
python3 -m herald samples/             # the command line
python3 -m pytest -q                   # 158 tests

The engine and the command line need no dependencies at all — only the standard library. PyQt6 is required solely for the window.

One of seven readers