RealTimeTrigger icon
Schedule icon
Queries icon
Switch icon
Script icon
If icon
Exit icon
JsonToIon icon
Batch icon
SlackIncomingWebhook icon
Query icon
Pause icon
WorkingDirectory icon
Clone icon
PushExecutionFiles icon
Create icon
Set icon

DMARC Aggregate Report Analyzer with Sender Inventory and Evidence-Based Policy Tightening

Parse DMARC aggregate reports with Kestra, inventory every sender, alert on spoofing, and tighten DMARC from none to reject through approved DNS pull requests.

Categories
Infrastructure

Most domains stay on DMARC p=none because nobody reads the daily XML reports. Tightening blindly drops mail from a forgotten SaaS sender; staying on none leaves the domain open to spoofing. This flow reads the reports and proposes the next policy step only when every authorized sender is ready.

How it works

  1. reports_mailbox (email.RealTimeTrigger) starts a run for each report email; a report_file upload backfills older reports.
  2. parse_reports unpacks .zip and .gz files, parses them with defusedxml and matches each source's reverse DNS to authorized_senders. jdbc.postgresql.Batch stores them, skipping known reports, and spoofing_wave alerts on large failing volumes from unknown sources.
  3. weekly_review (Schedule) computes each sender's pass rate and the current policy, and picks the next ladder step only if every authorized sender passes pass_threshold over min_days_clean days and the previous step is live.
  4. approve (Pause) asks a person. On approval the flow clones the DNS repository (git.Clone), changes only the p= and pct= tags of the DMARC record, pushes a branch (git.PushExecutionFiles) and opens a pull request with the evidence (github.pulls.Create).

What you get

  • A Postgres inventory of every source sending as your domain, with SPF, DKIM and DMARC results.
  • Spoofing alerts, and a weekly digest naming each blocker, such as a sender whose DKIM isn't aligned.
  • One-line DNS pull requests with the evidence table, one ladder step at a time.

Who it's for

  • Security, IT and email deliverability teams who own a domain's DMARC policy.

Why orchestrate this with Kestra

Trigger, database, approval and Git change run as one audited flow with retries; DNS changes still get your repository's review.

Prerequisites

  • A mailbox your DMARC rua= address delivers to, a PostgreSQL database, and a DNS-as-code repository on GitHub (BIND, octoDNS, Terraform or dnscontrol file with one DMARC record).
  • Set domain, authorized_senders, imap_host, dns_repo and dns_file in variables.

Secrets

  • DMARC_IMAP_USERNAME, DMARC_IMAP_PASSWORD: read the report mailbox.
  • DMARC_DB_URL, DMARC_DB_USERNAME, DMARC_DB_PASSWORD: JDBC URL and login for Postgres.
  • GITHUB_TOKEN: clone the DNS repository, push the branch and open the pull request.
  • SLACK_WEBHOOK_URL: spoofing alerts, digests and failures.

Quick start

  1. Add the secrets and set variables.
  2. Execute with mode: ingest and a .zip of past reports to backfill.
  3. Execute with mode: review and dry_run: true to read the digest without opening a pull request.
  4. Enable reports_mailbox and weekly_review.

Outputs: {{ outputs.ready_for_next_step }}, {{ outputs.pull_request }} and {{ outputs.assess.outputFiles['senders.csv'] }}.

How to extend

  • Add ip_ranges to authorized_senders for your own mail servers.
  • Point Grafana or Metabase at the dmarc_records table.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.