Collects email DNS security posture (MX, SPF, DMARC, DKIM)
epack install collector email-dns
Adds to epack.yaml, resolves dependencies, downloads binary.
Run all configured collectors and build a pack:
epack collect
Runs all collectors in epack.yaml and outputs an evidence pack.
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.
The Email DNS Posture Collector gathers email security configuration from DNS records for your domains.
This collector queries DNS for each configured domain and aggregates email authentication posture:
All metrics include enforcement status (whether DMARC is set to p=reject) and reporting configuration.
_dmarc.domain for DMARCselector._domainkey.domain for common DKIM selectorsThis collector does not require authentication - it only queries public DNS records.
See Configuration for setup instructions.
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
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
domains |
[]string | Yes | - | List of email domains to scan |
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.
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.
"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".
stream: myorg/email-dns-posture
collectors:
email-dns:
source: locktivity/epack-collector-email-dns@^0.1
config:
domains:
- example.com
Then run:
epack collect
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
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
{
"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
}
}
}
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 |
| 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 |
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
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"
**Full Changelog**: https://github.com/locktivity/epack-collector-email-dns/compare/v0.1.2...v0.1.3
**Full Changelog**: https://github.com/locktivity/epack-collector-email-dns/compare/v0.1.1...v0.1.2
**Full Changelog**: https://github.com/locktivity/epack-collector-email-dns/compare/v0.1.0...v0.1.1