From 516657bf6a3fdaa903421e87d66ba4d55b01b913 Mon Sep 17 00:00:00 2001 From: tegwick Date: Sun, 18 Oct 2026 22:32:23 +0200 Subject: [PATCH] MAS-WP-0005-T05: split into T11-T13 (MTA milters, gateway verdict, live check); note in MAS-WP-0004 Co-Authored-By: Claude Opus 5.5 Assistant: claude-code Assistant-Model: opus Assistant-Process: 252470@bnt-lap001 Assistant-Session: ad628c8f-4be2-4979-94c9-76c7ed6f8241 --- ...MAS-WP-0004-postfix-integration-profile.md | 5 +- workplans/MAS-WP-0005-spec-errata-v0-1-1.md | 51 ++++++++++++++++++- 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/workplans/MAS-WP-0004-postfix-integration-profile.md b/workplans/MAS-WP-0004-postfix-integration-profile.md index a304d54..05b54a3 100644 --- a/workplans/MAS-WP-0004-postfix-integration-profile.md +++ b/workplans/MAS-WP-0004-postfix-integration-profile.md @@ -38,7 +38,10 @@ the relay regexp) for a MAS receiving domain: - `allow_untrusted_routing=yes`, `swap_bangpath=no` and `allow_percent_hack=no`; - pipe to `mas-gateway`; - optional authenticated relay with a send cap; -- null-sender discard. +- null-sender discard; +- sender authentication: OpenDKIM (verify) + OpenDMARC milters with + `RemoveARFrom` for the host's authserv-id, annotate-only (from + MAS-WP-0005 T11; spec §14 item 10). Explain each setting and say why the stock config fails. ## Probe the profile diff --git a/workplans/MAS-WP-0005-spec-errata-v0-1-1.md b/workplans/MAS-WP-0005-spec-errata-v0-1-1.md index 913d5d1..ed660f1 100644 --- a/workplans/MAS-WP-0005-spec-errata-v0-1-1.md +++ b/workplans/MAS-WP-0005-spec-errata-v0-1-1.md @@ -172,7 +172,7 @@ rather than errata. ```task id: MAS-WP-0005-T05 -status: todo +status: progress priority: medium state_hub_task_id: "8d3bc09e-6f8d-5125-b10c-45b9aa5643a2" ``` @@ -187,6 +187,12 @@ Implement the SHOULD part of spec §14 item 10 in the reference stack: Decided 2026-10-18 to keep this out of the v0.1.1 errata code. +Split 2026-10-18 into T11 to T13. Authentication runs in the MTA +(OpenDKIM + OpenDMARC milters), because SPF, DKIM and DMARC need DNS and +only `mas_core/discovery.py` may touch the network. The gateway only +reads the `Authentication-Results` header carrying our own authserv-id, +and the MTA strips incoming headers that claim it. + ## Redeploy the live MX with v0.1.1 ```task @@ -347,3 +353,46 @@ and case-insensitive ids. Repeat the IONOS forward test with reply, Google Groups (lower-cased) and IONOS forward (stand-in). T04 is complete. `mas explain` also shows "read as … (v0.2 stand-in)". +## MTA authentication: OpenDKIM + OpenDMARC milters + +```task +id: MAS-WP-0005-T11 +status: progress +priority: medium +``` + +In the live image, OpenDKIM (verify only) and OpenDMARC (SPF +self-validation) run as Postfix smtpd milters. Both add +`Authentication-Results: mas.coulomb.social; …`. Incoming A-R headers +claiming that authserv-id are removed (`RemoveARFrom`). Annotate only; +never reject on DMARC failure. Milter failure means accept +(`milter_default_action = accept`). + +## Gateway verdict and reply gating + +```task +id: MAS-WP-0005-T12 +status: todo +priority: medium +``` + +`mas-gateway` takes `--trusted-authserv-id`. It parses only A-R headers +from that id and puts `message.authentication = {dmarc, spf, dkim, +header_from}` into the event. The ticket service gets +`--require-dmarc-pass`: it still creates tickets and attaches mail, but +sends auto-replies (intake confirmation, closed notice) only when +`dmarc == pass`. Unit tests cover forged A-R headers from other ids. + +## Live check: authenticated vs forged sender + +```task +id: MAS-WP-0005-T13 +status: todo +priority: medium +``` + +Deploy. A Gmail intake (DMARC pass) gets a reply. A mail with a +`From:` in the operator's own domain sent directly from the workstation +(SPF/DKIM fail, so DMARC fail) creates a ticket but gets no reply. Check +the send counter. +