dmarc-parser

Parses DMARC aggregate report emails from Gmail and writes the results to one or more metrics backends: InfluxDB v2 (default) and/or Prometheus (via Pushgateway).

Designed to run as a Kubernetes CronJob. Each invocation fetches all emails with a configured Gmail label, extracts XML report attachments (plain, gzip, or zip), parses them into records, writes to the configured backends, and deletes the processed emails. Emails are only deleted after every backend has flushed successfully, so a backend outage never discards unrecorded reports.

Environment Variables

Variable Default Description
GMAIL_TOKEN_FILE /config/gmail-token.json Path to Gmail OAuth token JSON
GMAIL_LABEL DMARC Gmail label to search for reports
GMAIL_USER me Gmail user ID
METRICS_BACKENDS influxdb Comma-separated backends: influxdb, prometheus
INFLUXDB_URL http://localhost:8086 InfluxDB v2 URL
INFLUXDB_TOKEN (required for influxdb) InfluxDB API token
INFLUXDB_ORG home InfluxDB organization
INFLUXDB_BUCKET metrics InfluxDB bucket
PROMETHEUS_PUSHGATEWAY_URL http://localhost:9091 Pushgateway URL (prometheus backend)
PROMETHEUS_JOB dmarc-parser Pushgateway job name
DELETE_AFTER_PROCESSING true Delete emails after processing

Metrics Backends

Select backends with METRICS_BACKENDS, e.g. influxdb, prometheus, or influxdb,prometheus.

InfluxDB (default) stores one point per report record with full tag detail, timestamped at the report’s date range. Use this backend if you want historical analysis — it is what the bundled Grafana dashboard queries.

Prometheus pushes per-run totals to a Pushgateway (the standard pattern for run-to-completion batch jobs). Because Prometheus samples are timestamped at scrape time, per-report timestamps are not preserved, and high-cardinality keys (source_ip, report_id, …) are deliberately excluded from labels. Metrics exposed:

Metric Labels Meaning
dmarc_run_messages domain, org_name, disposition, policy_dkim, policy_spf, policy_p Messages evaluated in reports processed by the most recent run
dmarc_run_reports Reports parsed by the most recent run
dmarc_last_run_timestamp_seconds Unix time of the most recent push

Grafana Dashboard

An example dashboard for the InfluxDB backend is provided at dashboards/dmarc-reports.json: pass/fail trends, DKIM/SPF results over time, volume by domain and reporting org, a top-source-IPs table for spotting spoofing, and summary stats.

Import it via Grafana → Dashboards → Import, then select your InfluxDB (Flux) datasource when prompted. Queries assume the default metrics bucket; adjust if you changed INFLUXDB_BUCKET.

Gmail Setup

  1. Create a Google Cloud project with the Gmail API enabled
  2. Create OAuth 2.0 credentials (Desktop application type)
  3. Run the Gmail API Python quickstart auth flow with the gmail.modify scope to generate a token JSON file
  4. Mount the token file into the container at GMAIL_TOKEN_FILE

Docker

docker build -t dmarc-parser .
docker run -v /path/to/gmail-token.json:/config/gmail-token.json \
  -e INFLUXDB_TOKEN=your-token \
  dmarc-parser

InfluxDB Schema

Measurement: dmarc_report

Tags: org_name, domain, report_id, source_ip, header_from, envelope_from, disposition, policy_dkim, policy_spf, policy_p, auth_dkim_domain, auth_dkim_result, auth_spf_domain, auth_spf_result

Fields: count (int), pass (0/1), fail (0/1)

License

MIT