Authenticated Received Chain (ARC) solves the email authentication problem caused by forwarding. When a message is forwarded, SPF fails (different sender IP) and DKIM may break (modified headers/body). ARC preserves the original authentication results through a chain of trust, allowing downstream servers to verify the message was authenticated before forwarding. This guide covers ARC implementation with OpenARC and Rspamd.
The Forwarding Problem
Consider this scenario: User A sends email from gmail.com to a mailing list at lists.example.com, which forwards to User B at outlook.com. When Outlook receives the message:
- SPF fails — the sending IP is the mailing list server, not Gmail
- DKIM may fail — the mailing list added a footer, breaking the body hash
- DMARC fails — both SPF and DKIM failed for gmail.com
- Result — legitimate email gets quarantined or rejected
How ARC Works
ARC adds three headers at each forwarding hop:
- ARC-Authentication-Results (AAR) — the authentication results at this hop
- ARC-Message-Signature (AMS) — DKIM-like signature of the message at this hop
- ARC-Seal (AS) — signature of the ARC headers, preventing tampering with the chain
Each set is numbered (i=1, i=2, ...) forming a chain. The receiving server validates the entire chain and can trust the original authentication results if the intermediaries are trusted.
Implementation with OpenARC
# Install OpenARC
sudo apt install openarc # Ubuntu/Debian
# Generate ARC signing key
sudo mkdir -p /etc/openarc/keys
sudo openarc-genkey -d example.com -s arc -D /etc/openarc/keys/
sudo chown -R openarc:openarc /etc/openarc/keys/
Configure OpenARC
# /etc/openarc.conf
Mode sv # Sign and verify
Canonicalization relaxed/relaxed
Domain example.com
Selector arc
KeyFile /etc/openarc/keys/arc.private
SignHeaders from:to:subject:date:message-id:mime-version:content-type
AuthservID mail.example.com
PeerList /etc/openarc/peers
TrustAnchorFile /usr/share/dns/root.key
Socket inet:8894@localhost
SyslogFacility mail
Trusted Peers
# /etc/openarc/peers
# List IP addresses of trusted forwarders whose ARC chains you trust
127.0.0.1
10.0.0.0/8
DNS Record
# Add the ARC public key as a DNS TXT record (same format as DKIM)
arc._domainkey.example.com TXT "v=DKIM1; k=rsa; p=MIIBIjAN..."
# The key is in /etc/openarc/keys/arc.txt
Integrate with Postfix
# /etc/postfix/main.cf
# Add OpenARC milter (after OpenDKIM if present)
smtpd_milters = inet:localhost:8891, inet:localhost:8894
non_smtpd_milters = inet:localhost:8891, inet:localhost:8894
Implementation with Rspamd
Rspamd has built-in ARC support, making it the simpler option if you already use Rspamd:
# /etc/rspamd/local.d/arc.conf
# ARC signing configuration
sign_authenticated = true;
sign_local = true;
use_domain = "header";
allow_hdrfrom_mismatch = true;
domain {
example.com {
path = "/var/lib/rspamd/dkim/example.com.key";
selector = "arc";
}
}
# ARC verification is enabled by default in Rspamd
# Rspamd adds ARC headers automatically when forwarding signed mail
Verifying ARC
# Check ARC headers in received email
# Look for these headers:
# ARC-Seal: i=1; a=rsa-sha256; cv=none; d=example.com; s=arc; ...
# ARC-Message-Signature: i=1; a=rsa-sha256; d=example.com; ...
# ARC-Authentication-Results: i=1; mail.example.com; dkim=pass; spf=pass
# cv= values:
# cv=none — first hop in the chain
# cv=pass — previous ARC seal validated
# cv=fail — chain validation failed (do not trust)
# Test with a forwarded message
# Send email through your forwarding server
# Check Authentication-Results header at destination:
# arc=pass (as.1.example.com = pass)
ARC for Mailing Lists
# Mailing list servers that modify messages should:
# 1. Verify incoming DKIM/SPF/DMARC
# 2. Add ARC headers recording the original authentication results
# 3. Forward with the ARC chain intact
# Mailman 3 has built-in ARC support
# In mailman.cfg:
[arc]
enabled = yes
authserv_id = lists.example.com
selector = arc
domain = lists.example.com
privkey = /etc/mailman3/arc.key
Google and Microsoft ARC Support
Major email providers evaluate ARC chains when making delivery decisions:
- Google (Gmail) — trusts ARC from verified intermediaries; ARC can override DMARC failures
- Microsoft (Outlook/365) — evaluates ARC chains and considers trusted sealers
- Yahoo — supports ARC verification
For your ARC seals to be trusted, your domain needs good reputation and consistent authentication. Over time, providers learn to trust your ARC signatures.
Troubleshooting
# ARC seal cv=fail
# Causes:
# - Incorrect private key
# - DNS record mismatch
# - Message modified after ARC sealing (by another milter)
# Check key match
openarc-testkey -d example.com -s arc -vvv
# Verify DNS record is accessible
dig TXT arc._domainkey.example.com +short
# Check milter ordering — ARC milter should run AFTER any content-modifying filters
Best Practices
- Implement ARC on any server that forwards email to preserve authentication chains
- Use the same key infrastructure as DKIM (RSA 2048-bit or Ed25519)
- Ensure ARC signing happens after all message modifications (content filters, footers)
- Use Rspamd for ARC if you already use it for spam filtering — simpler than a separate OpenARC setup
- Monitor ARC validation results in your DMARC aggregate reports
- Trust ARC chains only from known, reputable intermediaries