Hi Matt,

Agreed with Tim, receiving practical feedback from implementers of the
draft standard is very useful. I'll put my thoughts, comments, and
questions in-line.

On Fri, Jun 23, 2023 at 9:21 AM Matthew Holt <m...@dyanim.com> wrote:

>
> With respect to ARI, ACME servers and clients have conflicts of interest.
> The ACME client's goal is to keep the site up (with renewed and unrevoked
> certificates); the optimal way to do this is to start renewing early and
> retry often. The ACME server's goal is to keep the service up; the optimal
> way to do this is to suppress clients that overload your capacity.
> Obviously, these two goals are in opposition with each other. Proactive
> clients can spike demand, which can cause service interruptions. But
> service interruptions make clients more paranoid to retry even more often
> until it works, and so on. ARI narrows the timeframe in which a conforming
> client can retry failed renewals, which reduces reliability more as time
> goes on. Without ARI, this window is a reasonable ~60 days. With ARI,
> however, the window is reduced to just a few minutes, hours, or days. The
> less time until expiration, the less hope there is to renew the cert in
> time. As the draft currently stands, this is in the server's interest, but
> not the client's.
>

I'm confused by the statement that "with ARI the window is reduced to just
a few minutes, hours, or days". The draft spec clearly states that the
client should renew during the window if it can, but that any time after
the window is also acceptable: "if the selected time is in the past,
attempt renewal immediately". The renewal window only becomes reduced to a
few minutes, hours, or days if the ACME server shifts the suggested renewal
window that far. Which, sure, is possible, but is clearly against the
server's best interest as well: if the ACME server can't provide continuity
of business to their Subscribers, then their Subscribers will go elsewhere
for certificates.

Can this be improved? Absolutely, I'm certain of it. I'd love to hear
suggestions for ways that the server could suggest a renewal time that
doesn't run up against this push/pull between wanting to smooth traffic
without making clients nervous. Unfortunately, I don't believe either of
the suggestions at the bottom of the message actually addresses this point
(more on that below).


> 1) It is optional. No one will implement this. OK, some clients will --
> but I can say with authority from years of experience that optional
> restrictions are not typically favored. Very little mainstream software
> follow best practices to a tee.
>

Yep, optional features are difficult to incentivize. I think there's one
obvious carrot to incentivize client adoption: "if you implement ARI, your
certs will be renewed *before* they're revoked in the next mass revocation
incident". Continuity of business can be a powerful motivator. Frankly,
Let's Encrypt is even considering bigger carrots, such as "your subscriber
account can only get short-lived certs if we've seen it request ARI
endpoints", or "your renewal requests bypass all rate limits if they're
made within the ARI suggested window". We don't know if we'll dangle either
of those carrots, but it's clear that there are ways to incentivize
adoption.


> 2) A narrower renewal timeframe makes clients less reliable. In theory it
> should make them *more* reliable since it smooths out traffic, thus
> improving CA availability. But this assumes that most clients actually
> implement and follow ARI. Since it's optional, I don't see that happening.
> Especially since most ACME clients are still running as static cron jobs
> like it's 2015...
>
> I'm sure ARI doesn't really change in the nominal case, which is 99.9..9%
> of the time. In fact, Let's Encrypt's ARI seems to correspond with when my
> clients attempt renewals on their own anyway. (So in that sense, ARI is
> actually useless 99.9..9% of the time?)
>
> But when a renewal window does change, what does that mean? Well,
> something is wrong. Either the certificate is being revoked, or the CA
> anticipates downtime or availability issues.
>

This is not true. Explicitly, by the spec, the renewal window changing
means nothing. The situations you list are the motivations for writing the
spec in the first place, but they are not the only motivations for changing
the window in any given case. In fact, Let's Encrypt is currently
considering adding random jitter to the renewal window every time it is
requested, specifically to prevent interpretations like this, and to
naturally even-out renewal spikes through Brownian motion.


