ACME Renewal Information (ARI) Extension
Extracted elements (25)
RenewalInfo resources are exposed via unauthenticated GET requests (departing from RFC 8555's POST-as-GET requirement) because the renewal information is not confidential, and allowing easy caching helps shed load from clients that do not respect the Retry-After header.
The ARI extension was designed to allow CAs to suggest renewal windows to mitigate load spikes and handle exceptional circumstances such as mass-revocation events or upcoming mass-renewal spikes, which existing client-driven renewal strategies (fixed interval, percentage of validity) cannot accommodate.
This document assumes certificates issued by the ACME server comply with RFC 5280 and contain the Authority Key Identifier extension with the keyIdentifier field, since the keyIdentifier is required to construct the unique certificate identifier used in RenewalInfo requests.
A RenewalInfo object in which the end timestamp equals or precedes the start timestamp is invalid. Servers MUST NOT serve such a response, and clients MUST treat one as though they failed to receive any response from the server.
After an initial fetch of RenewalInfo, clients MUST fetch it again as soon as possible after the time indicated in the Retry-After header (with error backoff taking priority). Clients MUST set reasonable limits on their checking interval, for example treating values under one minute as one minute and values over one day as one day.
An ACME server that wishes to provide renewal information MUST include a new field, 'renewalInfo', in its directory object, with a value that is the URL of the renewal information resource.
Clients MUST attempt renewal at a time of their choosing based on the suggested renewal window. The RECOMMENDED algorithm selects a uniform random time within the window; if that time is in the past, the client renews immediately.
Clients MUST NOT check a certificate's RenewalInfo after the certificate has expired, and MUST NOT check it after they consider the certificate to be replaced (e.g., after a new certificate for the same identifiers has been received and configured).
Clients SHOULD fetch a certificate's RenewalInfo immediately after issuance.
Clients SHOULD include the 'replaces' field in newOrder requests when there is a clear predecessor certificate. Clients SHOULD NOT include it if the ACME server has not indicated ARI support by advertising the renewalInfo resource in its Directory.
If the server accepts a newOrder request with a 'replaces' field, it MUST reflect that field in the response and in subsequent requests for the corresponding Order object.
On receiving a long-term error (invalid or missing Retry-After, invalid RenewalInfo object, DNS failure, connection refused, non-5xx HTTP error), clients MUST make the next renewalInfo request as soon as possible after six hours have passed or some other locally configured default.
On receiving a temporary error (connection timeout, request timeout, 5xx HTTP errors), clients SHOULD do exponential backoff with a capped number of tries. If all tries are exhausted, clients MUST treat the request as a long-term error.
Servers SHOULD check that the certificate identified by 'replaces' and the newOrder request correspond to the same ACME Account, share at least one identifier, and that the certificate has not already been marked as replaced by a non-invalid Order. If the certificate has already been replaced, the server MUST return HTTP 409 with an 'alreadyReplaced' problem document.
A new 'replaces' field is added to the ACME Order object. Its value is a string uniquely identifying a previously issued certificate that this order is intended to replace, constructed using the same format as the RenewalInfo path component (base64url(AKI keyIdentifier) + '.' + base64url(Serial)).
A RenewalInfo object contains a required 'suggestedWindow' JSON object with RFC 3339 'start' and 'end' timestamps bounding the recommended renewal window, and an optional 'explanationURL' string pointing to a page explaining the suggested window.
The RenewalInfo resource is a new ACME resource type that allows clients to query the server for suggestions on when they should renew certificates. It is accessed via unauthenticated GET requests to a path under the server's renewalInfo URL.
The unique identifier for a certificate in RenewalInfo requests is constructed by concatenating the base64url-encoded keyIdentifier field of the certificate's AKI extension, a period character, and the base64url-encoded DER-encoded Serial Number field (without tag and length bytes), with all trailing '=' characters stripped from both parts.
IANA has added the 'alreadyReplaced' error type to the 'ACME Error Types' registry, defined as: 'The request specified a predecessor certificate that has already been marked as replaced.'
IANA has added the 'renewalInfo' entry to the 'ACME Resource Types' registry in the ACME Protocol registry group, associating it with the RenewalInfo object resource type defined in this document.
IANA has added the 'replaces' field (type: string, configurable: true) to the existing 'ACME Order Object Fields' registry within the ACME Protocol registry group.
IANA has created a new 'ACME RenewalInfo Object Fields' registry in the ACME Protocol registry group with Specification Required procedure. Initial entries are 'suggestedWindow' (object) and 'explanationURL' (string).
Servers must take measures to ensure that unauthenticated RenewalInfo requests cannot result in denial-of-service attacks, such as ensuring caches do not include superfluous request headers in their cache key, instituting IP-based rate limits, or applying other best-practice measures.
Significant clock skew between ACME client and server can cause undesired behavior: a client with a slow clock may see a past-dated suggested window as future, and servers attempting precise renewal scheduling may fail if clients have skewed clocks. Server operators should account for this when setting suggested renewal windows.
The full RenewalInfo request URL is: renewalInfo || '/' || base64url(AKI keyIdentifier) || '.' || base64url(Serial), where base64url encoding follows RFC 4648 and trailing padding is stripped from both components.