From 784e3050bd5bf91447efe50a1507b744cebf2645 Mon Sep 17 00:00:00 2001 From: Sean Whalen <44679+seanthegeek@users.noreply.github.com> Date: Thu, 4 Jun 2026 09:42:28 -0400 Subject: [PATCH] Detect aggregate reports by "domain" instead of "adkim" adkim is the published policy's DKIM alignment mode (defaulted to "r" by parsedmarc), an obscure thing to key detection on. Switch the aggregate detector to "domain" -- the reported From-domain, a required element present and non-empty in every aggregate record (2388/2388 sample rows) and unique to aggregate (failure uses reported_domain, SMTP TLS uses policy_domain). header_from is unsuitable: it can be empty when a record carries no identifiers. Co-Authored-By: Claude Opus 4.8 (1M context) --- google_secops_parser/README.md | 2 +- google_secops_parser/parsedmarc.conf | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/google_secops_parser/README.md b/google_secops_parser/README.md index 846c9ae..1f4d218 100644 --- a/google_secops_parser/README.md +++ b/google_secops_parser/README.md @@ -27,7 +27,7 @@ detects them by a field unique to each and maps them as follows: | parsedmarc report | Detected by | UDM `metadata.event_type` | |---|---|---| -| DMARC aggregate | `adkim` | `EMAIL_TRANSACTION` | +| DMARC aggregate | `domain` | `EMAIL_TRANSACTION` | | DMARC failure | `feedback_type` | `EMAIL_TRANSACTION` | | SMTP TLS (RFC 8460) | `policy_type` | `GENERIC_EVENT` | diff --git a/google_secops_parser/parsedmarc.conf b/google_secops_parser/parsedmarc.conf index 89778b2..43f60e1 100644 --- a/google_secops_parser/parsedmarc.conf +++ b/google_secops_parser/parsedmarc.conf @@ -10,7 +10,7 @@ filter { # # parsedmarc emits three flat JSON shapes, one object per syslog line, via the # CSV-row serializers (parsed_aggregate/failure/smtp_tls_reports_to_csv_rows): - # * DMARC aggregate report record -> detected by "adkim" + # * DMARC aggregate report record -> detected by "domain" # * DMARC failure report record -> detected by "feedback_type" # * SMTP TLS report record -> detected by "policy_type" # @@ -97,15 +97,20 @@ filter { } # --------------------------------------------------------------------------- - # 2. Detect the report type from a field unique to each shape. - # feedback_type / policy_type / adkim are always present and non-empty for - # their respective report types, so existence checks are reliable. + # 2. Detect the report type from a field that is always present, non-empty, + # and unique to each shape: + # feedback_type -> failure + # policy_type -> smtp_tls + # domain -> aggregate (the reported From-domain; a required + # element of every aggregate record) + # domain is preferred over header_from (which can be empty when a record + # carries no identifiers) and over adkim (a defaulted policy field). # --------------------------------------------------------------------------- if [feedback_type] { mutate { replace => { "report_type" => "failure" } } } else if [policy_type] { mutate { replace => { "report_type" => "smtp_tls" } } - } else if [adkim] { + } else if [domain] { mutate { replace => { "report_type" => "aggregate" } } }