> If we wait until the (adjusted) window to start renewing, we run ourselves
> closer to the imminently-impending revocation or the expiration of the
> certificate, lowering our chances of a successful renewal.
>

This assumes that the adjusted window will always be later in the lifetime
of the certificate than before. There is no reason to make this assumption.
A CA adjusting suggested windows in order to smooth out a load spike would
be wise to shift 50% of renewal windows *earlier*. Waiting to renew until a
time that is earlier than when you would have renewed anyway does not make
things riskier.


> 1) Many CAs enforce rate limits. If clients are to honor ARI windows, we
> would need a guarantee that the first successful cert within the ARI window
> will be allowed regardless of relevant rate limits. Because ARI restricts a
> client's ability to spread out renewals when managing certificates in bulk
> with respect to rate limits, the rate limits must NOT be a blocker when
> honoring ARI.
>

I like this idea. We hope and plan to implement this regardless, as I
suggested above with regards to it being a carrot that we can dangle to
incentivize client adoption. However, I don't believe it is something that
can be reasonably specified in an IETF RFC: rate limits are not part of the
ACME protocol, they're an internal detail of ACME server implementations.
Happy to be proven wrong.


> 2) If ARI were actually enforced, some concerns would be resolved... for
> example, we can have assurances that other ACME clients are doing the same,
> thus improving CA availability. It would essentially be the CA scheduling
> each individual certificate for each ACME client instance -- that's quite a
> powerful idea, as long as availability is guaranteed (which it's not).
>

What do you mean by "enforced"? Deny newOrder requests that appear to be
renewals but fall outside the suggested window?


> 3) ARI does not scale well. Some ACME clients manage 10K+ certificates,
> and in that case the client would have to check the ARI for at least 24
> certificates per hour to get through them in a month. Deferring to the
> Retry-After header may result in insufficient throughput. The current
> expectation or convention is to check every certificate every 6-12 hours,
> or tens of thousands of checks per day. One endpoint per certificate
> multiple times per day is quite saturating. This is a considerable burden
> for both ACME clients and servers. I would like to explore options that do
> not involve 2+ HTTP requests per certificate.
>

Totally agreed, we don't love the heavy-polling nature of ARI as it stands
either. It's a lot of requests, and that's a large part of why we've
striven to keep the response size so small. The original version of this
was just a single timestamp. It's grown to two timestamps and an optional
URL thanks to community feedback, but I'd be happy to reduce the response
size again if we decide that prioritizing efficiency is more important than
prioritizing third-party certificate monitoring tools.

Unfortunately, I don't currently have a different approach that I love. The
24-hour revocation timeline enforced by the BRs for certain kinds of
revocations means that clients should be checking at least once every 24
hours, regardless of mechanism. I'll comment more on your specific
proposals to address this below.

4) Crafting the URL is convoluted. As Peter Cooper described it, "The core
> issue is that the URL you need to construct is based on an OCSP structure
> identifying the certificate, which requires taking one's existing
> certificate and parsing out the serial number and issuer, and also taking
> the intermediate certificate that signed it and getting its public key too.
> So rather than just, like, using the fingerprint of the existing leaf or
> something similarly simple that a lot of tooling can already give you, one
> needs to really dig into both the leaf, and the intermediate, and hash
> various pieces thereof, and then take all that to build a new ASN.1
> structure." Why are we striving for near-parity with an OCSP request?? This
> should be orthogonal to OCSP, right?
>

This is great feedback. We picked this request format specifically because
we thought it would be easy. It's good to know that we were wrong, and
investigate what other request formats would work better.

Allow me to provide a little bit of context for how we arrived at using the
OCSP CertID structure:

