Skip to main content

spf-dkim-dmarc-audit

PyPI

Audit a domain's SPF, DKIM and DMARC against live DNS, with explanations and a concrete fix for every finding. No dependencies — it speaks DNS itself.

pip install spf-dkim-dmarc-audit         # from PyPI, Python 3.9+
spf-dkim-dmarc-audit --domain example.com
spf-dkim-dmarc-audit --domain example.com --dkim-selector s1 --json
spf-dkim-dmarc-audit --test-spf "v=spf1 include:_spf.google.com -all"

Or straight from a clone, no install — the same code either way:

git clone https://github.com/duke5am/spf-dkim-dmarc-audit
cd spf-dkim-dmarc-audit
python3 audit.py --domain example.com
python3 audit.py --domain example.com --dkim-selector s1 --json
python3 audit.py --test-spf "v=spf1 include:_spf.google.com -all"
 Email authentication audit: github.com
 audit.py 1.0.0  |  19 DNS queries  |  0.82s

POSTURE
    SPF     1 record(s), 10 lookup-causing term(s), terminal '~'
    DMARC   p=quarantine sp=reject pct=100  rua=mailto:dmarc@github.com
    MX      0 github-com.mail.protection.outlook.com

What it catches that a naive check misses

The 10-lookup SPF limit, counted recursively. SPF allows at most 10 DNS-lookup-causing terms including those inside your include: chains, and exceeding it is a permerror — meaning SPF stops working entirely. Counting only your own top-level terms undercounts badly. This walks the whole chain with a recursion cap and cycle detection:

[spf] count= 1  include:spf.protection.outlook.com (depth 0, from github.com)
[spf] count= 6  exists:%{i}._spf.mta.salesforce.com (depth 1, from _spf.salesforce.com)
[spf] count=10  include:ab.sendgrid.net            (depth 1, from sendgrid.net)

github.com sits at exactly 10 — one provider away from breaking.

Duplicate DMARC records silently disable your policy. Publishing two v=DMARC1 records does not give you the stricter one, it gives you none of them — policy discovery terminates. Run against a real domain:

[CRITICAL] Multiple DMARC records: the policy is not applied at all

p=none with no reporting address — monitoring that reports nowhere.

Revoked versus missing DKIM keys. An empty p= tag is a revoked key; a name that returns NODATA is a missing one. They need different fixes, and conflating them wastes an afternoon.

An include: target that publishes no SPF record — that include can never match, so the senders it was meant to authorise fail.

Exit codes

0 no findings above the threshold · 1 findings present · 2 bad input (an invalid domain is rejected up front rather than producing a report full of "none published" for a name that cannot exist) · 3 no resolver answered, so nothing was checked.

Honest limits

  • It can only see DNS. It cannot see your sending reputation or inbox placement. "It goes to spam" is usually a reputation or alignment problem, not a missing record.
  • DKIM selectors must be supplied (--dkim-selector). Selectors cannot be enumerated from DNS — no tool can do this, and any that claims to is guessing.
  • Message readers differ. The 10-lookup limit mandates a permerror; how a given receiver then treats the message is up to that receiver.
  • The lookup count is worst-case. A receiver may stop earlier if an earlier mechanism matches. Worst case is the number that matters when you do not know the sending IP.
  • Read-only: it never modifies DNS and never sends mail.

The full pack

The paid kit adds copy-paste DNS record templates for seven mail providers (with the note that DKIM selectors and public keys come from the provider's console and cannot be invented), the safe migration path from p=none to p=reject, the common-breakages catalogue, the plain-language glossary, and 184 tests on 49 recorded real-DNS fixtures.

  • google-oauth-verification-preflight — Preflight an OAuth consent screen before submitting for Google verification: scope classification, branding requirements and the common rejection reasons. (if you were searching for "google oauth verification rejected")

All 28 tools in this set, grouped by what they check: dev-tools-index

If you arrived here searching for one of these, this is the tool: spf dkim dmarc check · spf lookup limit exceeded · dmarc policy audit · why do my emails go to spam

→ Email Auth DNS Audit & Fix Templates — $34 on Gumroad

Metadata

Release files for spf-dkim-dmarc-audit 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for spf-dkim-dmarc-audit 0.1.0
File Size Uploaded
spf_dkim_dmarc_audit-0.1.0.tar.gz 56.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for spf-dkim-dmarc-audit 0.1.0
File Interpreter ABI Platform
spf_dkim_dmarc_audit-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 107.1 kB

Release files / spf_dkim_dmarc_audit-0.1.0.tar.gz

Download URL spf_dkim_dmarc_audit-0.1.0.tar.gz
Size 56.2 kB
Tags Source
SHA-256 checksum
How to use checksums
3d35b65df3c4c0f435ee6bf1175888a91f53bf0a9266a1ae20adaab0b931f3cd
BLAKE2b-256 checksum
How to use checksums
0a8323742de24326a7269611a068dd40f7ba63c2c2d4643e381179ccfac6571d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.5

Release files / spf_dkim_dmarc_audit-0.1.0-py3-none-any.whl

Download URL spf_dkim_dmarc_audit-0.1.0-py3-none-any.whl
Size 50.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e0f5bc7b6e38a698011a97258f2dbafb5b00f3d61c95309aaffdf75fda198f65
BLAKE2b-256 checksum
How to use checksums
b7783d63d1e563dff7df6c97529171bef7ac1f509a0719466628c1d6967fc424
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.5

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page