| Internet-Draft | Domain Affiliation Confirmation | October 2026 |
| Manelidis | Expires 25 April 2027 | [Page] |
Security systems assess domain names one at a time. A new domain of an established organization therefore starts with no reputation, and a legitimate domain that resembles another organization's name can be reported as an impersonation. This document defines Domain Affiliation Confirmation (DAC), by which the operator of a parent domain confirms that a child domain is operated by it or under its authority. The child publishes a DNS record naming the parent and a random token; the parent confirms that token, in the DNS or over HTTPS, by naming the child. Verification takes at most three DNS queries. The parent publishes no list of its domains, and an affiliation is ended by deleting one record. The document also states what a confirmation means to relying parties such as takedown services and reputation systems.¶
This note is to be removed before publishing as an RFC.¶
Discussion of this document takes place on the Domain Name System Operations (DNSOP) Working Group mailing list (dnsop@ietf.org). A reference implementation with test vectors accompanies this draft (Section 14).¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 25 April 2027.¶
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
Mail filters, browser warning systems, secure web gateways, and brand-protection services evaluate domain names individually. Two consequences follow for organizations that operate more than one domain.¶
Both problems would be reduced if an evaluating system could ask a precise question and get an answer from the party able to give it: "Does the operator of this established domain confirm that it operates this other domain?" No deployed mechanism answers it. Registration data [RFC9083] is frequently redacted and was not designed to express relationships between domains, and certificates bind keys to names, not names to each other.¶
This document defines Domain Affiliation Confirmation (DAC). The domain to be affiliated (the child) publishes a DNS record that names its parent domain and carries a random token. The parent confirms the affiliation by publishing, under a name derived from that token, a record that names the child. A verifier reads the child's record, reads the parent's confirmation, and checks that the confirmation names the child it started from.¶
The document also states what a confirmation means (Section 8): the parent's operator indicates that it operates the child or authorizes its operation, and that reports of abuse concerning the child may be directed to it. A relationship that relying parties are not meant to act on would leave the problems above unsolved (Appendix A.9).¶
Only the parent can create an affiliation. A claim the parent has not confirmed has no effect, and a confirmation for one child cannot be reused for another.¶
The parent publishes nothing from which its affiliated domains can be listed. Each child's claim is public, so affiliated domains can be found by examining domains individually, as with any public DNS data.¶
An affiliation is ended by deleting one record at the parent, without any change at the child. The change takes effect within cache and DNSSEC signature lifetimes (Section 11.6).¶
No new key material. The protocol relies on the parent's existing control of its DNS zone or, optionally, its web origin.¶
Bounded cost. Verification takes at most three TXT queries, plus one HTTPS request and its address resolution when the parent uses that channel, with no recursion and no searching.¶
Deployable with existing tools. Records are TXT records at underscored names [RFC8552].¶
The verification procedure does not consult a list of public suffixes. Every confirmation requires a record that only the parent's operator can publish.¶
DAC does not establish the identity, legitimacy, or licensing of the parent's operator. It conveys a statement by whoever operates the parent domain; whether that party deserves trust is for each relying party to decide (Section 8).¶
DAC does not express relationships between independent organizations, such as partnerships or service providers (Appendix A.5).¶
DAC does not define where administrative boundaries in the DNS lie. Relying parties may still need such information to decide which names to evaluate.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
DNS terms are used as defined in [RFC9499]. This document also uses the following terms.¶
In examples, "bank.example" is the parent domain and "embank.example" is the child domain [RFC2606]. The token used in examples, "mfrggzdfmztwq2lknnwg23tpobyxe43u", is illustrative and not random.¶
An affiliation consists of three records. The claim is published by the child; the marker and the confirmation are published by the parent.¶
Child: embank.example Parent: bank.example
+-------------------------------+ +--------------------------------+
| _affiliation.embank.example. | | _affiliation.bank.example. |
| TXT "v=DAC1; | | TXT "v=DAC1" (marker) |
| p=bank.example; | | |
| t=<token>" (claim) | | <token>._affiliation. |
+-------------------------------+ | bank.example. |
| TXT "v=DAC1; |
| d=embank.example" |
| (confirmation) |
+--------------------------------+
Verifier:
1. TXT _affiliation.embank.example -> p=bank.example, t=<token>
2. TXT _affiliation.bank.example -> marker, channel "dns"
3. TXT <token>._affiliation.bank.example
-> d=embank.example
4. d= equals the child domain -> result "confirmed"
A claim copied to another domain fails because the confirmation names the original child. Confirmation names cannot be found without the corresponding claims, because they contain the token. The marker prevents a wildcard elsewhere in the parent's zone from answering for confirmation names (Section 11.7) and tells the verifier which channel the parent uses.¶
The three records share one tag-list syntax: a version tag followed by zero or more tags, separated by semicolons. The ABNF [RFC5234] below uses case-sensitive strings [RFC7405]; WSP, ALPHA, and DIGIT are the core rules of [RFC5234].¶
<CODE BEGINS> file "dac.abnf" record = *WSP v-tag *( *WSP ";" *WSP tag ) [ *WSP ";" ] *WSP v-tag = %s"v" *WSP "=" *WSP %s"DAC1" tag = tag-name *WSP "=" *WSP tag-value tag-name = ALPHA *( ALPHA / DIGIT / "_" ) tag-value = 1*tval-char tval-char = %x21-3A / %x3C-7E ; VCHAR except ";" p-value = domain ; claim: parent domain t-value = 26*52b32-char ; claim: token c-value = 1*tval-char ; marker: channel m-value = 1*tval-char ; marker: mode r-value = 1*tval-char ; marker: abuse contact URI d-value = domain ; confirmation: child domain s-value = 1*tval-char ; confirmation: scope x-value = 4DIGIT "-" 2DIGIT "-" 2DIGIT ; confirmation: expiry f-value = 1*tval-char ; marker: report URI domain = label *( "." label ) label = ld-char [ *61ldh-char ld-char ] ld-char = %x61-7A / DIGIT ; lowercase letters and digits ldh-char = ld-char / "-" b32-char = %x61-7A / %x32-37 ; RFC 4648 base32, lowercase <CODE ENDS>¶
A TXT record is a DAC record if its text, after any leading spaces or tabs, begins with "v", optional whitespace, "=", optional whitespace, and "DAC1", followed by whitespace, ";", or the end of the text. Other TXT records are ignored, so DAC records can share a name with other TXT records. A DAC record is well-formed if it matches the "record" rule, contains no tag name more than once, and the value of every tag defined in this document matches the rule given for it, with an "x" value that is also a valid calendar date. A DAC record that is not well-formed is malformed.¶
Tag names are case-sensitive. Verifiers MUST ignore tags they do not recognize. New tags are registered as described in Section 13.3.1; adding a tag does not change the version.¶
A TXT record consisting of several character-strings is interpreted as their concatenation without separators, as in Section 3.3 of [RFC7208]. Publishers SHOULD keep each record within a single character-string of at most 255 octets.¶
Domain names in records are in canonical form: A-labels [RFC5890] in lowercase, without a trailing dot, at most 253 octets long, with a last label that is not entirely numeric. A label with hyphens in both the third and fourth positions MUST be a valid A-label. The "domain" rule expresses the character-level constraints; a name violating the others is malformed. Verifiers do not repair names.¶
A child domain declares its parent with one TXT record at the name formed by prepending the label "_affiliation" to the child domain:¶
_affiliation.embank.example. 3600 IN TXT
"v=DAC1; p=bank.example; t=mfrggzdfmztwq2lknnwg23tpobyxe43u"
¶
A child domain has at most one parent and MUST NOT publish more than one DAC record at its "_affiliation" name; a domain that is also a parent includes its marker tags in the same record (Section 4.4). The parent domain MUST NOT be the child domain itself. The claim name MAY be a CNAME, for example when the child's records are managed by the parent's operator.¶
A claim is published at, and an affiliation is verified for, one domain name. Organizations typically publish claims at their registrable domains, such as "embank.example", not at every host name.¶
A relying party assessing a name below such a domain, for example "marketing.embank.example", determines the domain it regards as responsible for that name, as it already does when attributing reputation, and verifies that domain. Claims are not published at names like "marketing.embank.example" for this purpose.¶
By default, a confirmation states nothing about names below the child domain, and relying parties apply their usual practice to them. A parent that operates, or authorizes the operation of, every name below the child states this by including the "s" tag with the value "subtree" in the confirmation (Section 4.5). The confirmation then also covers every name below the child. A parent MUST NOT include it when names below the child are operated by parties not acting under the parent's authority, such as customers of a hosting or platform service (Section 11.12).¶
If a name below a child with a subtree confirmation publishes its own claim, that claim governs the name and the names below it.¶
A parent domain that confirms affiliations publishes exactly one DAC record at the name formed by prepending "_affiliation" to the parent domain. A domain that is both a child and a parent publishes a single record there containing both the claim tags and the marker tags.¶
_affiliation.bank.example. 3600 IN TXT
"v=DAC1; r=mailto:abuse@bank.example"
¶
The marker MUST be a TXT record owned by the "_affiliation" name itself, not data reached through a CNAME or DNAME record. The marker makes "_affiliation" an existing node in the parent zone, so that a wildcard higher in the zone cannot answer for names below it (Section 11.7). The "_affiliation" name MAY be delegated as a separate zone, in which case that zone's operator publishes the marker and confirmations. A DNAME record [RFC6672] at that name redirects the queries for confirmations to another zone and has the same effect as delegating them.¶
For each confirmed child, a parent using the DNS channel publishes one TXT record at the name formed by prepending the child's token to the parent's "_affiliation" name:¶
mfrggzdfmztwq2lknnwg23tpobyxe43u._affiliation.bank.example.
3600 IN TXT "v=DAC1; d=embank.example"
¶
An expiry date suits domains used for a limited time, such as campaign sites, and also limits the consequences of a confirmation that is not removed when its domain changes hands (Section 11.4), for example when it is set to the domain's registration expiry date and updated on renewal. A parent extends a confirmation by replacing the record with one carrying a later date. Registration expiry dates normally move forward when domains renew automatically, so a parent tying "x" to them updates the confirmation at each renewal.¶
A confirmation name MUST NOT hold more than one DAC record. It MAY be a CNAME, for example to a name hosted by a DNS provider. The parent MUST NOT publish wildcard records at or below its "_affiliation" name.¶
A token links one claim to one confirmation. It makes confirmation names unpredictable, so that a parent's confirmations cannot be found by guessing names, whether by online queries or, for DNSSEC-signed zones using NSEC3, by offline guessing of hashed names. A token is not a secret: it is published in the claim and appears in queries. The protocol's resistance to forged affiliations does not depend on tokens being unknown (Section 11.3).¶
A token MUST contain at least 128 bits, and SHOULD contain 160 bits, from a cryptographically secure random source [RFC4086]. At 128 bits, guessing a confirmation name is infeasible and collisions between tokens are negligible.¶
A token is encoded in base32 (Section 6 of [RFC4648]) with lowercase letters and without padding, giving 26 to 52 characters; a 160-bit token is 32 characters, well within the 63-octet limit on a DNS label [RFC1035]. Case-sensitive encodings such as base64 cannot be used, because DNS name matching ignores case [RFC4343] and some resolvers alter the case of query names.¶
Tokens are opaque; verifiers do not decode them. A parent MUST use a different token for each child and SHOULD use a new token when re-establishing an affiliation that was previously ended.¶
Publishing the confirmation first lets the affiliation verify as soon as the claim is visible.¶
The parent operator ends an affiliation by removing the confirmation; no change at the child is needed. A parent operator MUST remove the confirmation for a child domain that it no longer operates or authorizes, including when the child domain is transferred, sold, or allowed to expire, except as described in Section 5.3. A claim left in the child's zone, or copied there by a later registrant, has no effect once the confirmation is gone.¶
A parent that withdraws from the protocol removes its marker, which ends all of its affiliations.¶
When a child domain moves from one parent to another, for example after an acquisition, the operators proceed in this order so that the child remains confirmed throughout:¶
If the child domain leaves both organizations, for example because it is sold, the parent removes its confirmation no later than the transfer (Section 5.2), and the child's new operator replaces or removes the claim.¶
A parent domain can itself be the child domain of another affiliation, for example when a subsidiary's primary domain is affiliated with its group's primary domain. Each affiliation is confirmed separately and means only what Section 8 states about that pair: a confirmation of the parent by its own parent says nothing about the parent's children. Verifiers MAY repeat the procedure with the parent domain as the child domain. A verifier that does so MUST NOT follow more than two levels beyond the first parent and MUST stop if a domain repeats.¶
The input is a child domain in canonical form (Section 4.1). Verifiers that accept names containing non-ASCII characters convert them to A-labels as specified in [RFC5891]; the processing of [UTS46] with non-transitional processing is a common way of doing so. A name that cannot be converted yields "permerror".¶
The output is a result (Section 6.3) and, when available, the parent domain, the channel, whether the result is authenticated (Section 6.5), whether the confirmation covers names below the child domain (Section 4.3), the parent's mode and abuse contact, and the time for which the result may be reused (Section 6.6).¶
Verifiers MUST use a DNS interface that exposes the answer section of responses, so that CNAME [RFC1034] and DNAME [RFC6672] records in an answer can be detected. In the steps below, "no record" means that the query returned NXDOMAIN, or NOERROR with no DAC record; this includes a name that exists only as an empty non-terminal. NXDOMAIN and NOERROR without data are treated alike because servers differ in which they return. Other DNS outcomes are handled as described in Section 6.4.¶
Query TXT at "_affiliation." followed by the child domain.¶
Query TXT at "_affiliation." followed by the parent domain. Any "p" and "t" tags in the marker belong to the parent's own claim and are ignored here. Apply the following checks in order.¶
If the channel is "dns", query TXT at the token, followed by "._affiliation.", followed by the parent domain.¶
If the channel is "https", obtain the confirmation as described in Section 7.¶
Examine the confirmation's "d" tag.¶
Domain names are compared as octet strings in canonical form. The procedure does not query any other names, follow references found in record content, or consult a list of public suffixes.¶
Only "confirmed" establishes an affiliation.¶
Any response code other than NOERROR and NXDOMAIN, a timeout, or a truncated response that cannot be retried over TCP yields "temperror". A response that fails DNSSEC validation ("bogus" [RFC4035]) also yields "temperror" and MUST NOT contribute to a "confirmed" result. Verifiers MUST support DNS over TCP.¶
For the DNS channel, a result is authenticated if all DNS answers used were validated as secure [RFC4035], either by the verifier or by a validating resolver reached over a trusted path.¶
For the HTTPS channel, the Web PKI authenticates the confirmation, but the decision to use that channel was taken from the marker. The result is authenticated only if the claim and the marker were validated as secure. Otherwise, a forged marker could select the HTTPS channel for a parent that does not use it (Section 11.5).¶
Verifiers report whether a result is authenticated. The abuse contact is taken from the marker and is authenticated only when the marker is.¶
A verifier MAY reuse a result for the smallest of: the TTLs [RFC2181] of the DNS answers used, where the TTL of a negative answer is determined as in [RFC2308]; the freshness lifetime of the HTTPS response (Section 7.2); the time remaining until a confirmation's expiry; and 86400 seconds.¶
After "temperror", verifiers retry with increasing intervals and SHOULD NOT retry more often than once a minute. Resolvers that serve stale data [RFC8767] can extend the time for which an ended affiliation still verifies.¶
A parent whose marker contains "c=https" publishes confirmations as HTTPS resources instead of DNS records, which suits operators that manage such data through a web application rather than their DNS provider. The claim and the marker remain DNS records; selecting this channel is done in the parent's DNS zone.¶
The confirmation for a token is the resource identified by:¶
https://<parent domain>/.well-known/affiliation/<token>¶
A confirmed token is served with status code 200 and media type "text/plain". The content is one DAC confirmation record, with the same syntax as in the DNS, optionally followed by a single CRLF or LF:¶
Request:
GET https://bank.example/.well-known/affiliation/
mfrggzdfmztwq2lknnwg23tpobyxe43u
Accept: text/plain
Response:
200 OK
Content-Type: text/plain
Cache-Control: max-age=3600
v=DAC1; d=embank.example
¶
A token that is not confirmed is answered with 404 (Not Found) or 410 (Gone).¶
A verifier fetching a confirmation:¶
Responses are handled as follows:¶
The freshness lifetime of a response is zero if it carries Cache-Control no-store or no-cache, is otherwise taken from a max-age directive if present, and is otherwise 3600 seconds.¶
This section states what a "confirmed" result means, so that relying parties can use it consistently. It does not prescribe relying-party policy.¶
A "confirmed" result means that, at the time of verification, the parent operator had published a statement that:¶
With "s=subtree", both statements also apply to every name below the child domain.¶
The second element distinguishes an affiliation from a mere association: a parent that confirms a child is the expected recipient of complaints about it. The statement is made by whoever controls the parent domain's DNS zone, or its HTTPS origin when that channel is used.¶
A confirmation says nothing about the trustworthiness, identity, or licensing of the parent operator, or about the content served by the child. A confirmation from a parent domain registered yesterday is as valid as one from a long-established organization. A confirmation therefore conveys at most the standing that a relying party already attributes to the parent domain.¶
Takedown decisions. When a domain resembling a protected name is confirmed as affiliated with a parent that the relying party already regards as legitimate, the resemblance is unlikely to be an impersonation of the parent's own name, and a conflict with another organization's name is a dispute between organizations. Relying parties can direct such reports to the parent's abuse contact or to the dispute processes for name conflicts. A confirmation alone does not justify delaying action on abuse that has been observed (Section 11.9).¶
Reputation. A relying party may extend to a confirmed child some or all of the reputation it attributes to the parent. Attributing more standing to the child than to the parent is inconsistent with the meaning above, and taking abuse observed on a confirmed child into account when assessing the parent gives parent operators a reason to confirm only domains they control.¶
Testing mode. Confirmations from a parent in "test" mode are intended for reporting to the parent, not for decisions.¶
Other results. "none", "not-confirmed", "temperror", and "permerror" are not, by themselves, evidence that a domain is malicious. Most domains publish no claim. A claim that a well-known parent does not confirm may be an attempt to borrow its standing, but it may also result from misconfiguration or from records an attacker caused to appear in a victim's zone (Section 11.10).¶
Assurance. Relying parties taking consequential actions can consider whether a result was authenticated (Section 6.5) and, for unauthenticated results, the measures in Section 11.5.¶
A parent can ask verifiers to report claims that name it but are not confirmed, for example by a domain that copied a claim or fabricated one. Such reports let the parent learn about attempts to borrow its standing, and about confirmations that have expired or been removed by mistake. Sending reports is optional for verifiers.¶
A verifier MAY send a report when it obtained the parent's marker, the marker carries an "f" tag, and the result is "not-confirmed" or "permerror" for a reason arising after step 2 of Section 6.2, that is, a missing, mismatched, expired, or malformed confirmation, or a confirmation that could not be obtained over HTTPS. Reports are not sent for "temperror" or for an unsupported channel. Reports are particularly useful while a parent is in "test" mode, and verifiers may send them then.¶
A verifier MUST NOT send a report to an "f" URI that does not meet the conditions in Section 4.4; in particular, reports go only to the parent domain or names below it, which prevents a marker from directing reports at third parties. A parent that wants reports processed by a provider points a name below its domain, or its mail routing, at that provider. Because an attacker can create any number of child domains, a verifier MUST send at most one message per report destination in 24 hours, combining reports into it, and SHOULD limit the number of reports per message, for example to 1000.¶
A report is a JSON [RFC8259] array of objects, each with the following members:¶
[
{
"version": "DAC1",
"observed": "2026-10-22T09:30:00Z",
"child": "embank-login.example",
"parent": "bank.example",
"result": "not-confirmed",
"reason": "different-child",
"reporter": "filter.example"
}
]
¶
Receivers ignore members and reason values they do not recognize.¶
For an "https" URI, the verifier sends the report in an HTTP POST request with media type "application/json", subject to the same restrictions as in Section 7.2, except that the content may be up to 65536 octets. For a "mailto" URI, the verifier sends an email message with the subject "DAC report for" followed by the parent domain, whose body, or one of whose body parts, is the report with media type "application/json". Verifiers SHOULD send report email from a domain that authenticates its mail, so that receivers can filter it. Failure to deliver a report is not retried more than once.¶
Reports are unauthenticated assertions by whoever sent them. A parent treats a report as a prompt to verify the named child itself, not as evidence, and rate-limits what it accepts. Reports are not a substitute for the monitoring described in Section 10.7.¶
Unless an expiry date is used, the records contain no dates, so creating an affiliation is a one-time operation with nothing to renew. An organization with many domains maintains the records with a tool that generates tokens and writes records through its DNS providers' interfaces.¶
Affiliations go stale when domains change hands. The most reliable control is to derive confirmations from the organization's registrar accounts or domain inventory, so that a confirmation is removed when its domain leaves the inventory. Registrars and DNS providers can offer this as a service.¶
The time for an ended affiliation to stop verifying is normally bounded by the TTL of the confirmation (or the freshness lifetime of the HTTPS confirmation) and by the 86400-second limit in Section 6.6; serve-stale resolvers and replay can extend it (Section 6.6, Section 11.6). A TTL of 3600 seconds is a reasonable default. For signed zones, the validity period of signatures over confirmation records also bounds how long a deleted confirmation can be replayed (Section 11.6); parents wanting prompt revocation keep it short for names below "_affiliation". The negative-caching TTL of the parent zone affects how soon a new confirmation becomes visible.¶
A parent can publish its marker with "m=test", create confirmations, and check results before changing the marker to "enforce". Relying parties can likewise verify in a reporting-only mode before acting on results.¶
The DNS channel needs only DNS records and benefits from DNSSEC. The HTTPS channel suits parents that prefer to manage confirmations in a web application; it requires that the parent domain itself serve HTTPS on port 443 without redirecting, which many organizations' apex domains do not do by default. A parent that changes channel publishes confirmations in the new channel before changing the marker and removes the old ones after the marker's TTL has passed.¶
Confirmations may be hosted by a DNS provider through CNAME records or by delegating the "_affiliation" name; the provider can then create and remove confirmations (Section 11.7).¶
Verification costs at most three TXT queries. Markers are shared by all children of a parent and are cached accordingly. Most domains publish no claim, and for them the cost is one query. A parent using the HTTPS channel receives a request for each verification of one of its children that is not answered from a cache; such parents SHOULD serve confirmations from infrastructure able to handle that load and SHOULD set a Cache-Control max-age.¶
Parent operators can check newly observed domains, for example from Certificate Transparency logs, for claims naming their domain. A claim carrying a token the parent did not issue indicates a domain attempting to borrow its standing; a claim for a domain no longer in the parent's inventory indicates a confirmation that should already have been removed.¶
The attacker wants a domain it controls to verify as affiliated with a parent it does not control, to prevent a legitimate affiliation from verifying, to use an affiliation to delay action against abuse, or to learn a parent's affiliated domains. The attacker can register domains, publish records in zones it controls, place content on web hosting it has access to, observe public DNS data, and in some cases forge or replay DNS responses on the path to a verifier. Compromise of the parent's DNS zone or web origin is discussed in Section 11.8.¶
Anyone can publish a claim naming any parent. The claim is confirmed only if a record exists under the parent's "_affiliation" node, or at the parent's HTTPS origin when the parent has selected that channel, that names the claiming domain. Absent forged responses (Section 11.5), only the parent operator can create such a record.¶
Claims and tokens are public. An attacker that copies a legitimate claim to its own domain obtains a confirmation naming the legitimate child, and the result is "not-confirmed". The binding between token and child is in the parent's confirmation, which the attacker cannot alter.¶
If a parent fails to remove the confirmation of a child domain that has changed hands, the new registrant of the child inherits the affiliation. This is the most likely failure in practice. The requirement in Section 5.2, inventory-driven automation (Section 10.1), and monitoring (Section 10.7) address it. Relying parties with access to registration data [RFC9083] [RFC9224] can treat a confirmation with caution when the child's registration changed after the confirmation was first observed.¶
Likewise, if a parent domain expires and is registered by someone else, the new registrant can confirm arbitrary domains. Relying parties that attribute standing to a parent based on its history can reassess a parent whose registration has changed rather than carrying standing across the change.¶
An attacker able to forge DNS responses to a verifier, for example through cache poisoning [RFC5452] or by hijacking routes to authoritative servers, can produce any result for unsigned zones. For the DNS channel, the forgery has to cover the parent's records; forging the claim alone cannot produce "confirmed".¶
Forging the marker can switch the channel in either direction. In particular, an attacker that can forge the marker of an unsigned parent zone and can place a file at a path under the parent's HTTPS origin, for example through shared hosting or an upload feature, can obtain "confirmed" for any domain. Such a result is not authenticated (Section 6.5), which is why the Web PKI alone does not make an HTTPS result authenticated.¶
Results authenticated with DNSSEC are not affected by forged responses. Relying parties taking consequential actions on unauthenticated results can perform the queries from several network locations and require the answers to agree, as certification authorities are required to do for domain validation [CABF-BR].¶
An attacker on the path to a verifier can replay a confirmation that the parent has deleted. For unsigned zones, any response can be forged anyway. For signed zones, a replayed RRset validates until its signatures expire, which can be weeks. Parents that want deletion to take effect promptly against such attackers use short signature validity periods for names below "_affiliation" (Section 10.2). A confirmation with an expiry date cannot be replayed to effect beyond that date.¶
If a parent zone contained a wildcard such as "*.bank.example" and no "_affiliation" node existed, queries for confirmation names would be answered from the wildcard [RFC4592]. If that wildcard were a CNAME into a zone operated by a third party, such as a hosting platform, a tenant of that platform might be able to publish a TXT record there confirming a domain of its choosing. The marker prevents this: since its owner name exists, a wildcard above it cannot match names below it, and verifiers reject a marker reached through a CNAME or DNAME record. An empty non-terminal at "_affiliation" also blocks the wildcard but yields "not-confirmed" because there is no marker.¶
Confirmation names may be CNAMEs, and the "_affiliation" name may be delegated or carry a DNAME record. The operator of the target or delegated zone can then create and remove confirmations. Parents delegate in this way only to parties they would trust to publish confirmations on their behalf.¶
An attacker controlling the parent's DNS zone can confirm any domain; it can also redirect the parent domain itself, so DAC does not add to the consequences of that compromise. An attacker controlling only the parent's web origin can confirm domains through the HTTPS channel only if the parent's marker selects that channel or the marker is forged (Section 11.5). Verifiers report the channel used, and relying parties concerned about web compromise can give less weight to confirmations obtained over HTTPS. A parent can detect confirmations it did not create by comparing them with its inventory, and recovers by deleting them.¶
An attacker that controls a parent domain to which relying parties attribute standing, for example an expired domain re-registered for its history or a compromised DNS account, can confirm look-alike domains used for phishing. Takedown requests may then be directed to an abuse contact that the attacker controls. Relying parties should not let a confirmation alone delay action against abuse they have observed, and can reassess parents whose registration has changed (Section 11.4) or whose set of confirmed domains grows unexpectedly.¶
An attacker able to place a TXT record at "_affiliation" under a victim's domain, for example through a dangling or wildcard CNAME in the victim's zone pointing to a platform the attacker uses, controls the victim's claim. It can make the victim appear to claim a parent that does not confirm it, which is one reason why results other than "confirmed" are not by themselves evidence of malice (Section 8.3). It can also name a parent the attacker operates and confirm the claim there, making the victim appear affiliated with the attacker and directing abuse reports about the victim to the attacker's contact. Children therefore MUST NOT publish wildcards covering their "_affiliation" name (Section 10.6) and SHOULD make their claim name a CNAME only to names they or their parent operator control.¶
Verification is bounded at three TXT queries and one HTTPS request with its address resolution, with no recursion and no references in record content, avoiding the lookup-limit problems experienced with [RFC7208]; following several levels (Section 5.4) is bounded at nine queries.¶
An attacker can publish claims with random tokens naming a participating parent, so that each verification causes a query for a new name at the parent's authoritative servers, or a request to its HTTPS origin. Aggressive use of DNSSEC-validated caches [RFC8198] can absorb such queries only where denial of existence covers ranges of names; the configurations recommended in Section 10.6 to prevent zone walking, and unsigned zones, give up that protection, so parents using them depend on verifiers limiting their query rates. Verifiers that accept names to verify from untrusted sources SHOULD rate-limit the queries and requests they send for each parent domain.¶
A subtree confirmation extends the parent's statement to names that the parent does not list individually. If anyone other than the parent's organization can create names below the child, for example because the child offers subdomains to customers or has a delegation or wildcard record pointing to a third party, those parties' names would appear affiliated with the parent. A subtree confirmation is also not evidence about the content of any particular name below the child; abuse observed there is handled as in Section 11.9. This is why parents include "s=subtree" only for children whose entire namespace they control (Section 4.3). A dangling record below the child, such as a CNAME to a deprovisioned cloud resource, has the same effect if taken over, so parents using subtree confirmations keep the child's zone free of such records.¶
An attacker can publish many claims naming a parent so that verifiers send reports to it; the per-pair limit in Section 9.1 and parent-side rate limiting bound the effect. Restricting report destinations to the parent's own names prevents markers from being used to direct reports at third parties. A forged marker can direct reports from a verifier to a name chosen by the attacker only within the same limits as other forged responses (Section 11.5). Reports are never evidence that a domain is malicious (Section 9.4).¶
Expiry dates are evaluated against the verifier's clock. An expiry date limits how long a forgotten confirmation remains effective but does not replace removing confirmations (Section 5.2).¶
An attacker can create its own parent and children with names resembling a legitimate organization's. Their affiliations verify, but convey only the standing of the attacker's parent (Section 8.2). User interfaces that display affiliations SHOULD display names in a form that makes confusable characters evident [UTS39].¶
A claim publicly discloses that the child declares an affiliation with the parent; this disclosure is the purpose of the claim. The parent publishes no list of its domains: a query at the parent reveals nothing about which children exist, and confirmations can be located only from the corresponding claims. A third party can still find affiliated domains by examining domains one by one, for example those listed in Certificate Transparency logs or zone files, so organizations should assume that every domain publishing a claim is discoverable. Domains that publish no claim, such as names held defensively or not yet launched, are not revealed.¶
This property depends on confirmation names not being enumerable. Zone transfers and DNSSEC denial of existence using NSEC records can reveal them; NSEC3 hashes of names containing random tokens of 128 bits or more cannot feasibly be reversed. Section 10.6 gives recommendations.¶
Queries reveal to resolver operators, and to passive DNS collections, which domains a verifier is evaluating. QNAME minimisation [RFC9156] reduces exposure of full names to servers higher in the DNS tree.¶
Failure reports disclose to the parent which of the verifier's evaluations involved claims naming the parent. Verifiers that do not wish to disclose this do not send reports, and the reports contain no information about why an evaluation took place.¶
The abuse contact in the marker is published, and parents SHOULD use role addresses. Publishers SHOULD NOT include personal data in records.¶
IANA is requested to add the following entry to the "Underscored and Globally Scoped DNS Node Names" registry [RFC8552]:¶
| RR Type | _NODE NAME | Reference |
|---|---|---|
| TXT | _affiliation | RFC XXXX |
IANA is requested to register the following in the "Well-Known URIs" registry [RFC8615]:¶
IANA is requested to create a registry group titled "Domain Affiliation Confirmation (DAC)" containing the three registries below. Registrations in all three are made under the Specification Required policy [RFC8126].¶
Each entry contains a channel name consisting of lowercase letters, digits, and hyphens, a short description, and a reference. The designated expert checks that the specification states how a confirmation is obtained, which outcomes map to which results, and the security properties of the channel. The initial contents are:¶
| Channel | Description | Reference |
|---|---|---|
| dns | TXT record under the parent's "_affiliation" name | RFC XXXX |
| https | Resource under "/.well-known/affiliation/" | RFC XXXX |
Each entry contains a reason value consisting of lowercase letters, digits, and hyphens, a short description, and a reference. The designated expert checks that the reason describes a distinct outcome of the procedure in Section 6.2 or of a channel. The initial contents are:¶
| Reason | Description | Reference |
|---|---|---|
| unconfirmed-token | No confirmation exists for the claim's token | RFC XXXX |
| different-child | The confirmation names another domain | RFC XXXX |
| expired | The confirmation's expiry date has passed | RFC XXXX |
| malformed-confirmation | The confirmation is malformed, not unique, or cannot be obtained | RFC XXXX |
This section is to be removed before publishing as an RFC.¶
This section records the status of known implementations of the protocol defined by this specification at the time of posting of this Internet-Draft, and is based on a proposal described in [RFC7942]. The description of implementations in this section is intended to assist the IETF in its decision processes in progressing drafts to RFCs. Please note that the listing of any individual implementation here does not imply endorsement by the IETF. Furthermore, no effort has been spent to verify the information presented here that was supplied by IETF contributors. This is not intended as, and must not be construed to be, a catalog of available implementations or their features. Readers are advised to note that other implementations may exist.¶
According to [RFC7942], "this will allow reviewers and working groups to assign due consideration to documents that have the benefit of running code, which may serve as evidence of valuable experimentation and feedback that have made the implemented protocols more mature. It is up to the individual working groups to use this information as they see fit".¶
[RFC5507] discourages overloading TXT records, mainly because unrelated uses collide at the same owner name. DAC uses a dedicated underscored name [RFC8552] and a version tag, which avoid that collision. A dedicated resource record type would remove the need for version-tag parsing, and authoritative servers handle unknown types [RFC3597]. TXT was chosen because DNS provisioning interfaces used by domain operators support it universally, and because experience with the dedicated SPF type [RFC6686], which [RFC7208] removed, showed the deployment cost of requiring one. The data model is simple enough that a dedicated type could be added later without changing it.¶
If the parent published a list of its domains, a single query at the parent would disclose the organization's entire portfolio at once, including domains not otherwise easy to find, which is a ready-made target list for attackers and can reveal products before launch. Every new domain would require editing a shared record, and the list would be bounded by record size or moved to a separate document fetched over HTTPS, adding a dependency. Hashing list entries does not help, because domain names are guessable. Per-child confirmations reveal nothing at the parent and are each located only from a claim.¶
A parent could publish a public key and sign each child's name, with the signature published by the child, so that the parent's zone would not change per child. Signatures remain valid after a child changes hands, however, so they need expiry dates, periodic re-signing of every child, revocation lists for urgent cases, and procedures for key rotation and compromise. DAC instead relies on the parent's existing control of its DNS zone or web origin, at the cost of one record per child at the parent.¶
Mechanisms that infer relationships between names depend on the Public Suffix List [PSL], a community-maintained list without a standard update model; [RFC9989] replaced its use in DMARC for this reason. DAC infers nothing: each confirmation requires a record that only the parent's operator can publish. A claim naming a public suffix as its parent is confirmed only if that suffix's operator confirms it. Relying parties may still use boundary information to decide which names to evaluate and how to attribute standing.¶
A mechanism in which organizations vouch for one another, with vouching that propagates, lets an attacker gain standing by compromising or paying any participant, dilutes the meaning of each step, and makes revocation depend on parties who may not know about the chain. DAC expresses only that one operator operates or authorizes a domain. The protocol cannot tell whether two levels belong to the same organization, which is why a confirmation says nothing about the confirmed domain's own children (Section 5.4).¶
In designs where every member of a group lists, and must be confirmed by, every other member, each new domain requires changes at every member, and a verifier must compute the group as the closure of pairwise links, at a cost that grows with the size of the group and has to be capped by arbitrary limits. DAC relates each child to exactly one parent, so adding a domain changes two records and verification has a fixed cost. Organizations with several levels are handled one affiliation at a time (Section 5.4).¶
Requiring DNSSEC or an HTTPS origin on both sides of every relationship would exclude most domains, including names held defensively that serve no content, and would make the mechanism unusable for most of the organizations it is meant to help. DAC instead reports whether each result is authenticated (Section 6.5), so that relying parties can require authentication where their decisions warrant it, and states precisely when an HTTPS confirmation counts as authenticated.¶
DAC needs no index, registry of relationships, or submission service. Every verifier obtains results directly from the domains concerned, so there is no additional party to operate, trust, or keep current, and no endpoint that can be used to make a service send traffic to arbitrary domains. Aggregators can be built on DAC, but nothing depends on them.¶
A mechanism that declares a relationship between domains, but whose specification forbids relying parties to draw conclusions from it, gives those parties nothing to act on, and the problems in Section 1.1 remain. DAC addresses a specific operational problem with intended consumers, takedown services and reputation systems, and states what a confirmation means (Section 8), including where reports of abuse are to be sent. It also bounds that meaning: a confirmation conveys no more standing than the parent already has (Section 8.2). The author invites operators of such services to comment on whether the stated meaning meets their needs.¶
The operator of bank.example launches embank.example and uses the DNS channel.¶
; In the bank.example zone (once):
_affiliation.bank.example. 3600 IN TXT
"v=DAC1; r=mailto:abuse@bank.example"
; In the bank.example zone (per child):
mfrggzdfmztwq2lknnwg23tpobyxe43u._affiliation.bank.example.
3600 IN TXT "v=DAC1; d=embank.example"
; In the embank.example zone:
_affiliation.embank.example. 3600 IN TXT
"v=DAC1; p=bank.example; t=mfrggzdfmztwq2lknnwg23tpobyxe43u"
¶
A verifier evaluating embank.example:¶
The result is "confirmed", reusable for 3600 seconds, and authenticated if all three answers validate as secure.¶
A mail filter assessing "statements.embank.example" verifies "embank.example", the domain it already treats as responsible for that name. Because the confirmation above has no "s" tag, the result states nothing about "statements.embank.example" itself. If bank.example operates every name under embank.example, it publishes the confirmation as "v=DAC1; d=embank.example; s=subtree", and the result covers "statements.embank.example" too.¶
An attacker registers embank-login.example and publishes a copy of the claim. Step 3 returns "d=embank.example", which differs from "embank-login.example", so the result is "not-confirmed". When the operator of bank.example sells embank.example, it deletes the confirmation; from then on, embank.example yields "not-confirmed" whatever its new operator publishes.¶
Each vector describes a change to the data of Appendix B and the expected result for the child domain "embank.example" (in vector 6, "embank-login.example"). T is the example token. The reference implementation (Section 14) runs these vectors as tests.¶
| # | Change from the example | Result |
|---|---|---|
| 1 | None | confirmed |
| 2 | No claim at the child | none |
| 3 | Child has only "v=spf1 -all" | none |
| 4 | Child has "v=DAC10; p=bank.example; t=T" | none |
| 5 | No marker at the parent | not-confirmed |
| 6 | Child is embank-login.example with a copy of the claim | not-confirmed |
| 7 | Claim carries a token the parent never issued | not-confirmed |
| 8 | Confirmation deleted | not-confirmed |
| 9 | Marker name is an empty non-terminal (NOERROR, no data) | not-confirmed |
| 10 | Marker answer contains a CNAME | permerror |
| 11 | Marker answer contains a CNAME and no TXT data | permerror |
| 12 | Claim answer contains a CNAME | confirmed |
| 13 | Confirmation answer contains a CNAME | confirmed |
| 14 | Two DAC records at the claim name | permerror |
| 15 | Two DAC records at the confirmation name | permerror |
| 16 | Confirmation repeats the "d" tag | permerror |
| 17 | Confirmation has no "d" tag | permerror |
| 18 | Token in uppercase | permerror |
| 19 | Token of 8 characters | permerror |
| 20 | Token of 26 characters, confirmed under that token | confirmed |
| 21 | Claim has "p=Bank.Example." | permerror |
| 22 | Claim has an additional tag "z=future" | confirmed |
| 23 | Claim repeats the "p" tag | permerror |
| 24 | Claim names embank.example as its parent | permerror |
| 25 | Parent is the single-label name "bank" | confirmed |
| 26 | Claim has "p=192.0.2.1" | permerror |
| 27 | Marker has "m=test" | confirmed, mode test |
| 28 | Marker has "m=other" | confirmed, mode test |
| 29 | Confirmation has "s=subtree" | confirmed, covers names below |
| 30 | Confirmation has "s=other" | confirmed, child only |
| 31 | Confirmation has "x=2099-12-31" | confirmed |
| 32 | Confirmation has "x=2020-01-01" | not-confirmed (report reason "expired") |
| 33 | Confirmation has "x=2027-02-30" | permerror |
| 34 | Confirmation has an "x" value equal to the current UTC date | confirmed |
| 35 | Confirmation has "s=subtree; x=2099-12-31" | confirmed, covers names below |
| 36 | Marker has "f=mailto:dac-reports@bank.example"; claim carries a token the parent never issued | not-confirmed; report with reason "unconfirmed-token" to that address |
| 37 | Marker has "f=mailto:reports@other.example"; claim carries a token the parent never issued | not-confirmed; no report |
| 38 | Marker has "f=mailto:r@bank.example?cc=x@other.example" | no reports (tag ignored) |
| 39 | Marker has "f=https://user@bank.example/r" or "f=https://bank.example:8443/r" | no reports (tag ignored) |
| 40 | Marker has "f=https://reports.bank.example/dac"; "c=https" and the resource returns 404 | not-confirmed; report reason "unconfirmed-token" |
| 41 | Confirmation repeats the "d" tag, marker has a valid "f" | permerror; report reason "malformed-confirmation" |
| 42 | Child record has only marker tags ("v=DAC1; r=mailto:abuse@embank.example") | none |
| 43 | Child record has claim and marker tags; its own children verify against it | confirmed (both) |
| 44 | Claim has "p=bank.example" but no "t" | permerror |
| 45 | Marker has "r=ftp://x.example" | confirmed, no contact |
| 46 | Marker has "c=future" or "c=HTTPS" | not-confirmed |
| 47 | SERVFAIL, timeout, or DNSSEC bogus at any of the three names | temperror |
| 48 | Confirmation name returns NOERROR without data | not-confirmed |
| 49 | "c=https"; 200, "text/plain", "v=DAC1; d=embank.example" | confirmed |
| 50 | "c=https"; 200, "text/plain; charset=utf-8", "v=DAC1; d=embank.example" | confirmed |
| 51 | "c=https"; 200, "text/plain", "Cache-Control: no-store", "v=DAC1; d=embank.example" | confirmed, not reusable |
| 52 | "c=https"; 404 | not-confirmed |
| 53 | "c=https"; 301 | permerror |
| 54 | "c=https"; 200 with "text/html" | permerror |
| 55 | "c=https"; content longer than 1024 octets | permerror |
| 56 | "c=https"; content is two records | permerror |
| 57 | "c=https"; malformed record | permerror |
| 58 | "c=https"; 503 or connection failure | temperror |
| 59 | "c=https"; parent has no globally reachable address | permerror |
| 60 | "c=https"; no resource, but a DNS confirmation exists | not-confirmed |
This document builds on the practices collected in [I-D.ietf-dnsop-domain-verification-techniques] and on operational experience with SPF, DMARC, MTA-STS, and ACME.¶