✨(inbound) ARC relay-trust: inbound_auth "arc" + arc_verdict rule#763
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughChangesThe inbound mail pipeline now verifies trusted ARC chains, caches ARC verdicts, supports ARC-based DKIM/DMARC authentication, and evaluates ARC relay trust
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Message
participant InboundPipeline
participant ARCVerifier
participant SpamRules
participant InboundAuth
Message->>InboundPipeline: enter inbound processing
InboundPipeline->>ARCVerifier: verify configured ARC sealer
ARCVerifier-->>InboundPipeline: cached ARC verdict
InboundPipeline->>SpamRules: evaluate arc_verdict conditions
InboundPipeline->>InboundAuth: evaluate ARC-based authentication
InboundAuth-->>Message: authentication verdict
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
New "arc" inbound_auth mode derives dkim/dmarc only from an ARC-sealed ARC-Authentication-Results whose outermost sealer is in SPAM_CONFIG["trusted_arc_sealers"] (empty = any valid seal); plaintext headers are never trusted. New SPAM_CONFIG["arc_gate"] (off|spam|drop) marks or drops inbound mail lacking a valid trusted seal, so a publicly-reachable mta-in effectively accepts only mail sealed by a trusted relay. The chain is verified with dkimpy; a verification/DNS failure never spams or drops. core/mda/arc.py holds the shared verifier. Config reference in docs/spam-config.md.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
a2ffa20 to
2c68aac
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/spam.md`:
- Around line 233-235: Update the “Fail closed” statement in the
trusted_arc_sealers documentation to say that an arc_verdict: "untrusted" rule
matches every non-widget message when the allowlist is empty, preserving the
preceding widget exemption.
In `@src/backend/messages/settings.py`:
- Around line 555-569: Update the SPAM_CONFIG documentation comment to describe
ARC conditions using the implemented arc_verdict key, include the accepted
reject and no-action aliases alongside spam, ham, and drop, and document that
unresolved DNS verification is treated as untrusted after
MESSAGES_INBOUND_DEFERRAL_MAX_AGE.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 0cb9aaee-e1a3-4bb4-92f7-880dbaefb241
📒 Files selected for processing (9)
docs/spam.mdsrc/backend/core/mda/arc.pysrc/backend/core/mda/inbound_auth.pysrc/backend/core/mda/inbound_pipeline.pysrc/backend/core/mda/spam.pysrc/backend/core/tests/mda/test_arc.pysrc/backend/core/tests/mda/test_inbound_auth.pysrc/backend/core/tests/mda/test_spam_processing.pysrc/backend/messages/settings.py
| # rules : list of spam rules; each is a header_match / | ||
| # header_match_regex OR an "arc_verdict" trust | ||
| # condition — "trusted" / "untrusted" — e.g. | ||
| # {"arc_verdict": "untrusted", "action": "drop"}, | ||
| # with action spam / ham / drop. | ||
| # inbound_auth : sender authentication backend — one of | ||
| # "native", "rspamd", "authentication-results", | ||
| # or None/absent to disable. See | ||
| # core.mda.inbound_auth for semantics. | ||
| # "native", "rspamd", "arc", | ||
| # "authentication-results", or None to disable. | ||
| # See core.mda.inbound_auth for semantics. | ||
| # trusted_arc_sealers : list of trusted ARC sealer d= domains | ||
| # (empty = trust nothing). Used by inbound_auth | ||
| # "arc" and by "arc" spam rules. When non-empty, | ||
| # a DNS failure verifying a claimed-trusted | ||
| # sealer holds the message for retry rather than | ||
| # failing open or closed. |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
Keep the SPAM_CONFIG comment aligned with the implemented rule contract.
This comment names the condition family as "arc" instead of arc_verdict, omits the accepted reject/no action aliases, and does not mention that an unresolved DNS result becomes untrusted after MESSAGES_INBOUND_DEFERRAL_MAX_AGE.
Proposed wording
- # condition — "trusted" / "untrusted" — e.g.
+ # condition — "trusted" / "untrusted" — e.g.
# {"arc_verdict": "untrusted", "action": "drop"},
- # with action spam / ham / drop.
+ # with action spam / reject, ham / no action,
+ # or drop.
...
- # "arc" spam rules. When non-empty,
+ # "arc_verdict" spam rules. When non-empty,
# a DNS failure verifying a claimed-trusted
- # sealer holds the message for retry rather than
- # failing open or closed.
+ # sealer holds the message for retry until
+ # MESSAGES_INBOUND_DEFERRAL_MAX_AGE, then treats
+ # it as untrusted.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| # rules : list of spam rules; each is a header_match / | |
| # header_match_regex OR an "arc_verdict" trust | |
| # condition — "trusted" / "untrusted" — e.g. | |
| # {"arc_verdict": "untrusted", "action": "drop"}, | |
| # with action spam / ham / drop. | |
| # inbound_auth : sender authentication backend — one of | |
| # "native", "rspamd", "authentication-results", | |
| # or None/absent to disable. See | |
| # core.mda.inbound_auth for semantics. | |
| # "native", "rspamd", "arc", | |
| # "authentication-results", or None to disable. | |
| # See core.mda.inbound_auth for semantics. | |
| # trusted_arc_sealers : list of trusted ARC sealer d= domains | |
| # (empty = trust nothing). Used by inbound_auth | |
| # "arc" and by "arc" spam rules. When non-empty, | |
| # a DNS failure verifying a claimed-trusted | |
| # sealer holds the message for retry rather than | |
| # failing open or closed. | |
| # rules : list of spam rules; each is a header_match / | |
| # header_match_regex OR an "arc_verdict" trust | |
| # condition — "trusted" / "untrusted" — e.g. | |
| # {"arc_verdict": "untrusted", "action": "drop"}, | |
| # with action spam / reject, ham / no action, | |
| # or drop. | |
| # inbound_auth : sender authentication backend — one of | |
| # "native", "rspamd", "arc", | |
| # "authentication-results", or None to disable. | |
| # See core.mda.inbound_auth for semantics. | |
| # trusted_arc_sealers : list of trusted ARC sealer d= domains | |
| # (empty = trust nothing). Used by inbound_auth | |
| # "arc" and by "arc_verdict" spam rules. When non-empty, | |
| # a DNS failure verifying a claimed-trusted | |
| # sealer holds the message for retry until | |
| # MESSAGES_INBOUND_DEFERRAL_MAX_AGE, then treats | |
| # it as untrusted. |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/backend/messages/settings.py` around lines 555 - 569, Update the
SPAM_CONFIG documentation comment to describe ARC conditions using the
implemented arc_verdict key, include the accepted reject and no-action aliases
alongside spam, ham, and drop, and document that unresolved DNS verification is
treated as untrusted after MESSAGES_INBOUND_DEFERRAL_MAX_AGE.
Local branch from #756
Summary by CodeRabbit
New Features
arcmode in spam filtering viaarc_verdictconditions (trusted, untrusted, DNS-indeterminate), includingdropactions.Documentation
Tests