Subject: Re: [Acme] Combine "requirements" and "authorizations."

From: Jacob Hoffman-Andrews <[email-masked]>
Date: Mon, 14 Nov 2016 20:02:21 -0800

On 10/29/2016 09:26 AM, Richard Barnes wrote:
> * Requirement == What you have to do to get *this* *particular*
> certificate issued
> * Authz == You must do one of N things to prove you control the identifier

Since authz's are recyclable or not at the server's discretion, why do
you need two separate types to represent the difference between
something needed for *this* *particular* certificate vs something needed
for any certificate containing an identifier? You can use the same type
to represent both, which simplifies both client and server
implementation, as well as simplifying the spec.

> The current structure is basically a conjunctive normal form:
>
> App <= (Chall1 || Chall2) && (Chall3 || Chall4) && Req1
>
> That is, there are two things that tell the client what to do,
> requirements and challenges.  Authorizations allow the CA to offer
> groups of challenges "or"ed together.
Right - and I'll note that Req1 in this diagram fills exactly the same
role as an authz.

> (1) the specialization of the authz grouping means you don't have to
> repeat the identifier in each challenge
The same is true when you specialize on a specific type of authz, i.e.
"dns-name".

I'll also note that the requirements / authorizations divide is a lot of
protocol complexity to take for some unspecific future use case. I agree
we need a nice place to slot in extensibility, but I think the place to
do that is among the types that are already going to be implemented,
specifically authz.

---

From: Richard Barnes <[email-masked]>
Date: Tue, 15 Nov 2016 23:43:39 +0900

@cpu and I talked this over today, and I'd like to propose a compromise
solution.  Outlined below, but will also be in slideware form for
discussion at the F2F tomorrow.

Basically, I think there are two properties we're trying to conserve here:
1. Minimize the number of layers of indirection and duplicate "status"
fields
2. Maximize the reuse of common logic, in particular the authorization flow

I'm willing to stipulate that we don't have a concrete need for the OOB
requirement type right now.  (If anyone has one, please speak up!)  That
basically removes any need for an additional layer of abstraction.  So it
seems like we can hit those two criteria by doing the following:

1. Removing the "requirements" abstraction and replacing the "requirements"
array with an "authorizations" array
2. In particular, remove the OOB requirement type
3. "Inline" the authorization objects into the order/application object,
just as challenges are inlined into authorizations (while still keeping
them addressable, as challenges are)

Pros:
a. Removes duplication of "status"
b. Maintains authorizations as a general construct (not DNS-specific)
c. Saves the client a GET per authorization

Cons:
a. Removes the ability of the CA to require anything besides proof of
holding identifiers
b. Sends a lot of bytes for authorizations that are already valid

If it turns out CAs need to ask for more things, we can debate then whether
their needs can be expressed as authorizations, or whether we need to add
some additional fields to the order object.  Either way, this can be done
in an extension; doesn't need to be in the base spec. Con (b) is mostly
syntactic sugar, but you could address it by saying that authorizations
with status == valid could be represented by reference, as in { "status":
"valid", "url": "..." }.

Happy to hear folks' thoughts on the list here, and talk F2F tomorrow.

--Richard

On Tue, Nov 15, 2016 at 1:02 PM, Jacob Hoffman-Andrews <[email-masked]> wrote:

> Since authz's are recyclable or not at the server's discretion, why do you
> need two separate types to represent the difference between something
> needed for *this* *particular* certificate vs something needed for any
> certificate containing an identifier? You can use the same type to
> represent both, which simplifies both client and server implementation, as
> well as simplifying the spec.
>
> requirements and challenges.  Authorizations allow the CA to offer groups
> of challenges "or"ed together.
>
> protocol complexity to take for some unspecific future use case. I agree we
> need a nice place to slot in extensibility, but I think the place to do
> that is among the types that are already going to be implemented,
> specifically authz.
>

---

From: Jacob Hoffman-Andrews <[email-masked]>
Date: Tue, 15 Nov 2016 16:46:27 -0800

On 11/15/2016 06:43 AM, Richard Barnes wrote:
> 1. Removing the "requirements" abstraction and replacing the
> "requirements" array with an "authorizations" array
Seems good.
> 3. "Inline" the authorization objects into the order/application
> object, just as challenges are inlined into authorizations (while
> still keeping them addressable, as challenges are)
I don't see the need for this, and actually think it's a negative. GETs
are cheap for the client, especially with HTTP/2. Inlining like this
means there are two ways for a client to check the status of an
authorization: by polling the authz, or by polling the application /
order. We've seen in Boulder that having two ways to do things leads to
bugs, so I'd rather say you must poll the authorization.

Also, for orders with lots of authz's in them, polling the order object
will be more expensive for the server than polling individual authzs,
because each poll of the order object has to reconstruct a larger number
of objects from the DB. When clients poll individual authzs, they only
check each authz until it is done, then stop.