A new mechanism to ask the ACME2 server for a window within which to renew a certain valid certificate is called ACME Renewal Information (ARI).
The following source identifies a protocol transition in late April 2024 from draft-ietf-acme-ari-01 to draft-ietf-acme-ari-03: LE user ‘beautifulentropy’, “Discontinuing support for ACME clients using draft-ietf-acme-ari-01”, 19 Mar 2024, Discontinuing support for ACME clients using draft-ietf-acme-ari-01 .
The ARI-03 protocol is described in: Samantha Frank, webpage “An Engineer’s Guide to Integrating ARI into Existing ACME Clients”, 25 April 2024, An Engineer’s Guide to Integrating ARI into Existing ACME Clients - Let's Encrypt .
RFC 9773, “ACME Renewal Information (ARI) Extension”, June 2025 appears to be ARI, version 3.
The ARI-03 protocol is concerned about uniformly spreading out the load on the Certificate Authorities (CAs) ACME[2] server. I don't object to that idea in isolation, but in the real world of conflicting social objectives that goal seems to me to be unreasonably burdensome to client software design and implementation. This suggests to me the common pasture problem. CA rate limits will not be obviated by ARI or communal cooperation in an actual ecosystem.
Perhaps you have read some version of the online essay or ebook: Eric S. Raymond, “The Cathedral and the Bazaar”. (A source: The Cathedral and the Bazaar)
I am trying to understand how my personal ACME[2] client could use ARI. I have two design issues with the algorithm for time selection. I am aware that I am not a very knowledgeable programmer and ask for thoughtful philosophical or practical opinions. I have not (yet?) read all of RFC 9773. I have read all of Frank, “An Engineer’s Guide to Integrating ARI into Existing ACME Clients”. When I did, I had design concerns only with the section: “Step 5: Selecting a specific renewal time”.
Section “Step 5: Selecting a specific renewal time”:
draft-ietf-acme-ari provides a suggested algorithm for determining when to renew a certificate. This algorithm is not mandatory, but it is recommended.
- Select a uniform random time within the suggested window.
- If the selected time is in the past, attempt renewal immediately.
- Otherwise, if the client can schedule itself to attempt renewal at exactly the selected time, do so.
- Otherwise, if the selected time is before the next time that the client would wake up normally, attempt renewal immediately.
- Otherwise, sleep until the next normal wake time, re-check ARI, and return to “1.”
For Lego, we implemented the above logic in the following function:
func (r *RenewalInfoResponse) ShouldRenewAt(now time.Time, willingToSleep time.Duration) *time.Time {
// Explicitly convert all times to UTC.
now = now.UTC()
start := r.SuggestedWindow.Start.UTC()
end := r.SuggestedWindow.End.UTC()
// Select a uniform random time within the suggested window.
window := end.Sub(start)
randomDuration := time.Duration(rand.Int63n(int64(window)))
rt := start.Add(randomDuration)
// If the selected time is in the past, attempt renewal immediately.
if rt.Before(now) {
return &now
}
// Otherwise, if the client can schedule itself to attempt renewal at exactly the selected time, do so.
willingToSleepUntil := now.Add(willingToSleep)
if willingToSleepUntil.After(rt) || willingToSleepUntil.Equal(rt) {
return &rt
}
// TODO: Otherwise, if the selected time is before the next time that the client would wake up normally, attempt renewal immediately.
// Otherwise, sleep until the next normal wake time.
return nil
}
I notice the phrase ‘not mandatory’. RFC 9776 has this:
Clients MUST attempt renewal at a time of their choosing based on the suggested renewal window. The following algorithm is RECOMMENDED for choosing a renewal time:
Notice two details of the example implementation from Frank, Step 5:
(1) Step 3 of the algorithm in Frank, the section for Step 5 is ‘if the client can schedule itself to attempt renewal at exactly the selected time, do so’. Without a master process or thread controlling worker processes or threads, the only ways to schedule for the exact time are to ‘tell the scheduler how to schedule’ or sleep the current process. The example seems to sleep the current process.
I don't want to integrate a scheduler into my ACME[2] client for what should be obvious reasons, or you know something I don't know, and that I would like to know. I don't want to sleep my client process because it is doing all the renewals in its purview in sequence. ARI is designed to address security breaches. Maybe a certification to be considered by my client for renewal has an a security issue more dire than the issue of the currently considered certification.
(2) Step 4 of Frank, the section for Step 5 is ‘if the selected time is before the next time that the client would wake up normally, attempt renewal immediately’. How does the code know what the time of the next scheduled run is? Do I query systemd? Do you query something else? A second source of truth that is easily outdated by changing the scheduling per the scheduler program of choice?
Step 5 of Frank, the section for Step 5 is ‘sleep until the next normal wake time, re-check ARI, and return to “1.”’ That I can do. However, the corresponding step in RFC 9776 is ‘sleep until the time indicated by the Retry-After header and return to Step 1’. I have an issue with sleeping the client program as noted.
All of my concerns have to do with futuristic computations and scheduling changes. My design intentions are to have a scheduling-ignorant client. If I omit preemptively immediate invocation and invocation scheduling for a particular certification, which I would do with my client software, then I am potentially late according to the AC's renewal window that is potentially not yet begun and is certainly not yet over.
Contravening that tendency to be late to renew per the ARI window is the time qualifier of my (the client's) choosing that could select a certificate for renewal at the time of the current invocation of the client software. Additionally, the futuristic window overshoot is mitigated by more frequent regular invocations of the ACME[2] client software. The impending transition from 90-day end-entity certificates to 6-day end-entity certificates necessitates regular client invocations with intervals of no more than 6 days. Daily invocation seems likely. What kind of problem would certificate renewal after the close of a futuristically specified window period terminus of no more than one or six days be?
I don't think the anticipatory renewal windows given by CAs are so precise that integration with a scheduler or managed worker threads are justified. I find it hard to believe that I see these issues as onerous and no one else does, but then I have not found any online indications that my concerns are anyone else's concerns. Shall I just use the big client software made by somebody else? Are ACME[2] clients to be like browsers?
If you program ACME[2] clients or servers, what are your software design intentions regarding futuristic ARI? I am trying to discern by survey the developmental direction of the conventional design features of ACME[2] client software. I wonder if my client software is just a dinosaur facing elimination in a mass extinction event now barely visible on the horizon.