Learn › Exchange Online › 4 · The protection stack (EOP & Defender)

The EOP pipeline: order of operations

Every 'why did this get through / why was this blocked' question is an order-of-operations question. EOP evaluates in a fixed sequence with fixed precedence — learn the sequence once and the product stops feeling random.

The sequence (inbound)

  1. Connection filtering — IP allow/block lists, reputation. A connection-level block means no message object at all (nothing to trace downstream).
  2. Anti-malware — signature/heuristic file verdicts; malware wins over everything later (no allow-list rescues it).
  3. 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.
  4. Anti-spam / anti-phish evaluation — content filtering, spoof intelligence, impersonation models, sender DMARC honouring, bulk (BCL) scoring. Produces the verdict...
  5. 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.
  6. 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.

PowerShell for this concept

Discussion

No messages yet — start the thread.

Sign in with your email to join the discussion — we send a one-time link, no password.