Mailflow Security Scoreยถ

Understanding the 0-100 Mailflow Security Score and transparent scoring rubric.


Overviewยถ

The Mailflow Security Score is a 0-100 rating that measures your domain's email security configuration. It starts at 100 (perfect) and deducts points based on security issues found in your SPF, DKIM, and DMARC records.

Key Principlesยถ

โœ… Transparent - Every deduction is clearly explained โœ… Actionable - Each issue includes fix instructions and DNS snippets โœ… Weighted - More critical issues deduct more points โœ… Deterministic - Same configuration always produces same score


Score Rangesยถ

  • โœ… 90-100: Excellent


    Your email security is well-configured with only minor improvements possible.

  • โœ“ 75-89: Good


    Solid configuration with some medium-priority improvements needed.

  • โš ๏ธ 50-74: Fair


    Basic security in place but significant vulnerabilities exist.

  • โŒ 0-49: Poor


    Critical security issues found. Immediate action required.


Severity Levelsยถ

Issues are categorized by severity, which determines point deductions:

Severity Point Range Description Examples
Critical 20-40 pts Major security vulnerabilities Missing DMARC, SPF allows all
High 10-20 pts Significant security gaps Missing DKIM, weak SPF
Medium 5-10 pts Important improvements DMARC policy=none, no reports
Low 1-5 pts Best practice violations Relaxed alignment, low pct

Complete Scoring Rubricยถ

DMARC Issuesยถ

CRITICAL DMARC_MISSING (-40 points)ยถ

Issue: DMARC record not found

Description: No DMARC policy found at _dmarc.{domain}. This is the most critical email security control.

Fix:

_dmarc.example.com. IN TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.com; pct=100"

Steps: 1. Start with p=none to monitor 2. Review aggregate reports (rua) 3. Gradually move to p=quarantine then p=reject


HIGH DMARC_POLICY_NONE (-15 points)ยถ

Issue: DMARC policy set to p=none

Description: DMARC is in monitoring mode only. No enforcement against spoofed emails.

Fix:

_dmarc.example.com. IN TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com; pct=100"

When to upgrade: - After 1-2 weeks of monitoring - When aggregate reports show 100% legitimate mail passes - When you're confident in SPF/DKIM configuration


MEDIUM DMARC_POLICY_QUARANTINE (-5 points)ยถ

Issue: DMARC policy not at maximum enforcement

Description: Policy is p=quarantine. For maximum protection, use p=reject.

Fix:

_dmarc.example.com. IN TXT "v=DMARC1; p=reject; rua=mailto:dmarc@example.com; pct=100"


MEDIUM DMARC_NO_RUA (-5 points)ยถ

Issue: DMARC missing aggregate reports (rua)

Description: No rua= tag means you won't receive DMARC aggregate reports for monitoring.

Fix:

# Add to your DMARC record:
rua=mailto:dmarc-reports@example.com


MEDIUM DMARC_PCT_LOW (-5 points)ยถ

Issue: DMARC percentage (pct) is less than 100

Description: Only X% of failing messages are subject to policy. Use pct=100 for full protection.

Fix:

# Set in your DMARC record:
pct=100


LOW DMARC_ALIGNMENT_STRICT (-2 points)ยถ

Issue: DMARC alignment could be stricter

Description: Using relaxed alignment (adkim=r or aspf=r). Strict alignment (s) provides stronger protection.

Fix:

# If all mail uses exact domain match:
adkim=s; aspf=s


SPF Issuesยถ

CRITICAL SPF_MISSING (-30 points)ยถ

Issue: SPF record not found

Description: No SPF record exists for {domain}. Emails may be rejected or marked as spam.

Fix:

example.com. IN TXT "v=spf1 include:_spf.google.com -all"

Common SPF Examples:

# Google Workspace
"v=spf1 include:_spf.google.com -all"

# Microsoft 365
"v=spf1 include:spf.protection.outlook.com -all"

