Flexible SPF Record Matching

When monitoring SPF (Sender Policy Framework) records, strict exact matching can cause false alerts when customers add additional mail services to their SPF configuration. Flexible matching solves this by verifying only that your required SPF components are present.

The Challenge with Exact Matching

Imagine you require customers to include include:_spf.service.com in their SPF record. With exact matching enabled, you might set up monitoring like this:

curl -X POST https://api.dnsradar.dev/monitors \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "domain": "piedpiper.com",
  "record_type": "TXT",
  "expected_value": "v=spf1 include:_spf.service.com -all",
  "is_exact_match": true
}'

This works initially, but if the customer adds Google Workspace to their email setup, their SPF record becomes:

v=spf1 include:_spf.service.com include:_spf.google.com -all

With exact matching, your monitor would trigger a MISMATCH alert, even though your required include is still present.

Enabling Flexible Matching

Set is_exact_match to false and specify only the SPF components you require:

curl -X POST https://api.dnsradar.dev/monitors \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "domain": "piedpiper.com",
  "record_type": "TXT",
  "expected_value": "v=spf1 include:_spf.service.com",
  "is_exact_match": false
}'

How Flexible Matching Works

With flexible matching enabled for SPF records, DNSRadar:

  1. Verifies the SPF record starts with v=spf1
  2. Checks that all mechanisms and modifiers in your expected_value are present
  3. Ignores additional mechanisms, modifiers, or qualifiers

Valid SPF Variations

With the flexible configuration above, these SPF records would all be considered VALID:

v=spf1 include:_spf.service.com -all
v=spf1 include:_spf.service.com ~all
v=spf1 include:_spf.service.com include:_spf.google.com -all
v=spf1 ip4:1.2.3.4 include:_spf.service.com include:_spf.microsoft.com -all

All these records contain your required include:_spf.service.com mechanism, so they pass validation regardless of additional components or modified qualifiers.

Monitoring Multiple SPF Components

You can require multiple specific SPF components:

curl -X POST https://api.dnsradar.dev/monitors \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "domain": "piedpiper.com",
  "record_type": "TXT",
  "expected_value": "v=spf1 include:_spf.service.com ip4:1.2.3.4",
  "is_exact_match": false
}'

This configuration ensures both the include:_spf.service.com mechanism and the ip4:1.2.3.4 mechanism are present, while allowing additional SPF components.

When Monitors Trigger

A MISMATCH alert will be triggered if:

  • Your required include is removed: v=spf1 include:_spf.google.com -all
  • The SPF version is missing: include:_spf.service.com -all
  • The SPF record is completely removed
  • The SPF syntax is invalid

Limitations

Best Practices

  1. Specify Minimum Requirements: Only include the SPF components you absolutely need to verify
  2. Omit Final Qualifiers: Let customers choose -all, ~all, or ?all based on their needs
  3. Test Configurations: Use the webhook testing endpoint to verify your monitoring setup
  4. Document Requirements: Clearly communicate to customers which SPF components you require

Combining with Other Record Types

Often, you'll want to monitor SPF alongside other DNS records:

curl -X POST https://api.dnsradar.dev/monitors/bulk \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "monitors": [
    {
      "domain": "piedpiper.com",
      "record_type": "TXT",
      "expected_value": "v=spf1 include:_spf.service.com",
      "is_exact_match": false
    },
    {
      "domain": "piedpiper.com",
      "subdomain": "_dmarc",
      "record_type": "TXT",
      "expected_value": "v=DMARC1",
      "is_exact_match": false
    },
    {
      "domain": "piedpiper.com",
      "record_type": "MX",
      "expected_value": [
        "mx1.service.com",
        "mx2.service.com"
      ],
      "is_exact_match": false
    }
  ],
  "group": "email-infrastructure"
}'

Next Steps