What's holding up the rollout of persistent domain validation for ACME?
Corey Bonnell
There is a new ACME validation method, dns-persist-01, being standardized at the IETF, and it has even been rolled out to Let’s Encrypt’s staging environment. However, an unresolved security concern is blocking progress on the standard and the roll-out in production for Let’s Encrypt.
dns-persist-01: DNS propagation delays begone!
While ACME has had a DNS-based validation method (dns-01) since the very beginning 1, it requires real-time updates to DNS for every validation attempt. This creates two issues:
- The ACME client needs to have an API key to update the zone, or communicate with a third party service (such as
acme-dns) to create the record. This means that credentials that can be used to update DNS zones are scattered across web servers. - DNS updates need to propagate and be widely visible on the Internet before the ACME server gives up on trying to validate the domain. The possibility of validation failures was only amplified when Multi-perspective issuance corroboration was made mandatory last year.
To resolve these issues, a new method named dns-persist-01 was proposed. Let’s Encrypt’s blog post covers the details of how the method works, so I won’t repeat them here. Suffice it to say that the new method avoids the two issues listed above as well as opens up the opportunity for the ACME server to automatically validate domains without the ACME server and client executing the challenge/response flow for every certificate request.
The original Let’s Encrypt plan
Let’s Encrypt announced their implementation in the blog post linked above in February. At that point, support already existed in Pebble (a “miniature” version of Let’s Encrypt’s production ACME server that is designed specifically for testing). Additionally, several implementers of ACME clients had integrated experimental support for dns-persist-01. With testing infrastructure in place and client support being prepared, it appeared that the published timeline in the February blog post calling for staging roll-out in late Q1 2026 and a production roll-out targeted for Q2 2026 would be met.
However, that schedule has since slipped. In early April, a discussion started on the IETF ACME working group’s mailing list concerning the relatively weak security guarantees of dns-persist-01 compared to the other ACME validation methods. The discussion spun out into a GitHub issue, where several participants in the ACME working group discussed changes to the specification to address the security issue. In a community thread on deployment status, a Let’s Encrypt engineer noted in May 2026 that the specification was still evolving and that shipping could land in Q3 if consensus on certain open issues at the IETF didn’t resolve quickly. By late June, the position had hardened into a blocker: another Let’s Encrypt engineer stated that Let’s Encrypt will not deploy dns-persist-01 until the open GitHub issue is resolved.
The big open issue: proxy ACME servers run by attackers
The problem is that the dns-persist-01 record, as originally specified, contains only information supplied by the ACME server. Specifically, the issuer-domain-name and the account URI are sourced from the CA operating the ACME server. Nothing in the record is independently supplied by the client and verified by the ACME server. The lack of client-supplied information in the dns-persist-01 record enables this attack:
- The attacker stands up a malicious ACME server.
- The attacker gets a victim to configure the malicious server’s directory URL in their ACME client. For example, this could be done through a typosquatted directory URL (e.g.,
https://acme-v02.api.letsencyrpt.org/) that closely resembles a real one. - When the victim registers an ACME account with the malicious server, the attacker simultaneously registers their own account at a “real” CA, and then hands the victim back that account’s URI verbatim in the response payload for the “register account” ACME request.
- The victim publishes a
dns-persist-01record containing what they believe is their account URI. In reality, it authorizes the attacker’s account at the real CA. This enables the attacker to obtain certificates for the victim’s domain.
This sort of attack was anticipated when the original ACME specification, RFC 8555 was published. Preventing this sort of MitM (“Machine in the Middle”) attack is the motivation why all other ACME validation methods include some form of the ACME account’s public key to appear in the challenge response. The inclusion of the public key thwarts this sort of attack by having the ACME server compare the expected public key value for the account and the public key value presented in the challenge response. When the attacker tries to issue for the victim’s domain, the real ACME server expects to see a value derived from the attacker’s key, but it will instead retrieve a challenge response containing the victim’s key. Since the expected public key and retrieved public key do not match, the attacker’s attempt to validate the victim’s domain will fail.
Proposed remediation and trade-offs
The design change that is being proposed in the GitHub issue comments is the same as the other ACME validation methods. Specifically, dns-persist-01 needs to include a value computed over the public key of the ACME account, rather than relying solely on server-provided data. Binding the record to the client’s key remediates the security vulnerability, because the attacker can no longer get the victim to provision a value that authorizes the attacker’s own account.
However, there is a trade-off in the proposed change. In the original design, the ACME client could freely rotate its ACME account keys without requiring a corresponding DNS record change, as the ACME account URI is stable across key rollovers. The downside is that by requiring the inclusion of the public key in the DNS TXT record, the TXT record value needs to be kept in sync with any account key changes.
A side benefit of the proposed change is that account key rollovers that are performed in response to a key compromise event automatically invalidate the existing DNS records. This ensures that the records cannot be misused by an attacker who has compromised the old account key.
Where things stand
dns-persist-01 is a useful evolution of DNS validation, as it obviates the need to store DNS credentials in ACME client configurations and removes the concern about propagation delay. However, the move from per-issuance proof to standing authorization changes the threat model. The “proxy ACME server” concern is one that Let’s Encrypt has tied its production deployment to its resolution.
Until the ACME working group arrives at a solution, expect the roll-out timeline to keep slipping.
There’s also
dns-account-01, but only a few clients and CAs support it, so it is not widely used. ↩︎