# Multiple providers
"v=spf1 include:_spf.google.com include:spf.protection.outlook.com -all"

# With specific IPs
"v=spf1 ip4:192.0.2.0/24 include:_spf.google.com -all"


CRITICAL SPF_PASS_ALL (-40 points)ยถ

Issue: SPF allows all senders (+all)

Description: SPF record ends with +all, allowing anyone to send mail as your domain. Critical vulnerability.

Fix:

# Replace +all with -all
v=spf1 include:_spf.google.com -all


CRITICAL SPF_MULTIPLE_RECORDS (-30 points)ยถ

Issue: Multiple SPF records found

Description: RFC 7208 requires exactly one SPF record. Multiple records cause PermError.

Fix:

# Combine into one record:
v=spf1 include:provider1.com include:provider2.com -all


HIGH SPF_SOFTFAIL (-10 points)ยถ

Issue: SPF uses ~all (softfail) instead of -all

Description: SPF softfail (~all) may allow spoofed emails. Use -all (hardfail) for stronger protection.

Fix:

# Change ~all to -all
v=spf1 include:_spf.google.com -all


HIGH SPF_NEUTRAL (-15 points)ยถ

Issue: SPF uses ?all (neutral)

Description: SPF neutral (?all) provides no protection. Use -all for enforcement.

Fix:

# Change ?all to -all
v=spf1 include:_spf.google.com -all


HIGH SPF_TOO_MANY_LOOKUPS (-12 points)ยถ

Issue: SPF exceeds 10 DNS lookup limit

Description: SPF record requires more than 10 DNS lookups. Receivers will treat this as PermError.

Fix:

# Option 1: Use SPF flattening service
# Option 2: Replace includes with IP addresses
v=spf1 ip4:192.0.2.0/24 ip4:198.51.100.0/24 -all

# Option 3: Use SPF macros (advanced)

Tools: - SPF Flattener - EasyDMARC SPF Record Generator


HIGH SPF_SYNTAX_ERROR (-20 points)ยถ

Issue: SPF syntax error

Description: SPF record has syntax errors.

Common Errors: - Missing v=spf1 at start - Invalid mechanisms - Typos in domain names - Missing -all at end


DKIM Issuesยถ

HIGH DKIM_MISSING (-20 points)ยถ

Issue: No DKIM keys found

Description: No DKIM public keys discovered for common selectors. DKIM signatures authenticate your emails.

Fix:

# Example for Google Workspace
google._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGS..."

# Example for custom selector
default._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=YOUR_PUBLIC_KEY"

Generate DKIM Key:

# Generate 2048-bit RSA key
openssl genrsa -out dkim.private 2048
openssl rsa -in dkim.private -pubout -outform PEM

# Or use your email provider's DKIM setup wizard


HIGH DKIM_KEY_TOO_SHORT (-15 points)ยถ

Issue: DKIM key length below 2048 bits

Description: DKIM key is less than 2048 bits. Keys under 2048 bits are considered weak.

Fix: - Generate new 2048-bit or 4096-bit RSA key - Or use Ed25519 (modern, smaller, faster)

# Generate 2048-bit key
openssl genrsa -out dkim.private 2048

# Or 4096-bit for extra security
openssl genrsa -out dkim.private 4096

CRITICAL DKIM_KEY_REVOKED (-25 points)ยถ

Issue: DKIM key is revoked

Description: DKIM selector has empty or missing p= tag, indicating revoked key.

Fix: - Publish a valid DKIM public key - Or remove the revoked DNS record entirely


HIGH DKIM_SYNTAX_ERROR (-15 points)ยถ

Issue: DKIM record syntax error

Description: DKIM record has syntax errors.

Common Errors: - Missing v=DKIM1 - Invalid base64 in p= tag - Typos in tag names - Missing semicolons


Score Calculation Exampleยถ

Let's walk through a real example:

Domain Configurationยถ

# SPF Record
example.com. IN TXT "v=spf1 include:_spf.google.com ~all"

