email-dns

v0.1.3 collector

Collects email DNS security posture (MX, SPF, DMARC, DKIM)

Install

epack install collector email-dns

Adds to epack.yaml, resolves dependencies, downloads binary.

Usage

Run all configured collectors and build a pack:

epack collect

Runs all collectors in epack.yaml and outputs an evidence pack.

Configuration

Or add manually to epack.yaml:

collectors:
  email-dns:
    source: https://github.com/locktivity/epack-collector-email-dns

Then run epack install to lock and sync.

Email DNS Posture Collector

The Email DNS Posture Collector gathers email security configuration from DNS records for your domains.

What It Collects

This collector queries DNS for each configured domain and aggregates email authentication posture:

  • MX Records: Mail exchange servers and priorities
  • SPF Records: Sender Policy Framework configuration
  • DMARC Records: Domain-based Message Authentication policy including:
    • Policy (none/quarantine/reject)
    • Subdomain policy
    • Percentage applied
    • Aggregate reporting URI (rua)
    • Forensic reporting URI (ruf)
  • DKIM Records: DomainKeys Identified Mail (checks common selectors)
  • Assessment: Per-domain pass/fail evaluation based on enforcement status

All metrics include enforcement status (whether DMARC is set to p=reject) and reporting configuration.

Use Cases

  • Third-party risk assessments: Provide evidence of email security posture to customers and auditors
  • Compliance monitoring: Verify all sending domains have proper email authentication
  • Security benchmarking: Track email security improvements over time
  • Gap identification: Find domains missing SPF, DKIM, or DMARC

How It Works

  1. The collector receives a list of domains from your configuration
  2. For each domain, it performs DNS lookups:
    • MX records for mail servers
    • TXT records for SPF (v=spf1)
    • TXT records at _dmarc.domain for DMARC
    • TXT records at selector._domainkey.domain for common DKIM selectors
  3. Records are parsed and validated
  4. Per-domain assessment is computed (enforced, has reporting, issues)
  5. Summary statistics are aggregated
  6. Output is wrapped in the epack collector protocol envelope

Authentication

This collector does not require authentication - it only queries public DNS records.

See Configuration for setup instructions.

Configuration

Basic Setup

The Email DNS collector queries public DNS records and does not require authentication.

collectors:
  email-dns:
    source: locktivity/epack-collector-email-dns@^0.1
    config:
      domains:
        - example.com
        - company.org

Configuration Options

Field Type Required Default Description
domains []string Yes - List of email domains to scan

DKIM Selectors

The collector automatically checks these common DKIM selectors for each domain:

Selector Provider
default Generic
selector1, selector2 Microsoft 365
google Google Workspace
k1 Mailchimp
s1, s2 Generic
mail Generic
dkim Generic

If your organization uses custom DKIM selectors not in this list, the DKIM check may not find them. The collector reports what it finds, but absence of a DKIM record doesn't necessarily mean DKIM isn't configured.

DNS Resolution

The collector uses the system's default DNS resolver. For consistent results across environments, ensure your DNS resolver can reach authoritative nameservers for all configured domains.

Troubleshooting

"domains is required"

The domains field must be set in your config:

config:
  domains:
    - example.com  # Required - at least one domain

DNS lookup failures

If DNS lookups fail for specific domains:
- Verify the domain exists and is reachable
- Check your network's DNS resolution
- Ensure the domain's DNS servers are responding

Missing DKIM records

DKIM records may not be found if:
- The domain uses a custom selector not in the default list
- DKIM is not configured for the domain
- The DKIM record has been removed or is misconfigured

DMARC policy shows "unknown"

The DMARC policy is extracted from the p= tag. If parsing fails or the policy value is non-standard, it will show as "unknown".

Examples

Basic Usage

Single Domain

stream: myorg/email-dns-posture

collectors:
  email-dns:
    source: locktivity/epack-collector-email-dns@^0.1
    config:
      domains:
        - example.com

Then run:

epack collect

Multiple Domains

stream: myorg/email-dns-posture

collectors:
  email-dns:
    source: locktivity/epack-collector-email-dns@^0.1
    config:
      domains:
        - example.com
        - company.org
        - brand.io
        - marketing.example.com

Including Parked Domains

Best practice is to include all domains you own, including parked domains. Parked domains should still have DMARC set to p=reject to prevent spoofing.

