The sequence (inbound)
- Connection filtering — IP allow/block lists, reputation. A connection-level block means no message object at all (nothing to trace downstream).
- Anti-malware — signature/heuristic file verdicts; malware wins over everything later (no allow-list rescues it).
- Transport rules (ETRs) — YOUR logic runs here, including SCL-setting rules — which is why an ETR 'bypass spam filtering' action works: it fires before spam verdicts.
- Anti-spam / anti-phish evaluation — content filtering, spoof intelligence, impersonation models, sender DMARC honouring, bulk (BCL) scoring. Produces the verdict...
- Verdict actions + policy application — WHICH policy applies is the most misunderstood part: the highest-priority policy that includes the RECIPIENT wins (preset policies outrank custom; Strict > Standard > custom by priority order). One recipient, one policy — never a merge.
- Post-delivery — ZAP retro-acts on delivered mail when verdicts change; Safe Links rewrites act at click time.
The precedence traps that generate tickets
| Mystery | Resolution |
|---|---|
| "It's on the allow list but still quarantined" | Malware and high-confidence phish outrank allows by design; also check WHICH policy actually applied (step 5) |
| "Spam policy changes do nothing" | The user is in scope of a preset (Standard/Strict) that outranks your custom policy — the effective-policy tool tells you |
| "The ETR whitelist works for some users only" | Rule conditions vs policy scoping mismatch — different recipients, different step-5 winners |
| "Bounced before any policy could act" | Connection-level (step 1) — look in the connect logs mindset, not content policies |
| "It was in the inbox, then vanished" | ZAP — the audit trail says so explicitly |
Design that keeps the stack sane
Prefer presets (Standard/Strict) for the org baseline + tightly-scoped custom policies for exceptions; keep the Tenant Allow/Block List as THE override surface (it is order-aware in ways ad-hoc ETR allows are not); treat 'bypass filtering' ETRs as debt with expiry dates — they are step-3 landmines that age badly. Every one of these objects is in the serv365 nightly scan (HostedContentFilterPolicy, AntiPhishPolicy, MalwareFilterPolicy, QuarantinePolicy...) — filtering-stack drift is visible history, which matters because 'who loosened the phish policy' should never be an unanswerable question.
What to watch (proofs)
- The effective policy for a recipient: the configuration-analyzer / effective-protection tooling names the step-5 winner — screenshot it into every 'policy not applying' ticket.
- Verdict evidence per message: trace detail + quarantine entry show the verdict AND the policy that acted — the order made visible.
- Your override debt: ETRs with bypass actions + tenant allow entries, listed with ages — the quarterly pruning list.
- Drift on the stack: the scanned protection policies' change history — serv365 turns 'the filter changed' from suspicion into a dated diff.