# DKIM Record
google._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIGfM..." (1024-bit)

# DMARC Record
_dmarc.example.com. IN TXT "v=DMARC1; p=none;"

Issues Foundยถ

Issue Severity Deduction
SPF_SOFTFAIL (~all instead of -all) High -10
DKIM_KEY_TOO_SHORT (1024-bit) High -15
DMARC_POLICY_NONE (p=none) High -15
DMARC_NO_RUA (no reports) Medium -5

Score Calculationยถ

Starting Score:     100
Total Deductions:   -45
Final Score:        55/100 (Fair)

Potential if Fixed: 100/100
Score Gain:         +45 points

Improving Your Scoreยถ

Quick Wins (Easy Fixes)ยถ

  1. Add DMARC Reports (+5 points)

    rua=mailto:dmarc@example.com
    

  2. Change SPF to Hard Fail (+10 points)

    ~all โ†’ -all
    

  3. Set DMARC Percentage to 100 (+5 points)

    pct=100
    

Medium Effortยถ

  1. Upgrade to DMARC Quarantine (+15 points)

    p=none โ†’ p=quarantine
    

  2. Generate 2048-bit DKIM Key (+15 points)

  3. Generate new key
  4. Publish to DNS
  5. Update mail server

High Impactยถ

  1. Upgrade to DMARC Reject (+20 points)

    p=quarantine โ†’ p=reject
    

  2. Add DKIM if Missing (+20 points)

  3. Configure mail server for DKIM signing
  4. Publish public keys

Monitoring Your Scoreยถ

Track Progress Over Timeยถ

Use the /api/v1/history endpoint to monitor improvements:

import requests

response = requests.get(
    "https://api.reputeapi.com/api/v1/history",
    params={"domain": "example.com", "days": 30},
    headers={"X-API-Key": "your-api-key"}
)

history = response.json()
for snapshot in history['snapshots']:
    print(f"{snapshot['timestamp']}: {snapshot['score']}/100")

Set Up Alertsยถ

Monitor your score and get alerted to changes:

def check_score_threshold(domain, min_score=80):
    """Alert if score drops below threshold"""
    response = requests.get(
        f"https://api.reputeapi.com/api/v1/score",
        params={"domain": domain},
        headers={"X-API-Key": "your-api-key"}
    )

    score = response.json()['score']

    if score < min_score:
        send_alert(f"Email security score dropped to {score}")

    return score

Best Practicesยถ

Start with Monitoringยถ

  1. Add DMARC with p=none

    v=DMARC1; p=none; rua=mailto:dmarc@example.com
    

  2. Monitor reports for 1-2 weeks

  3. Verify all legitimate mail passes
  4. Gradually increase enforcement

Progressive Enhancementยถ

Week 1-2:  p=none (Monitor)
Week 3-4:  p=quarantine; pct=10 (Test)
Week 5-6:  p=quarantine; pct=50
Week 7+:   p=quarantine; pct=100
Month 2+:  p=reject (Full Protection)

Regular Auditsยถ

  • Weekly: Check for new issues
  • Monthly: Review aggregate reports
  • Quarterly: Audit full configuration
  • After Changes: Validate immediately

Common Questionsยถ

Why didn't my score improve immediately?ยถ

DNS changes can take time to propagate (up to 24-48 hours). The API caches results for performance, so use refresh=true to bypass cache:

curl "https://api.reputeapi.com/api/v1/check?domain=example.com&refresh=true" \
  -H "X-API-Key: your-api-key"

Can I get a perfect 100 score?ยถ

Yes! A perfect score requires: - โœ… SPF record with -all - โœ… DKIM keys (2048-bit or better) - โœ… DMARC with p=reject, pct=100, and aggregate reports - โœ… No syntax errors or misconfigurations

What's a realistic target score?ยถ

  • 75-85: Good for most organizations
  • 85-95: Great security posture
  • 95-100: Excellent, enterprise-grade

Next Stepsยถ