As enterprise senders universally enforce strict p=reject DMARC policies, organizations that route inbound mail through third-party Secure Email Gateways (SEGs)—such as Proofpoint, Mimecast, Cisco Secure Email, or Barracuda—before delivering to Exchange Online frequently encounter a painful false-positive problem: legitimate emails fail both SPF and DKIM when evaluated by Exchange Online Protection (EOP).
To solve this without weakening DMARC or maintaining fragile IP-based Connector overrides, RFC 8617 introduced ARC (Authenticated Received Chain).
In this guide, we examine why intermediate mail hops break standard email authentication, visualize how ARC preserves upstream authentication state, and provide a production-ready Exchange Online PowerShell runbook to configure Trusted ARC Sealers (Set-ArcConfig) and audit ARC headers.
Why Third-Party Gateways Break SPF and DKIM
When an external sender (contoso.com) sends an email to your domain, and your MX record points to a third-party gateway (or an on-premises Exchange Edge server) that relays the message into Exchange Online:
1. SPF Breaks by Design: When the message arrives at Exchange Online, the connecting SMTP IP address is your third-party gateway, not contoso.com's authorized outbound servers. Unless Enhanced Filtering for Connectors (Skip Listing) is perfectly tuned, SPF fails.
2. DKIM Breaks When Gateways Modify Messages: If your third-party gateway appends an external warning banner, rewrites URLs, or modifies MIME boundaries, the cryptographic body hash (bh=) of the original DKIM signature is invalidated.
3. DMARC Fails: With both SPF and DKIM failing at the Exchange Online boundary, DMARC evaluates as fail, and EOP quarantines or rejects legitimate business mail.
- Verifies SPF=pass, DKIM=pass
- Modifies body (banner/URL rewrite)
- Stamps cryptographic ARC Seal
- Validates Trusted ARC Sealer (`i=1`)
- Inherits upstream DMARC pass (`oda=1`)
- Delivers cleanly to Inbox
Anatomy of the Three ARC Headers
When an ARC-enabled gateway processes an email, it prepends an indexed set of three headers (i=1 for the first hop, i=2 for the second hop, up to 50 hops):
1. ARC-Authentication-Results (AAR): Captures the exact SPF, DKIM, and DMARC verdicts observed by the gateway before it modified the message.
2. ARC-Message-Signature (AMS): A DKIM-like cryptographic signature covering the message headers and body as they leave the gateway.
3. ARC-Seal (AS): A cryptographic signature covering the entire chain of ARC- headers (cv=none on hop 1, cv=pass on subsequent hops), signed by the gateway's domain (d=) and selector (s=).
[!IMPORTANT] Exchange Online will only trust an upstreamARC-Authentication-Resultsheader to override a failed DMARC verdict if the signing domain (d=) in theARC-Sealis explicitly configured in your tenant'sArcTrustedSealerslist!
Configuring Trusted ARC Sealers in Exchange Online PowerShell
Prerequisites
Connect to Exchange Online PowerShell using an account assigned Organization Management or Security Administrator:Import-Module ExchangeOnlineManagement
Connect-ExchangeOnline -UserPrincipalName admin@lab365.in
Step 1: Inspect Your Current ARC Configuration
Run Get-ArcConfig to check if any trusted ARC sealers are currently registered in your tenant:
Get-ArcConfig | Select-Object Identity, ArcTrustedSealers, WhenChanged
If ArcTrustedSealers is blank, Exchange Online is not trusting any upstream ARC seals.
Step 2: Identify Your Gateway's ARC Signing Domain (d=)
Before running Set-ArcConfig, inspect the raw message headers of an email that passed through your third-party gateway and locate the ARC-Seal header:
ARC-Seal: i=1; a=rsa-sha256; s=arcselector1; d= gateway.yourdomain.com; cv=none;
b=X9kL2...
Take note of the exact domain string in d= (for example, gateway.yourdomain.com or arc.mimecast.com). Ensure that the gateway publishes its corresponding public DKIM/ARC key in DNS at <selector>._domainkey.<domain>.
Step 3: Register Trusted ARC Sealers (Set-ArcConfig)
Use Set-ArcConfig to register your trusted ARC signing domain(s).
Register a Single Signing Domain:
Set-ArcConfig -Identity Default -ArcTrustedSealers "gateway.lab365.in"
Add Additional Signing Domains Without Overwriting Existing Entries:
If you have multiple gateways or regional hops, append neatly using array addition:$currentArc = (Get-ArcConfig -Identity Default).ArcTrustedSealers
$updatedSealers = ($currentArc + "eu-gateway.lab365.in" + "us-gateway.lab365.in") | Select-Object -Unique
Set-ArcConfig -Identity Default -ArcTrustedSealers ($updatedSealers -join ",")
# Verify updated list
Get-ArcConfig -Identity Default | Select-Object Identity, ArcTrustedSealers
Production PowerShell Script: ARC Header Inspector & Validator
After configuring Set-ArcConfig, how do you verify that Exchange Online is actually honoring the ARC seal?
In the final Authentication-Results header stamped by Exchange Online, EOP appends oda=1 (Original-Authentication-Results trusted via ARC*).
Save and run this PowerShell function to parse raw .eml files or pasted message headers, extract the ARC chain (i=1..N), and verify whether EOP honored the ARC override (oda=1).
<#
.SYNOPSIS
Parses raw email headers to inspect the ARC (Authenticated Received Chain) and EOP 'oda=1' status.
.DESCRIPTION
Extracts ARC-Seal, ARC-Message-Signature, ARC-Authentication-Results, and final
Exchange Online Authentication-Results to diagnose DMARC/ARC behavior.
.NOTES
Author: Sunil Chauhan (https://www.lab365.in)
#>
function Test-EmailArcHeaders {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true, HelpMessage = "Path to a raw .eml or .txt file containing message headers")]
[string]$HeaderFilePath
)
if (-not (Test-Path -LiteralPath $HeaderFilePath)) {
Throw "File not found: $HeaderFilePath"
}
$rawContent = Get-Content -LiteralPath $HeaderFilePath -Raw
# Unfold multi-line RFC 5322 headers
$unfolded = $rawContent -replace "\r?\n[ \t]+", " "
$lines = $unfolded -split "\r?\n"
Write-Host "==========================================================" -ForegroundColor Cyan
Write-Host " Exchange Online ARC & Authentication Header Inspector " -ForegroundColor Cyan
Write-Host "==========================================================" -ForegroundColor Cyan
$arcSeals = $lines | Where-Object { $_ -match "^ARC-Seal:" }
$arcAuth = $lines | Where-Object { $_ -match "^ARC-Authentication-Results:" }
$eopAuth = $lines | Where-Object { $_ -match "^Authentication-Results:" }
if (-not $arcSeals) {
Write-Warning "[!] No ARC-Seal headers found in this message. The upstream gateway is not ARC-signing."
return
}
Write-Host "[+] Detected $($arcSeals.Count) ARC Hop(s):" -ForegroundColor Green
foreach ($seal in $arcSeals) {
$instance = if ($seal -match "i=(\d+)") { $matches[1] } else { "?" }
$domain = if ($seal -match "d=([^;\s]+)") { $matches[1] } else { "Unknown" }
$selector = if ($seal -match "s=([^;\s]+)") { $matches[1] } else { "Unknown" }
$cv = if ($seal -match "cv=([^;\s]+)") { $matches[1] } else { "Unknown" }
[PSCustomObject]@{
HopInstance = "i=$instance"
SealerDomain= $domain
Selector = $selector
ChainValidation = $cv
} | Format-List
}
Write-Host "--- Upstream ARC-Authentication-Results ---" -ForegroundColor Yellow
foreach ($aar in $arcAuth) {
Write-Host $aar -ForegroundColor Gray
}
Write-Host ""
Write-Host "--- Final Exchange Online Authentication-Results ---" -ForegroundColor Yellow
foreach ($ar in $eopAuth) {
Write-Host $ar -ForegroundColor White
if ($ar -match "oda=1") {
Write-Host "[✓] SUCCESS: 'oda=1' detected! Exchange Online trusted the upstream ARC sealer." -ForegroundColor Green
} elseif ($ar -match "arc=pass") {
Write-Host "[!] INFO: 'arc=pass' detected, but 'oda=1' is not present (either DMARC passed natively or sealer domain is not in ArcTrustedSealers)." -ForegroundColor Yellow
} elseif ($ar -match "arc=fail") {
Write-Host "[X] FAILURE: 'arc=fail' detected! The ARC chain or signature was broken in transit." -ForegroundColor Red
}
}
}
# Example Usage:
# Test-EmailArcHeaders -HeaderFilePath ".\sample-headers.txt"
Summary Checklist for Messaging Architects
- [ ] Enable ARC Signing on your third-party inbound email gateway (Proofpoint, Mimecast, Cisco, etc.) and publish its public key in DNS.
- [ ] Combine ARC with Enhanced Filtering for Connectors (Skip Listing) on your inbound Partner connector in Exchange Online so both IP intelligence and cryptographic headers work together.
- [ ] Register the gateway's exact
d=signing domain usingSet-ArcConfig -Identity Default -ArcTrustedSealers. - [ ] Validate inbound modified messages using the Microsoft Message Header Analyzer or
Test-EmailArcHeadersto confirmarc=passandoda=1.
Related reading: Enabling Inbound SMTP DANE with DNSSEC in Exchange Online · Multi-Domain SPF, DKIM, and DMARC Audit Script for Microsoft 365