We need a way to uniquely identify the certificate in question. ACME has
one mechanism for doing so already: the URL provided by a finalized Order.
Personally, my ideal would be to say "the ARI url is the Certificate URL
concatenated with /ari". Unfortunately we can't do that, because there's
nothing to prevent the URL provided by an Order from having query
parameters, in which case appending a new path component would be
incorrect. So, we could follow ACME's example, and provide a second
"renewalInfo" URL in finalized Orders as well. Unfortunately, this a) means
that clients have to persist this URL in order to use it, and b) clients
which did not persist the URL (either ephemeral clients, or third-party
certificate monitoring clients) cannot construct the URL at all.

So we need a way to uniquely identify a certificate which can be
constructed from the certificate itself. The serial seems like an obvious
candidate. However, serials are only required to be unique on a per-issuer
basis, and a single ACME server may issue from multiple issuer
certificates. It turns out that OCSP already has a solution for this:
combine the serial with a unique identifier of the issuer. And OCSP's
solution even comes with algorithm agility for how the unique identifier of
the issuer is computed! That's nice. So we took OCSP's request format,
stripped away the pieces not pertaining to identifying a single
certificate, et voila, the CertID.

We believed this would be easy because many ACME clients are written in
languages or running in environments that already have access to robust
OCSP libraries. I wrote the first version of this
<https://github.com/letsencrypt/boulder/blob/73b72e8fa2d852a40753926c34f38313a7db083d/wfe2/wfe_test.go#L3517-L3538>
(constructing
an OCSP request, parsing it, extracting the relevant parameters, and
serializing them into a CertID) in a few minutes. Again, it's useful to
know that we were wrong.

This leads to the question of: what should we use to uniquely identify the
certificate instead? Certainly we could go with the "fingerprint" or
"thumbprint" (a sha256 hash of DER bytes or PEM encoding, depending on who
you ask, of the certificate) if people think that is sufficiently simple,
easy to specify, unique, and future-proof. We could also go with "just the
Serial", and force existing ACME servers to choose between either keeping
serials unique across all issuers they represent, or splitting the server
into multiple servers which each represent just a single issuer. Or we
could return to the "url in the Order object" approach we started with. I'm
curious what path forward people think is best.


> 5) Web browsers / HTTP clients are bound to "abuse" ARI because the GET
> request is not authenticated. Even if the information is not strictly
> sensitive, I can totally see some browsers or tools using ARI as a signal
> that a certificate is being revoked, and thus can no longer be trusted, and
> thus block a site before a server even sees that it needs to renew its
> cert. I could be incorrect, but can't the information needed to obtain ARI
> can be scraped from CT logs? If so, I think a global ARI monitor/database
> is inevitable, and that has interesting implications that I don't know have
> been fully realized.
>

Yes, as mentioned above, this was a design goal as a result of community
feedback. See this early discussion
<https://mailarchive.ietf.org/arch/msg/acme/szDHa5z6qRiAtmeC2ohrePPoBjU/>
for context. Again, this is a design goal that I'd be willing to compromise
if there are sufficient reasons to do so, but I don't think that argument
has been fully articulated as of yet.


> All in all, the current ARI spec feels a little rushed. I'm hoping Let's
> Encrypt's production deployment is meant to help gather feedback about ARI
> before finalizing it, rather than to solidify it. Can we revisit both its
> fundamentals and practical implications too?
>

Yes, the IETF process is about "rough consensus and running code". We can't
finalize the spec until something is running. Let's Encrypt's deployment,
and our encouragement of client adoption, is so that we can receive
precisely this kind of feedback before the draft becomes an RFC.


> I would like to explore some alternatives to the current draft. I can
> think of two approaches that might address these concerns:
>
> A) Instead of a totally separate flow to obtain ARI, simply utilize a
> Retry-After header in the flow of existing ACME responses. Upon finalizing
> an order, the ACME server can respond with a Retry-After header which acts
> as the current-draft Retry-After header for ARI responses. The client then
> attempts renewal at/after the Retry-After time, but with the OCSP CertID
> added to the NewOrder object; this indicates to the ACME server that the
> client is asking if now is a good time to renew the certificate indicated
> by the CertID. If it's not a good time, the ACME server can reply as such,
> with another Retry-After, and the client then waits and repeats, until the
> server actually issues the certificate. If the client needs the certificate
> immediately, simply omit the CertID from the NewOrder and the normal,
> "non-ARI" flow is assumed. This is backwards-compatible and requires no
> additional infrastructure or endpoints.
>

