Renewal information¶
RFC 9773 lets a server tell each client when to renew a certificate and lets a client name the
certificate a new order replaces. Setting Config.RenewalInfo enables both.
RenewalInfo: acmeserver.LifetimeRenewal{},
With it set, the directory advertises renewalInfo, clients fetch a suggested window with an
unauthenticated GET and new orders may carry replaces. Without it, the resource is absent and a
replaces member is ignored.
The renewal window¶
type RenewalAdvisor interface {
RenewalInfo(ctx context.Context, cert *Certificate) (RenewalInfo, error)
}
LifetimeRenewal is the built-in advisor. It opens the window at two thirds of the certificate
lifetime and closes it at five sixths. For a 90-day certificate that is days 60 to 75. A revoked
certificate gets a window that opened at its revocation time, so clients renew at once. The
fractions, an explanation URL and the Retry-After are fields on the struct:
RenewalInfo: acmeserver.LifetimeRenewal{
Start: 0.5,
End: 0.75,
ExplanationURL: "https://ca.example.com/renewal",
RetryAfter: 12 * time.Hour,
},
Implement RenewalAdvisor for other schedules, for example to move every window forward when a
CA incident requires mass renewal. The End must be later than the Start. RetryAfter defaults
to six hours and tells clients how long to wait before asking again.
The certificate identifier¶
Clients address renewal information by the certificate identifier of RFC 9773 section 4.1: the
base64url authority key identifier and the base64url serial number joined by a dot. The server
computes it as Certificate.RenewalID when the certificate is stored. It is empty when the leaf
has no authority key identifier. Such a certificate has no renewal information and cannot be
replaced. Make sure your CA sets the extension.
Stores keep non-empty RenewalID values unique and look certificates up by them through
CertificateByRenewalID.
Replacing a certificate¶
A new order may name the certificate it replaces. The server checks that:
- the identifier is well formed and names a stored certificate, otherwise
malformed - the certificate belongs to the requesting account, otherwise
unauthorized - the new order shares at least one identifier with the certificate's validated identifiers, otherwise
malformed
The store then marks the certificate as replaced by the order in the same transaction that creates
the order. A second order naming the same certificate is refused with alreadyReplaced while the
first one is not invalid. Once the first order expires or fails, the claim is free again. Clients
such as acmez and lego drop the replaces member after an alreadyReplaced answer and order
without it.
Order.Replaces and Certificate.ReplacedByOrderID record the relation for the host. A CA that
wants to revoke the old certificate once the new one is issued has both ends of the link.