Thoughts from starting to play with ARI

Just as another data point, the other CA I'm aware of that implemented ARI is Google (though I haven't tried actually using it yet since I would need to make a Google Cloud account to do so), and their directory (in both their production and their test environments) have renewalInfo listed without a trailing slash.

Thanks for the explanation. Though apparently other CAs either have other interpretations or intentionally diverged from the spec and choose to not error on them even if they can't respect them.

Really maybe the answer here is that more of these choices should be available, maybe in the meta data from the directory. Understanding which parameters a CA allows to set (dates, must-staple, hash algorithms for CSRs, hash algorithms for ARI requests, and who knows what else), plus other things like applicable rate limits, server challenge retry behavior, and so forth, in a client-consumable way, I think would really help with clients being able to just accept a directory URL as all that's needed for CA configuration.

That's still mostly off-topic for talking about ARI, so let's try to get back on track, with the next part I'm focusing on:

Selecting a random time within the suggested window

I'm not sure that the "RECOMMENDED" algorithm in the draft gives the intended result, for the typical case of a cron-style "wake up and check things a couple times a day" client. In particular, if I understand it correctly, it wants the client to select a new random time within the suggested window for each time that it runs. This means that if the window is of a decent size (say, 7 days), and the client is checking twice a day, then the client is much more likely to initiate renewing earlier in the window rather than later in the window. On each run it has a chance to pick a random time, and so it would need to basically always pick a time near the end of the window, on every single run, in order to actually renew near the end of that window.

If my math is right, which it may very well not be, with a 7-day long suggested window, and a client checking twice a day, It would have had better-than-50% odds of having done renewal by the end of the second day, and by the time it was halfway-though the window (3½ days), the odds would be over 92%. So there would be a significant skew toward renewing at the beginning of the window.

I don't know if maybe that's the intended outcome, or if the idea is really that a CA wouldn't ever be giving out large windows like that. (But if windows are always going to be relatively small, then I'm not sure why you'd need both a start and end time, rather than only a start time.) Really I think that maybe the spec should give some sort of guidance to CAs about how they should be selecting suggested windows, rather than the current draft which looks to primarily be focused just on guidance for clients. It may be that some CAs would think of the responsibility being on the client to pick a random time well within a large suggested window, whereas other CAs would want to do a bit more "micromanaging" and always give out relatively small windows.

If the intention is for clients (which aren't able to schedule renewal at an exact particular time per step 3 of the recommended algorithm, though even if they can it's not entirely clear to me from what's written how that scheduling should interact with what happens if ARI is checked again before that specific time) to try to uniformly spread themselves out within the window, then I think there needs to be guidance to either

  1. Store the random time and suggested window in some persistent storage, and for the client to use the same random time if it got the same suggested window, or
  2. Do something with a repeatable pseudo-random generator, seeded with the cert and suggested window and maybe some other things too like hostname or account id, and use that to calculate a renewal time in a repeatable way from what the client has access to, so that on the next run if the server gives the same suggested window then the client will calculate the same renewal time. (Like, calculate SHA-256 of a concatenation of the the suggested window, plus existing cert, plus hostname, take that giant number and divide by 2^256 to get a fraction between 0 and 1, and use that to scale how far through the suggested window to plan as the renewal time. Though I don't know if it needs to be that fancy.)

That is all assuming, though, that CAs will usually not change suggested windows absent some precipitating event, rather than dynamically recalculating expected load constantly and tweaking windows by an hour or two at a time in one direction or another each time a client requests it.

Determining next wake-up time

The other thing about following the recommended algorithm which, while I wouldn't say is hard, I think can be at least a little tricky, after you've done the above to select a renewal time, is in step 4 where it says "if the selected time is before the next time that the client would wake up normally". I think most cron-style schedule systems don't have an easy (or at least standardized) way to specify to the application when the next time will be that the client would get run. Obviously one can pass it in as another parameter (say, having it run my-client renew --next-run=12h when set to run twice a day), but it means that switching to once-a-day or three-times-a-day or whatever involves more than just updating the scheduling itself, but also updating the command-line that gets run. And it may not be obvious to the system administrators exactly what that value is and why it needs to be accurate. (Well, if it's not completely accurate that wouldn't be a terrible thing, but it seems like it ought to be close.) Also, for scheduling systems that let one add some jitter to the schedule time (which we would generally want, wouldn't we?) it may be even trickier to figure out the right parameter to pass along for "run anytime the system has capacity between 6am and 8am, and then again anytime the system has capacity between 6pm and 8pm".

6 Likes