Files
claudetools/clients/glaztech/session-logs/2026-05-28-session.md
Mike Swanson 57d03c6097 sync: auto-sync from GURU-5070 at 2026-05-28 12:26:25
Author: Mike Swanson
Machine: GURU-5070
Timestamp: 2026-05-28 12:26:25
2026-05-28 12:26:29 -07:00

7.1 KiB

Glaztech — Email Delivery Investigation & Transport Rules

User

  • User: Mike Swanson (mike)
  • Machine: GURU-5070
  • Role: admin

Session Summary

Steve Eastman (Glaztech) reported that emails from two vendor contacts — hartsglass@centurytel.net and olemons@eastexglass.com — were showing "Deliver" in MailProtector but not arriving at SHVSALES@glaztech.com. The emails were not appearing in M365 Quarantine either, which was the key diagnostic clue.

Investigation via Exchange Online message trace and connector inspection revealed the root cause: both sender domains (centurytel.net and eastexglass.com) publish DMARC policy p=reject. Glaztech's inbound connector ("Inbound Spam Filter") has Enhanced Filtering enabled with EFSkipIPs set to the three MailProtector IPs (162.248.93.233, 162.248.93.81, 65.113.52.82), but SCLMinusOne is null — meaning EOP does not trust MailProtector's verdict and re-evaluates all mail. With Enhanced Filtering, EOP looks past the MailProtector relay to the original sender's authentication. Both sender domains fail DMARC, producing hard 550 5.7.509 NDR rejections in Exchange Online before messages ever reach the mailbox or quarantine.

Additional rejected senders were identified from the email thread Steve forwarded: SSales@arkglass.com, bossier@glassservices.com, and an unnamed contact at aaaglassinc.com (Donald Arnold). DNS inspection of glassservices.com found a broken SPF record (v=spf1 -all — no authorized senders), meaning their emails will be rejected by all mail providers regardless of any Glaztech-side fix.

The fix applied was two SCL=-1 transport rules in the Glaztech Exchange Online tenant. Transport rules evaluate before the anti-spam pipeline (including DMARC enforcement) in EOP, so setting SCL=-1 bypasses the DMARC rejection for these specific senders. Rules were created via the Exchange Operator service principal using POST /adminapi/beta/{tenant}/InvokeCommand with New-TransportRule cmdlet (direct REST resource endpoints 404 in this tenant).


Key Decisions

  • SCL=-1 transport rule over connector trust — Setting SCLMinusOne: true on the connector would trust MailProtector's verdict for ALL inbound mail, which is too broad. Targeted transport rules scoped to specific senders are the more surgical fix.
  • Two rules instead of one — The aaaglassinc.com sender was handled by domain (SenderDomainIs) rather than specific address since the contact email was not known. The other four were handled by exact address (From). Separate rules keep the logic clean.
  • glassservices.com SPF not fixable on our side — Their v=spf1 -all will cause rejection everywhere. The appropriate action is notifying Steve so he can tell the glassservices.com vendor their IT needs to fix the SPF record. Our SCL=-1 rule still covers bossier@glassservices.com as a workaround.
  • No Syncro ticket created — This was handled reactively via email thread; no ticket was opened during the session. Consider creating one retroactively if billing for this work.

Problems Encountered

  • Direct REST resource endpoints 404: /adminapi/beta/{tenant}/TransportRule returns 404. Fixed by using the InvokeCommand pattern: POST /adminapi/beta/{tenant}/InvokeCommand with {"CmdletInput": {"CmdletName": "New-TransportRule", "Parameters": {...}}}.
  • Transport rule name 66-char limit exceeded: Initial rule name "SCL Bypass - hartsglass@centurytel.net and olemons@eastexglass.com" was 66 chars; EXO enforces a 64-char max. Fixed by shortening to "SCL Bypass - hartsglass + olemons (SHVSALES)" (44 chars).
  • Initial misdiagnosis: First assumed emails were landing in Junk/spam folder (SCL scoring). Steve's follow-up with full message trace revealed actual cause was hard DMARC 550 5.7.509 NDR — the SCL=-1 fix still resolves this correctly since transport rules run before DMARC enforcement in the EXO pipeline.

