Skip to content

linyows/reports

Repository files navigation

English | 日本語

REPORTS

DMARC and MTA-STS report viewer

GitHub Workflow Status GitHub Release

Architecture

graph TD
    subgraph IMAP Servers
        S1[IMAP Server<br>Gmail, etc.]
        S2[IMAP Server<br>Work, etc.]
    end

    subgraph reports
        IMAP[IMAP Client<br><i>libcurl</i>]
        MIME[MIME Parser<br><i>base64 decode</i>]
        DECOMP[Decompress<br><i>gzip/zip via zlib</i>]
        DMARC[DMARC Parser<br><i>libxml2</i>]
        MTASTS[MTA-STS Parser<br><i>std.json</i>]
        STORE[(Store<br>JSON files per account)]
        CLI[CLI / C ABI<br>fetch, list, show, summary]
    end

    S1 -- IMAPS --> IMAP
    S2 -- IMAPS --> IMAP
    IMAP --> MIME --> DECOMP
    DECOMP --> DMARC
    DECOMP --> MTASTS
    DMARC --> STORE
    MTASTS --> STORE
    STORE --> CLI

    CLI --> Terminal[Terminal<br>table output]
    CLI --> JSON[JSON stdout<br>--format json]
    CLI --> Swift[SwiftUI macOS<br>via libreports-core.a]
Loading

Features

  • Fetch DMARC aggregate reports (RFC 7489) and TLS-RPT reports (RFC 8460) from IMAP
  • Multiple IMAP account support with per-account storage
  • Parse XML/JSON report formats with ZIP/GZIP decompression
  • List, show, and summarize reports with table or JSON output
  • Filter by account, domain, and time period (week/month/year)
  • Incremental fetch with UID tracking (skips already-fetched messages)
  • Parallel IMAP fetch with multiple connections, auto-scaled to CPU cores (~3.5x faster)
  • Headless core with C ABI static library for native UI integration

Installation

Build from source

Requires Zig 0.15.2 or later.

$ git clone https://github.com/linyows/reports.git
$ cd reports
$ zig build --release=fast

The binary will be available at ./zig-out/bin/reports.

Dependencies

  • libxml2 - DMARC XML parsing
  • libcurl - IMAP connectivity
  • zlib - gzip/zip decompression

On macOS, these are included in the SDK. On Linux:

$ sudo apt-get install libxml2-dev libcurl4-openssl-dev zlib1g-dev

Usage

Configure

Create ~/.config/reports/config.json:

{
  "accounts": [
    {
      "name": "personal",
      "host": "imap.gmail.com",
      "port": 993,
      "username": "you@gmail.com",
      "password": "your-app-password",
      "mailbox": "INBOX",
      "tls": true
    }
  ]
}

For Gmail, generate an App Password. Set mailbox to the label name if reports are filtered (e.g., "dmarc").

Legacy single-account format ("imap": {...}) is also supported and treated as a "default" account.

Fetch reports

$ reports fetch
$ reports fetch --account personal
$ reports fetch --full          # re-fetch all messages

Messages are fetched in parallel using multiple IMAP connections (auto-scaled to CPU cores). Subsequent runs skip already-fetched messages via UID tracking.

List reports

$ reports list
ACCOUNT    TYPE     ORGANIZATION         REPORT ID                      DATE              DOMAIN
---------- -------- -------------------- ------------------------------ ----------------- --------------------
personal   DMARC    google.com           12864733003343132926           2026-04-02 00:00  example.com
personal   DMARC    google.com           3504435274969495050            2026-04-01 00:00  example.com
...

$ reports list --account personal --domain example.com
$ reports list --format json

Show report details

$ reports show 12864733003343132926
Organization: google.com
Report ID:    12864733003343132926
Domain:       example.com
Policy:       none

SOURCE IP        COUNT  DISPOSITION  ENVELOPE FROM             HEADER FROM               DKIM   SPF
---------------- ------ ------------ ------------------------- ------------------------- ------ ------
198.51.100.1    4      none                                   example.com              fail   pass

$ reports show 12864733003343132926 --format json

Summary statistics

$ reports summary --format table
DMARC Reports:    186
TLS-RPT Reports:  0
Total Messages:   547
DKIM/SPF Pass:    182
DKIM/SPF Fail:    365

$ reports summary --period month --format table
$ reports summary --account personal --domain example.com --format json

List domains

$ reports domains
$ reports domains --format json

Performance

The fetch command uses parallel IMAP connections to download messages concurrently. The number of workers is automatically determined based on CPU core count (up to 16).

Mode 224 messages
Sequential (single connection) 1m 54s
Parallel (auto-scaled workers) 33s

Incremental UID tracking ensures that subsequent runs only fetch new messages, making regular use nearly instant.

C ABI / SwiftUI Integration

The build produces a static library and C header for native app integration:

$ zig build
$ ls zig-out/lib/libreports-core.a
$ ls zig-out/include/reports.h
#include "reports.h"

reports_init();
char *json = reports_list(config_json);
// use json...
reports_free_string(json);
reports_deinit();

Comparison with Other Tools

Tool Language UI DMARC TLS-RPT IMAP Fetch No Infra Required
Reports Zig + Swift CLI + macOS native Yes Yes Yes (parallel) Yes
parsedmarc Python CLI + Elasticsearch/Grafana Yes No Yes No
dmarc-report-viewer Rust Web (single binary) Yes Yes Yes Yes
dmarcguard Go + Vue.js Web (single binary) Yes No Yes Yes
dmarc-visualizer Docker Web (Grafana) Yes No No No
dmarc-report-converter Go CLI Yes No No Yes
dmarc-srg PHP Web Yes No No No
Viesti-Reports PHP Web Yes Yes No No

Key differentiators of Reports:

  • Native macOS app -- The only open-source DMARC/TLS-RPT tool with a native desktop GUI (SwiftUI), not just a web UI or CLI
  • Headless core architecture -- Zig-based core compiled to a C ABI static library, enabling both CLI and native UI from a single codebase (inspired by Ghostty)
  • Parallel IMAP fetch -- Multi-threaded worker pool auto-scaled to CPU cores, ~3.5x faster than sequential fetch
  • Zero external infrastructure -- No database, web server, or Docker required; just a config file and local JSON storage
  • DNS-based IP enrichment -- PTR, ASN, organization, and country lookup via DNS queries (Team Cymru) without external API keys or GeoIP databases
  • Monitoring integration -- check command with exit codes (0/1/2) for anomaly detection, designed for cron jobs and monitoring systems

Development

# Build
zig build

# Run tests
zig build test

# Format check
zig fmt --check src/

# Run
zig build run -- help

Author

linyows

About

DMARC and MTA-STS report viewer

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages