CertaDNS
Skip to lesson

Staying Under the Limit · lesson 2 of 3

Dynamic SPF

After this lesson you can

Explain how an exists-based record answers per connection, and what it demands of DNS.

Assumes you have read What macros are actually used for.

Flattening answers "who may send" by copying a list. Dynamic SPF answers it by asking a question at the moment of the connection. It is the only approach that solves the lookup budget without creating something that goes stale.

The shape

v=spf1 exists:%{i}._spf.example.com -all

One term, one lookup, no list. For a connection from 198.51.100.7 the receiver resolves 198.51.100.7._spf.example.com. If it exists the mechanism matches; if it does not, evaluation moves on and hits -all.

The record never changes. Authorisation lives in the zone behind it, and changing who can send is a DNS operation rather than an SPF edit.

What the DNS side has to do

This is the part that decides whether you can have it. The zone must answer for every authorised address, and there are two ways to do that:

ApproachHowNeeds
MaterialisedWrite an actual record for every authorised address into the zone.Automation to generate and prune it. Works on any DNS provider, and the zone can get very large.
SynthesisedAnswer the query at request time from a backend that knows the current sender set.A DNS provider that supports a dynamic backend. Most do not.

The honest constraint

Dynamic SPF is the right architecture and it is not available to everyone, because it depends on something your DNS provider either offers or does not. If yours does not, the realistic options are delegation and removal — not flattening as a first resort.

What you give up

  • Readability. The record no longer documents who can send. Anyone auditing you — including you, in a year — must expand and query.
  • Cacheability. Every distinct address is a distinct name, so receivers get far fewer cache hits than they would on a handful of includes.
  • A new dependency. If the backend is down, the lookup is a void one, and enough of those are a permerror. A stale flattened record at least keeps working for the hosts that did not move.

Verifying one

Expand by hand and query. If the name resolves, the mechanism matches — the content is irrelevant, existence is the answer:

# authorised host
dig +short A 198.51.100.7._spf.example.com     -> any answer = pass

# unauthorised host
dig +short A 203.0.113.9._spf.example.com      -> NXDOMAIN = no match, falls through to -all

Test both directions when you deploy one. A backend that answers for everything is an +all with extra steps, and it will not look wrong in the record.

Try it on a real domain

Free, no account, public DNS only.

Go deeper

Last reviewed