Configuration Changes

Two transport rules created in Glaztech M365 tenant (82931e3c-de7a-4f74-87f7-fe714be1f160):

Rule GUID Name Condition Action
482c714a-8780-4c62-ae0a-0b6da9ca9d52 SCL Bypass - hartsglass + olemons (SHVSALES) From: hartsglass@centurytel.net, olemons@eastexglass.com, SSales@arkglass.com, bossier@glassservices.com SetSCL: -1
7e0c01a8-ec22-43fe-b600-796c0f295aa5 SCL Bypass - aaaglassinc.com (SHVSALES) SenderDomainIs: aaaglassinc.com SetSCL: -1

Both rules: State = Enabled.


Credentials & Secrets

  • Exchange Operator Service Principal
    • App ID: b43e7342-5b4b-492f-890f-bb5a4f7f40e9
    • Secret: Ct28Q~fKYUu.RvkMaGNAV1YeK6h-HBewCTPnwa.Y
    • Vault: msp-tools/computerguru-exchange-operator.sops.yaml
  • Glaztech Tenant ID: 82931e3c-de7a-4f74-87f7-fe714be1f160

Infrastructure & Servers

  • Glaztech M365 tenant: 82931e3c-de7a-4f74-87f7-fe714be1f160
  • MailProtector IPs (EFSkipIPs on inbound connector): 162.248.93.233, 162.248.93.81, 65.113.52.82
  • EXO InvokeCommand endpoint: https://outlook.office365.com/adminapi/beta/{tenant}/InvokeCommand
  • Token endpoint: https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token

Commands & Outputs

# Auth token
POST https://login.microsoftonline.com/82931e3c-.../oauth2/v2.0/token
scope=https://outlook.office365.com/.default

# Check connector Enhanced Filtering state
POST /adminapi/beta/{tenant}/InvokeCommand
{"CmdletInput":{"CmdletName":"Get-InboundConnector","Parameters":{"Identity":"Inbound Spam Filter"}}}
# → EFSkipIPs: [162.248.93.233, 162.248.93.81, 65.113.52.82], SCLMinusOne: null

# Create rule 1 (specific addresses)
{"CmdletInput":{"CmdletName":"New-TransportRule","Parameters":{
  "Name":"SCL Bypass - hartsglass + olemons (SHVSALES)",
  "From":["hartsglass@centurytel.net","olemons@eastexglass.com","SSales@arkglass.com","bossier@glassservices.com"],
  "SetSCL":-1,"Enabled":true}}}
# → GUID: 482c714a-8780-4c62-ae0a-0b6da9ca9d52

# Create rule 2 (domain)
{"CmdletInput":{"CmdletName":"New-TransportRule","Parameters":{
  "Name":"SCL Bypass - aaaglassinc.com (SHVSALES)",
  "SenderDomainIs":["aaaglassinc.com"],
  "SetSCL":-1,"Enabled":true}}}
# → GUID: 7e0c01a8-ec22-43fe-b600-796c0f295aa5

Pending / Incomplete Tasks

  • Notify Steve about glassservices.com SPF: bossier@glassservices.com will be rejected by all mail providers (SPF v=spf1 -all). Steve should tell the vendor their IT needs to fix the SPF record. Our SCL bypass is a workaround only.
  • Harts Glass resend: The original rejected emails need to be resent by the sender. Our rule is now live but previously rejected messages are NDRed and will not auto-retry.
  • Syncro ticket: No ticket opened for this work. Create retroactively if billing.

Reference Information

  • DMARC root cause: centurytel.netp=reject; eastexglass.comp=reject
  • NDR code: 550 5.7.509 (DMARC failure under Enhanced Filtering)
  • Transport rule GUIDs: 482c714a (addresses), 7e0c01a8 (aaaglassinc.com domain)
  • EXO InvokeCommand pattern: Required because direct /TransportRule REST endpoint 404s in this tenant