Good point. The nested list should be an object. I originally had this as a tuple of CN + URL – then realized it needed issuer and expiry.
There is a disconnect with both my intent and usage on some points. I'll address them below, but first...
Using Certbot as an example flow, as it is the most popular client: One must first determine the current options for a chain by searching the CA's online documentation. Then they must submit the chain's identifier via the --preferred-chain
argument. Cerbot will then download all the chains and either: 1) use the one which best matches logic or 2) use the default if none match. All other chains are tossed (not a good idea, IMHO).
So the intended usage patterns are:
- querying the server to determine which chains are currently offered, so an existing client like Certbot can present the current options for commandline arguments, without needing to change their UX/UI to present an interactive chain selection.
- enabling a non-interactive client to detect a change in active chains before renewal
The intent of using the ACME spec to influence chain selection is to standardize what the arguments would be in order to increase interoperability between clients, and guide clients to use select criteria. Referecing the Certbot issue I linked to, a fingerprint was briefly considered but then sidelined for concerns over subscribers incorrectly calculating the value. By exposing select information in the payload - such as CN - a client would be more likely to use those fields as the label. Stated differently: if the payload contains CNs and not fingerprints, client maintainers are highly likely to use the CNs and unlikely to use fingerprints.
Side note: Those are good parameters; I'll add size on my next edit.
This endpoint is intended to address changing chains/roots, and should be expected to vary across requests as the payload would be ephemeral and account-specific.
Under the current ACME implementation, one must finalize
an order to see the current chains - a "chicken vs egg" situation.
A purpose of the endpoint is to allow a subscriber to query the server to determine what the current options are for the initial order or renewal. Ideally a client would then surface to their users a message like:
Currently valid options for our "preferred-chain" are:
The client could then list all the chains as they wish, with a client-specific selector.
If a subscriber requires a specific chain on renewal, a client could then query the server before renewal to ensure the chain is still offered. If it is no longer offered, a client could potentially:
- abort the renewal then notify the client
- continue with the renewal, use a different chain, then notify the client
Your approach works for initial interactive enrollment. I am trying to address automatic non-interactive renewals.
-
If the requested chain does not appear, the logic is up to the client. I believe Certbot will use the default chain if none match.
-
For an interactive client, I think the approach you outlined is absolutely correct. My concern is for non-interactive processes and renewals - and being able to surface the situation where a chain is no longer offered before finalizing (or even starting) an ACME Order. A subscriber should be able to determine if their preferred chain is no longer an option before consuming a (metered) ACME Order or restarting servies under a chain they do not wish to run.
-
There are two usage patterns that come to mind regarding "Here's what we got" and "it doesn't appear" .
- These two are months/days apart - the inital interactive order and a renewal. Polling this endpoint would allow the client to surface the change to the subscriber before doing a renewal.
- These two are minutes apart, the change being due to an upstream deployment. A client should download the certificates (the order has been finalized) and alert the user to the mismatch. The client/subscriber should decide what happens next - e.g. should services under the new certificate be restarted or not?
Flipping from Certbot to certmagic for a moment, I believe the utility would be in this scenario: Before or during renewal, certmagic determines the previously selected chain preference is no longer valid. Certmagic determines whether the renewal should proceed or not, then notifies the user. The user can then invoke certmagic to query the endpoint and list the current options, which are then used to update the renewal configuration for the instant domain (and any other affected ones).