I don't understand how this approach helps solve the issues you identified
above. In order to get up-to-date information, the same number of requests
still need to be made, it's just that now they're newOrder requests instead
of renewalInfo requests. The unique identifier included in the request is
no easier to construct. The Retry-After timestamp changing might still
cause selfish clients to stop providing the CertID and renew right now.

Now, I *am* a fan of adding a field to newOrder requests which uniquely
identifies the cert being replaced. If such a field is populated, the CA
would treat it the same as if the client had made a POST request to mark
the certificate as replaced (Section 4.2 of the current draft). This has
many nice effects, like letting the CA track renewals explicitly (instead
of attempting to identify them with heuristics), letting renewal requests
bypass rate limits, and more. I just don't think it elegantly replaces the
renewalInfo endpoint itself.


> B) If we do need a separate flow for some reason, I would like to see a
> single endpoint containing a static JSON resource that describes all the
> active certificates that need early renewal, rather than one
> tediously-crafted URL per certificate. Certificates can be described by
> their NotBefore or NotAfter dates, serial numbers, or other relevant
> attributes. For example, if just a few certs with certain serials were
> misissued, those serials could be enumerated at this endpoint. Or if a mass
> revocation is happening, the timeframe of NotBefore dates could be listed,
> and ACME clients can simply check against the certs they manage with those
> dates, and replace them. You can represent millions of certificates in,
> like, 85 bytes this way. And it's way less work for clients and servers.
> And lastly, drop the "window" idea -- certificates described by this
> endpoint should be renewed ASAP: try to renew immediately, then back off
> and retry, for reasons described above (once we know the future is
> uncertain and/or revocation is imminent, current certs can't be trusted
> and/or clients must try to preserve their sites' uptime).
>

On the one hand, I'm in complete agreement, it would be great to have a
"batch" endpoint that returns suggested windows for all certificates
associated with a given account, or matching some other criteria. On the
other hand, there's a reason that Let's Encrypt diverges from RFC8555 and
does not implement the "orders" field on account objects: endpoints which
serve unboundedly-large documents and require paging are difficult to
implement correctly on both the server and client side, and can quickly
lead to disruptive database queries.


> And finally, I want to bring attention to the longer-term prospects for
> ARI: it's quite possible that ARI will become irrelevant before it is
> widely adopted by most clients. This itself may discourage adoption. As
> stated above, ARI has two primary use cases: revocation and traffic
> smoothing. As we push for shorter certificate lifetimes, revocation should
> become irrelevant. And traffic smoothing will perhaps become a natural
> consequence as clients are renewing more frequently anyway. We all know
> revocation and long-lived certificates are broken, so I'd rather WebPKI
> developers focus our energy on the ACTUAL goal: short-lived certificates.
> We should not be focusing our ecosystem resources on infrastructure that
> acts as a band-aid for a broken leg.
>

This is an interesting point. ARI was first conceived
<https://bugzilla.mozilla.org/show_bug.cgi?id=1619179#c7> as a way to
improve business continuity across mass revocation events, and grew from
there. The idea that 10-day certs might be a reality, and that revocation
would be wholly optional for them, was almost unimaginable at that time.
But even today, the reality is that CAs such as Let's Encrypt will likely
have to support revocation for a very long time to come: migrating the
whole world to 10-day certs will not happen overnight. So I think that this
work is worthwhile, even if other solutions are also on the horizon.

Thanks,
Aaron
_______________________________________________
Acme mailing list
Acme@ietf.org
https://www.ietf.org/mailman/listinfo/acme

Reply via email to