collectors:
  email-dns:
    source: locktivity/epack-collector-email-dns@^0.1
    config:
      domains:
        - example.com           # Primary domain
        - corp.example.com      # Corporate subdomain
        - parked-domain.com     # Parked domain
        - old-brand.com         # Legacy domain

Sample Output

{
  "protocol_version": 1,
  "data": {
    "schema_version": "1.0.0",
    "collected_at": "2026-04-20T10:30:00Z",
    "domains": [
      {
        "domain": "example.com",
        "mx": [
          {"host": "smtp.google.com", "priority": 10}
        ],
        "spf": {
          "record": "v=spf1 include:_spf.google.com ~all",
          "valid": true
        },
        "dmarc": {
          "record": "v=DMARC1; p=reject; sp=reject; pct=100; rua=mailto:dmarc@example.com",
          "policy": "reject",
          "subdomain_policy": "reject",
          "pct": 100,
          "rua": "mailto:dmarc@example.com",
          "valid": true
        },
        "dkim": [
          {"selector": "google", "record": "v=DKIM1; k=rsa; p=...", "valid": true}
        ],
        "assessment": {
          "enforced": true,
          "has_reporting": true
        }
      },
      {
        "domain": "parked-domain.com",
        "mx": [],
        "spf": {
          "record": "v=spf1 -all",
          "valid": true
        },
        "dmarc": {
          "record": "v=DMARC1; p=reject; sp=reject",
          "policy": "reject",
          "subdomain_policy": "reject",
          "pct": 100,
          "valid": true
        },
        "assessment": {
          "enforced": true,
          "has_reporting": false,
          "issues": [
            "No DMARC aggregate reporting (rua) configured",
            "No DKIM records found for common selectors (custom selectors not checked)"
          ]
        }
      }
    ],
    "summary": {
      "total_domains": 2,
      "with_mx_pct": 50,
      "with_spf_pct": 100,
      "with_dmarc_pct": 100,
      "with_dkim_pct": 50,
      "with_all_three_pct": 50,
      "enforced_pct": 100,
      "with_reporting_pct": 50,
      "all_enforced": true
    }
  }
}

Understanding the Output

Assessment

Each domain includes an assessment object:

Field Description
enforced true if DMARC policy is reject with pct=100
has_reporting true if rua (aggregate reports) is configured
issues List of problems found

Summary Metrics

Field Description
total_domains Number of domains scanned
with_mx_pct Percentage of domains with MX records
with_spf_pct Percentage of domains with SPF records
with_dmarc_pct Percentage of domains with DMARC records
with_dkim_pct Percentage of domains with DKIM records
with_all_three_pct Percentage with MX + SPF + DMARC
enforced_pct Percentage with DMARC p=reject
with_reporting_pct Percentage with aggregate reporting (rua)
all_enforced true only if ALL domains have p=reject

Pass Criteria

For full compliance with email authentication requirements:
- all_enforced should be true
- with_reporting_pct should be 100
- All sending domains should have SPF and DKIM

CI/CD Integration

GitHub Actions

name: Collect Evidence

on:
  schedule:
    - cron: "0 0 * * 1"  # Weekly on Monday
  workflow_dispatch:

jobs:
  collect:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install epack
        run: |
          curl -sSL https://github.com/locktivity/epack/releases/latest/download/epack-linux-amd64 -o epack
          chmod +x epack
          sudo mv epack /usr/local/bin/

      - name: Collect evidence
        run: epack collect --frozen

      - name: Upload pack
        uses: actions/upload-artifact@v4
        with:
          name: evidence-pack
          path: "*.pack"
v0.1.3 Latest
2026-04-21

**Full Changelog**: https://github.com/locktivity/epack-collector-email-dns/compare/v0.1.2...v0.1.3

darwin/amd64 darwin/arm64 linux/amd64 linux/arm64
v0.1.2
2026-04-21

**Full Changelog**: https://github.com/locktivity/epack-collector-email-dns/compare/v0.1.1...v0.1.2

darwin/amd64 darwin/arm64 linux/amd64 linux/arm64
v0.1.1
2026-04-21

**Full Changelog**: https://github.com/locktivity/epack-collector-email-dns/compare/v0.1.0...v0.1.1

darwin/amd64 darwin/arm64 linux/amd64 linux/arm64

Details

Publisher
locktivity
Latest
v0.1.3
Protocol
v1

Platforms

darwin/amd64 darwin/arm64 linux/amd64 linux/arm64

Links