Read when: changing DNS ownership, managed-record filtering, or DNS reconciliation semantics tied to DNS record ownership.
Defines: the DNS instantiation of the ownership model, including DNS attribute-based ownership via MANAGED_RECORDS_COMMENT_REGEX and RECORD_COMMENT, DNS-side admissibility, and ownership-aware DNS reconciliation.
Does not define: exact Cloudflare request payload shapes or local warning text.
MANAGED_RECORDS_COMMENT_REGEX lets one updater instance decide which DNS records it recognizes as its own.
Safely isolate DNS record ownership when multiple updater instances may touch overlapping DNS names. This note defines the DNS attribute-based ownership layer inside the ownership model.
RECORD_COMMENTis the fallback comment this instance uses when reconciling DNS records.MANAGED_RECORDS_COMMENT_REGEXis the attribute-based selector used to decide which DNS records are managed by this instance.- These settings are intentionally separate: one controls what this instance writes, and the other controls what it may mutate.
Within the ownership model:
- resource ownership is defined elsewhere
- IP-family ownership is defined in Ownership Model
- this note defines DNS attribute-based ownership and DNS-side admissibility
- reconciliation semantics are defined in Reconciliation Algorithm
The selector uses Go regexp RE2 syntax with MatchString semantics. It is not an implicit full-match pattern.
The empty default matches all comments, preserving pre-selector behavior. Ownership isolation is opt-in.
MANAGED_RECORDS_COMMENT_REGEXis compiled during config building and stored in the handle-facing runtime config.- After successful config building, the compiled regex is always non-nil, including the default empty template.
RECORD_COMMENTmust matchMANAGED_RECORDS_COMMENT_REGEX.
The last rule prevents self-orphaning.
Managed-record filtering happens immediately after listing DNS records from Cloudflare.
Only matched records participate in:
- IP parsing
- target satisfaction checks
- stale-record detection
- metadata derivation for new creates
DELETE_ON_STOP
Unmatched records are invisible to DNS mutation logic, so the updater may create a new managed record even if an unmanaged record already has the desired IP address.
DNS admissibility is defined by whether raw data can be validly derived into DNS targets for the in-scope DNS resources.
IPv4 DNS derivation forgets prefix length, so provider-valid IPv4 raw entries are DNS-admissible.
For IPv6, let r be a raw entry, d an in-scope DNS domain, and h a member of the effective hostid6 set for d. The raw IPv6 set is DNS-admissible exactly when every r is compatible with every effective h for every in-scope d.
Each derivation combines the observed prefix with host bits: the result keeps the network bits inside the observed prefix and replaces everything below it with the derivation's host bits, so any bit that neither the prefix nor the host bits set becomes zero. Compatibility is the static rule that keeps this combination well-defined:
preserveis compatible with every valid raw IPv6 entry and produces its observed address- an IPv6 literal is compatible when its non-zero bits do not overlap the observed prefix
mac(...)is compatible only when the observed prefix is exactly/64, and produces a Modified EUI-64 host ID from the configured 48-bit MAC address (RFC 4291, Appendix A, "Creating Modified EUI-64 Format Interface Identifiers"). A Modified EUI-64 interface identifier is a 64-bit value (RFC 4291, 搂2.5.1, "Interface Identifiers") defined only within a/64: a longer prefix leaves fewer than 64 host bits, and a shorter prefix leaves the subnet bits between the prefix and/64undefined by the MAC. The two failures are reported distinctly, because only the short-prefix case has a literal workaround: the MAC determines the interface identifier, but the operator must supply the subnet bits, which the tool cannot infer and should not silently assume.
For each domain, the desired DNS target set is the union of targets produced by the cross-product of its effective hostid6 set and the raw IPv6 set. Equal target addresses collapse under set semantics.
Any incompatibility makes the raw IPv6 set inadmissible for the family-wide contract. The resulting whole-family consequence is defined in Lifecycle Model.
DNS instantiates the reconciliation algorithm with these resource-specific rules:
- the resource unit is
(domain, IP family) - a managed record satisfies a desired target when its record IP equals that desired target IP
- the common operator-facing case is one desired IP and one managed record per domain
- matching duplicate managed records may remain
- duplicate multiplicity is tolerated residue, not desired state
- already-satisfying record metadata is soft unless another DNS-specific contract overrides it
When DNS reconciliation needs create metadata, it resolves that metadata per (domain, record type) unit from recyclable managed records only.
For scalar DNS metadata fields (TTL, PROXIED, RECORD_COMMENT), DNS uses the shared reconciliation rule from Reconciliation Algorithm.
TAGS uses the same rule per individual tag instead of per whole field:
- tag names are compared case-insensitively
- tag values are compared case-sensitively
- a tag is inherited only if every recyclable managed record has that canonical tag
- otherwise the fallback for that tag is used
With today's exposed config surface, the fallback tag set is empty, so DNS tag reconciliation reduces to the canonical intersection/common subset of recyclable managed records.
DNS refines the shared residual-risk policy with these tiers:
R0: missing desired target satisfactionR1: stale managed records still pointing to non-desired targetsR2a: proxied mismatch (expectedPROXIED=false, actualtrue)R2b: proxied mismatch (expectedPROXIED=true, actualfalse)R2c: TTL driftR2d: comment/tags driftR3: duplicate or hygiene residue
DNS uses the shared reconciliation-intent semantics from Lifecycle Model.
For DNS, the resource eligible for deletion is an individual managed record, not a broader DNS root. DNS shutdown may therefore delete only managed records.
setter and api.Handle use the following DNS mutation contract:
UpdateRecordreconciles one managed record to desired state for both:- content/IP
- metadata in scope (
TTL,PROXIED,RECORD_COMMENT,TAGS)
- desired-state mutation source is
desiredParams
This contract is intentionally explicit. Any future contract change here should update interface comments, implementation comments, and API write tests together.
Record-list caches store already-filtered managed records.
This requires one handle and its bound setter to use one stable managed-record filter for their lifetime. The current cache key does not include filter identity.
- The design prefers strict ownership isolation over reusing foreign records. This may leave parallel records with the same IP address, but it avoids mutating another deployment's records.
- Regex selectors allow flexible grouping, but exact ownership boundaries require explicit anchors such as
^managed-by-a$. - The selector name is intentionally distinct from
RECORD_COMMENTto reduce operator confusion.
This design applies only to DNS record ownership based on DNS record comments.
- If one process ever needs multiple ownership scopes for the same domain and IP family, the cache design must change so filter identity becomes part of the caching model.
- Future configuration and UI work should continue to keep ownership selection separate from the parameters written to DNS records.
- If future DNS-side derivation adds another target-construction policy, this note should define the resulting DNS admissibility constraints rather than pushing them into generic lifecycle text.
- If future work changes the broader ownership model, this note should continue to own only the DNS attribute-based ownership layer instead of absorbing unrelated ownership rules.