Docs / Email Servers / Implementing ARC for Email Forwarding Chains

Implementing ARC for Email Forwarding Chains

By Admin · Mar 15, 2026 · Updated Apr 23, 2026 · 227 views · 4 min read

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

Was this article helpful?