Subject: [Acme] Simplifying ToS agreement

From: Jacob Hoffman-Andrews <[email-masked]>
Date: Thu, 8 Sep 2016 11:40:33 -0700

Restarting the conversation on
https://github.com/ietf-wg-acme/acme/pull/167.

An earlier version of the ACME protocol treated the new-reg URL as the
entry point for all interactions. You'd configure a client with the
new-reg URL, and after creating an account, you'd get URLs for other
resources using a series of Link headers.

This posed a problem: How do we integrate a terms-of-service URL? Our
first approach to this problem was that you get the terms-of-service URL
*after* you register, via a Link header from your registration object.
You then POST to the registration with an update. This helped reduce the
number of URLs and Link headers for clients and servers would have to be
kept track of, but it was awkward. Ideally users should agree as part of
the act of registration. Allowing accounts to be in a state where they
haven't yet agreed to the ToS means more code for both the server and
the client.

Eventually we switched to using the directory URL as the entry point.
This solved a number of other problems with URL discovery. This also
allowed us to present the terms-of-service URL to unauthenticated users,
and made it possible to agree to the terms during account creation
rather than afterwards.

Should we continue to model terms-of-service agreement as an updateable
field on the registration object? Emphatically no. This is not a field
that users can update, nor is it a field that we expect the server to
update frequently. In the spirit of AGL's "have one joint and keep it
well oiled" (https://www.imperialviolet.org/2016/05/16/agility.html),
this is a field that is updated very rarely and therefore is likely to
break poorly implemented clients if it changes. It's also redundant with
the terms-of-service URL that now exists in the directory. The
"agreement" field in the registration object is an accident of ACME's
history, and we should fix it before finalizing the protocol.

---

From: Richard Barnes <[email-masked]>
Date: Thu, 8 Sep 2016 17:32:55 -0400

> history, and we should fix it before finalizing the protocol.

So what, we should just delete it?  Are you arguing that this functionality
is unnecessary?

--Richard

>
> _______________________________________________
> Acme mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/acme
>

---

From: Jacob Hoffman-Andrews <[email-masked]>
Date: Thu, 8 Sep 2016 14:56:24 -0700

On 09/08/2016 02:32 PM, Richard Barnes wrote:
> So what, we should just delete it?  Are you arguing that this
> functionality is unnecessary?
I'm arguing for the changes in
https://github.com/ietf-wg-acme/acme/pull/167
<https://github.com/ietf-wg-acme/acme/pull/167>, specifically that we
treat terms-of-service URL as a directory field, rather than an
updateable field on the account.

---

From: Niklas Keller <[email-masked]>
Date: Fri, 9 Sep 2016 09:44:05 +0200

2016-09-08 23:56 GMT+02:00 Jacob Hoffman-Andrews <[email-masked]>:

> I'm arguing for the changes in https://github.com/ietf-wg-acm
> e/acme/pull/167, specifically that we treat terms-of-service URL as a
> directory field, rather than an updateable field on the account.
>

Does it really make sense to have it as this pseudo-field then? If there's
just one possible value we can just go ahead and allow account creation
only directly including the agreement.

I guess we still need an explicit agreement key for legal purposes?

Regards, Niklas

---

From: Josh Aas <[email-masked]>
Date: Sat, 10 Sep 2016 18:04:07 -0500

I just want to add that when Jacob says "this is a field that is
updated very rarely and therefore is likely to break poorly
implemented clients if it changes," he is not talking about
theoretical breakage. When we updated the Let's Encrypt subscriber
agreement for the first time some clients broke.

-- 
Josh Aas
Executive Director
Internet Security Research Group
Let's Encrypt: A Free, Automated, and Open CA

---

From: Richard Barnes <[email-masked]>
Date: Sat, 10 Sep 2016 19:13:23 -0400

OK, let me clarify my invariants here: I think we can't get away with not
supporting the case where the CA updates the terms and needs clients to
re-agree.  I also feel like the current proposal in #167 is semantically
incomplete, like just saying "I agree" ... to what?

I think both of these issues can be addressed with a few tweaks to this
Jacob's proposal:

- Clarify that having the agreement flag set means that the client has
agreed to whatever is in directory["terms-of-service"]
- Note that that implies that if the CA changes the terms in a breaking
way, then it needs to clear the flag in the registrations
- Add an error code "agreementRequired" (as in #182) so that the CA can
tell the client when this has happened

I agree that this will still be a seldom-exercised code path -- a lazy
implementer might still fail to properly handle the "agreementRequired"
error code.  But at least (1) it gives a conscientious implementer a clear
signal and (2) if the client does screw it up and complains to the CA, it
gives the CA something they can point to and say "you didn't do this
properly".

Jacob, can you live with those tweaks?  Happy to land #167 and write text
for the above in a follow-on PR if folks are agreeable to the approach.

--Richard

---

From: Jacob Hoffman-Andrews <[email-masked]>
Date: Mon, 12 Sep 2016 12:06:01 -0700

On 09/10/2016 04:13 PM, Richard Barnes wrote:
> OK, let me clarify my invariants here: I think we can't get away with
> not supporting the case where the CA updates the terms and needs
> clients to re-agree.
I would argue that we don't need to support it explicitly, because
returning an error with a link to an out-of-band URL for re-agreeing is
sufficient, and matches the most likely flow.

>   I also feel like the current proposal in #167 is semantically
> I think both of these issues can be addressed with a few tweaks to
> this Jacob's proposal:
>
> - Note that that implies that if the CA changes the terms in a
> breaking way, then it needs to clear the flag in the registrations
> - Add an error code "agreementRequired" (as in #182) so that the CA
> can tell the client when this has happened
This works for me, thanks!

---

From: Ron <[email-masked]>
Date: Tue, 13 Sep 2016 12:22:16 +0930

> incomplete, like just saying "I agree" ... to what?

That was the major problem I hadn't liked about this too.

> tell the client when this has happened

I'd still be happier if the "terms-of-service" field actually reflected
exactly what was agreed to (ie. what was in the directory at the time of
agreement) rather than being a potentially ambiguous flag.

I don't really see how the possible failure modes for that are different,
and it does remove any doubt if a client needs to query what had been
agreed to previously.

I think Richard's suggestion would be equivalent to that if the spec
mandated that interpretation with MUSTs, _and_ server implementors
didn't screw up that seldom-exercised code path, _and_ server admins
updating a ToS don't screw up indicating that flag must be cleared ...
which is why I prefer the more explicit semantics in the protocol.

A real screw up _should_ result in early and loud failure rather than
being swept under the rug.  That's the only way they get found and
fixed.

> gives the CA something they can point to and say "you didn't do this

There is an easy way to fix that ...  LE has a staging server (and any
other CA wanting to implement this would likely want to have one too).
And there's no reason the staging server need to have the same ToS as
the live service.  So it can just update its ToS once a day or so,
even if it's just to change a single line "The is the staging ToS for
Sep 13, 2016".

Anything that isn't tested Will be broken.  We can't fix that in the
protocol, but we can fix it by adding tests :)

  Ron

---

From: Jacob Hoffman-Andrews <[email-masked]>
Date: Tue, 13 Sep 2016 08:56:21 -0700

> protocol, but we can fix it by adding tests :)
We can also fix it by deleting unnecessary things, which is the best and
most reliable way to avoid bugs. That's why I think this is the right
approach.

---

From: Niklas Keller <[email-masked]>
Date: Tue, 13 Sep 2016 21:32:22 +0200

> sufficient, and matches the most likely flow.

This is an interesting idea. Maybe that's also something we could to
for the initial registration? Provide those errors and an out-of-band URL?

This would ensure that people do at least open the page that contains the
ToS.

Regards, Niklas

---

From: Ron <[email-masked]>
Date: Wed, 14 Sep 2016 17:44:07 +0930

> most reliable way to avoid bugs. That's why I think this is the right

I'm a big fan of that idiom too, but doing something half-assed is the
worst of both worlds.

If we aren't going to have a functional protocol interface that lets
both the client and server unambiguously communicate what was agreed
to (and query that if/when needed) - then we should just drop the
process of ToS agreement from the protocol altogether, rather than
doing some sort of legal theatre lite where the client blindly sends
a hard coded "sure, whatever you say, whenever you say it" flag.

We could just provide a directory entry (which could even be optional)
that indicates where the terms can be found, and let those terms say
that any other use of the service indicates acceptance of those terms
(just like pretty much every other network service in existence does
without needing to kludge a contentless 'accept' bit into the protocol).

Making the client send back a hard coded "open sesame" string is of
dubious legal effect, but has all the same problems of being cruft
that people will need to implement, but that absolutely nobody will
test unless the test servers force them to.  There will still be
bugs, but there won't be any actual value add to encourage even some
people to care about it being done right, or being there at all.

---

From: Jacob Hoffman-Andrews <[email-masked]>
Date: Fri, 16 Sep 2016 17:19:55 -0700

> doing some sort of legal theatre lite where the client blindly sends

For better or for worse, there is some "legal theatre lite" required to
get a certificate in the Web PKI. The Baseline Requirements require it.
The question is: Do we automate it or do we not automate it?

> a hard coded "sure, whatever you say, whenever you say it" flag.

I am *not* proposing a "sure, whatever you say, whenever you say it"
flag. I am proposing that ACME only needs to know how to agree on terms
of service when creating an account. If the server later wants their
users to agree to new terms, that can be readily be implemented with
error codes and out-of-band URLs.

You are proposing that ACME specify not only initial agreement, but also
how to negotiate subsequent agreements. There is no need for this,
specifically because those subsequent agreements cannot be automated.
ACME is the Automated Certificate Management Environment. Why would we
include extra plumbing that can only be used manually?

> that indicates where the terms can be found

This exists, and is what my proposal is based on.

> without needing to kludge a contentless 'accept' bit into the protocol).

I understand this proposal is an unappealing compromise. I feel the same
way. I'd prefer to go all the way and remove explicit agreement to
terms. Unfortunately, the BRs don't seem compatible with this.

In another thread, Rich has asked if we are close to consensus. How
strong are your objections? Are you willing to join the CA/Browser Forum
as an Interested Party and propose the necessary change to the BRs?

Thanks,
Jacob

---

From: Ron <[email-masked]>
Date: Sat, 17 Sep 2016 18:38:29 +0930

> The question is: Do we automate it or do we not automate it?

And if the answer to that is "we do automate it", then the important
question is: Does this even remotely satisfy the actual requirement?

AIUI the CABF requirement is for an explicit agreement that is legally
binding to the end user in the applicable jurisdiction.

The problem you ran into with the existing system is that some (many?
all?) extant clients simply hardcoded:

 "agreement":"https://letsencrypt.org/documents/LE-SA-v1.0.1-July-27-2015.pdf"

into their source, without even looking at what the directory reported.
And that others required user intervention before performing the actions
to accept a changed ToS URL.

And the solution you are proposing to 'fix' that is for them to instead
hardcode "agreement":"yes", so that it still 'works' no matter what
random text is indicated in the directory at any point in time - and so
that doing it once implicitly agrees to any future ToS in advance.

Which is roughly equivalent to adding a line to my client software that
sends "btw":"You now agree to pay Ron One Beelion dollars tomorrow".

When the client blindly includes that in a protocol message without the
end user ever having seen it, you won't have to be a bookkeeper or lawyer
to correctly guess the chance of any court anywhere considering either
of those to form a binding contract.

Will it satisfy the CABF?  Who knows, they turn a blind eye to all sorts
of things that are inconvenient - but in terms of protocol design, it's
not any sort of mechanism that provides people options for meeting the
requirement, or for indicating what you are agreeing to.  It just says
you're generically agreeable to anything.  And doesn't give you a way
to post-facto query what it was that some employee of yours actually
agreed to on your company's behalf, possibly without your knowledge or
consent or permission or authorisation.

I would like to see a good way to fix the problem(s) you ran into in
practice when LE changed its ToS.  What I don't want to see is that
we try to fix what was a relatively simple client implementation bug
by using the protocol to mandate people implement something which is
fatally flawed and unfit for purpose from the outset - because it will
be harder and uglier to fix that later than if we just punted on this
and did nothing at all.

> include extra plumbing that can only be used manually?

I don't see how it could possibly be worse to have _one_ well specified
mechanism which is suitable for _both_ initial agreement and later
re-agreement if a CA decides that is necessary, that can be implemented
_once_ in the same client and server software?

One or both of us seems to be missing something in what the other is
saying or thinking here ...  since we seem to be in violent agreement
about the goal, but not about what might actually achieve it.

If the protocol was to remain as it presently is, where the server
declared the applicable ToS in the directory, and the client responds
with the explicit URL of what they have agreed to (and that becomes
state in the registration object) - then whether or not a change in
the ToS can be fully automated is *entirely* the decision of of the
client side.

Which IMO is as it should be.  The end user should be the one to
decide whether a 'blind' change to the ToS is acceptable to them
or not, not the service provider.

And all the client software needs to do to provide that choice is to
give the end user a configuration option that indicates whether or
not to automatically register acceptance if the ToS ever does change,
using the same protocol mechanism they used the first time.

Having already implemented this myself, I know that it works and
that it's possible :)

What you are suggesting is that I'd have to replace that with some
entirely unknown, and unspecified, and possibly different process
for every server that ever needed this.  So unless I'm missing some
key part of what you are saying, _that_ is the option which would
in fact be entirely impossible to automate.

> This exists, and is what my proposal is based on.

Sorry, maybe I wasn't clear there - I meant *only* provide the directory
entry, as a convenience to client software, so the user doesn't have to
hunt for it at some out of band location.  And make acceptance implicit
on proceeding with registration.

Which would have about as much legal weight as including a hidden
"I accept" constant in the protocol - would delete useless code like
you were advocating - and has a lot more precedent in existing practice
advocated by the lawyers of network service providers.

If that gets ruled invalid in a court, then a lot more than the CABF
contracts will fall down in a screaming heap.

> terms. Unfortunately, the BRs don't seem compatible with this.

And I understand (and sympathise with) the barrel you are over with this.
I realise you are looking for the simplest and most foolproof thing that
will satisfy the CABF BRs - but I'm having a hard time seeing how this
would even roughly achieve either of the technical or legal aims.

We'd still have useless cruft that people need to implement, in possibly
buggy ways, and it would have even less legal standing than what we
currently have for the purpose of meeting the BRs.

It's the sort of compromise that has us trying to share a cocktail
umbrella to keep us out of the rain.  It ties up one hand without
actually keeping anyone any drier, while I think we do have other
viable options here.

> as an Interested Party and propose the necessary change to the BRs?

I certainly don't want to be a curmudgeon standing in the way of
reaching a consensus here, and the only thing I really object to
with passion is "do something half-assed" - I could be just as happy
with either of "provide a real mechanism" or "excise this from the
ACME protocol entirely".  You said you'd talk to your legal folk
about whether they thought removing it was an option, and I don't
yet know for sure what the result of that was, which is why I
hadn't been pushing for one of those options over the other yet
and wanted to wait until we had more feedback again from you.

If proceeding with registration on its own constitutes explicit
acceptance regardless of the content of the protocol message which
does that, then I'd probably tip toward removing it.  If that's
somehow not enough, then I think we do need a real mechanism in
the protocol that has some chance of being flexible enough to work
across not only a range of legal jurisdictions and desired use
cases - but might also survive a change in interpretation of the
CABF too.

Even if you and I were to lobby the CABF for a change to their BRs,
or were to agree that we think an extra magic constant in the
protocol really would add any legal weight to satisfying them as
they are today - the opposite could also happen, that enough of
the CABF concludes that LE is an existential threat to them and
so tightens their rules in the other direction.  Or a court actually
rules that "no way is this sort of thing even remotely binding".

Which is why I think that for making decisions about the protocol,
we need to think less about "what is the absolute minimum we can
get away with for the current BRs" - and more about "do we actually
need a mechanism for this at all or not?".

If we do need it, it should be a real mechanism for maintaining
this as shared state between client and server.  If we don't,
we should get rid of it so that we do have a clean slate to add
a proper mechanism later if it ever does become needed and what
is needed becomes clearer.

The worst option I see is that we clutter the protocol now with
a lip-service policy decision that becomes a legacy wart stuck
on the side of whatever is actually needed to really solve this
problem.

I have a really hard time seeing how the magic constant string
that you proposed adding would have any more legal weight than
just saying in the RFC that "a protocol message with a curly
brace in it indicates acceptance of the terms of service".

I understand what you are _trying_ to do with that, but I think
a lot of people would have to pretend pretty hard for it to have
any substantial difference from the "do nothing" option beyond
being an additional (re)implementation burden.

If we can get past that somehow, we should be able to converge
on agreement about all this pretty quickly.

  Best,
  Ron

---

From: Alan Doherty <[email-masked]>
Date: Sun, 18 Sep 2016 06:14:01 +0100

sorry to drop in on thread
(i have no horse in this race but i think people may be speaking at crossed purposes here)

i think one is saying 
a ToS agreement phase after first setup of client (ie once human is gone and system is expected to autorenew every xx days all by itself)
cannot be done by client unattended (if offered via a default yes option, the whole agreement becomes legally void)

the other says if a client can ever do a legal ToS agreement it can be re-used to handle tos re-agreement

i think personally that this sort of ToS stuff like many systems could be moved out of protocol without much de-hooking
example scenario

client initial setup tos agreement

client starts account setup
client receives a CA requires oob information to continue url (unique url for this instance)
client displays url to user performing setup as an error, and pauses* till user indicates oob actions performed

user opens url in browser, reads and agrees to ToS and/or any other extra conditions CA specifies
server marks conditions met in its session/db/backend/whatever

client is resumed, checks servers updated status and continues 
or 
if user failed to perform the oob stuff
client receives a CA requires oob information to continue url (unique url for this instance)
client displays url to user performing setup, and pauses till user indicates oob actions performed

other scenario, CA updates its ToS and requires all users to re-confirm rather than the usual (continuing to use service after xxx date imply consent (facebook et al))

client begins its normal automated unattended renewal (with a few days to spare we hope)
client receives a CA requires oob information to continue url (unique url for this instance)
client displays url to user via error message in email/cron/log/whetever

user hopefully monitoring for failure errors visits url and performs actions
and either manually restarts client, or client cron job smart enough to see yesterdays didnt get renewed cert try again

extra scenario CA in obscure territory where its required to have a photo-id on file for all customers because of some crazy local law(new)
client begins its normal automated unattended renewal (with a few days to spare we hope) or setup
client receives a CA requires oob information to continue url (unique url for this instance)
client displays url to user via error message in email/cron/log/whetever or interactively if user doing setup

*paused

could be an interactive pause 
or 
an actual exit with state saved to a location so on next run it can resume from this point (cleaner)

the CA requires oob information/process/agreement message could be sent to client as an error/code with the extra fields of "ca's explanation text" "url"

so ca could send for example
"ToS agreement needed via visiting this page"   "https://www.obscure-ca.org/ToS/?client-id=abnfX5679"
"confirmation of address details required to setup an account"  "https://www.obsure-co.org/signup/?client-id=abnfX5679"

but either way it takes tos and many other bits required for say EV vs non-EV certs out of acme while still allowing acme to work for/with CAs with requirements beyond just authenticating the domains and providing the certs

just my 2 cents

---

From: Jeremy Rowley <[email-masked]>
Date: Mon, 19 Sep 2016 15:43:14 +0000

For the record, the CAB Forum doesn't police anything and thus can't "turn a
blind eye" to any action. Whether a CA fulfills a give requirement is in the
discretion of the browser implementing the CAB Forum BRs, the auditor
providing the attestation of compliance and the CA.

That said, I think there are many CAs interested in complying with both the
spirit and letter of the CAB Forum requirements while also using ACME.
Therefore, if ACME truly is CA agnostic, an automated ToS presentation
should permit a meaningful, binding experience. 

-----Original Message-----
From: Acme [mailto:[email-masked]] On Behalf Of Ron
Sent: Saturday, September 17, 2016 3:08 AM
To: Jacob Hoffman-Andrews <[email-masked]>
Cc: [email-masked]
Subject: Re: [Acme] Simplifying ToS agreement

On Fri, Sep 16, 2016 at 05:19:55PM -0700, Jacob Hoffman-Andrews wrote:
> For better or for worse, there is some "legal theatre lite" required 
> to get a certificate in the Web PKI. The Baseline Requirements require it.

"agreement":"https://letsencrypt.org/documents/LE-SA-v1.0.1-July-27-2015.pdf
"

into their source, without even looking at what the directory reported.
And that others required user intervention before performing the actions to
accept a changed ToS URL.

And the solution you are proposing to 'fix' that is for them to instead
hardcode "agreement":"yes", so that it still 'works' no matter what random
text is indicated in the directory at any point in time - and so that doing
it once implicitly agrees to any future ToS in advance.

When the client blindly includes that in a protocol message without the end
user ever having seen it, you won't have to be a bookkeeper or lawyer to
correctly guess the chance of any court anywhere considering either of those
to form a binding contract.

Will it satisfy the CABF?  Who knows, they turn a blind eye to all sorts of
things that are inconvenient - but in terms of protocol design, it's not any
sort of mechanism that provides people options for meeting the requirement,
or for indicating what you are agreeing to.  It just says you're generically
agreeable to anything.  And doesn't give you a way to post-facto query what
it was that some employee of yours actually agreed to on your company's
behalf, possibly without your knowledge or consent or permission or
authorisation.

I would like to see a good way to fix the problem(s) you ran into in
practice when LE changed its ToS.  What I don't want to see is that we try
to fix what was a relatively simple client implementation bug by using the
protocol to mandate people implement something which is fatally flawed and
unfit for purpose from the outset - because it will be harder and uglier to
fix that later than if we just punted on this and did nothing at all.

> flag. I am proposing that ACME only needs to know how to agree on 
> terms of service when creating an account. If the server later wants 
> their users to agree to new terms, that can be readily be implemented 
> with error codes and out-of-band URLs.
> 
> You are proposing that ACME specify not only initial agreement, but 
> also how to negotiate subsequent agreements. There is no need for 
> this, specifically because those subsequent agreements cannot be
automated.

One or both of us seems to be missing something in what the other is saying
or thinking here ...  since we seem to be in violent agreement about the
goal, but not about what might actually achieve it.

If the protocol was to remain as it presently is, where the server declared
the applicable ToS in the directory, and the client responds with the
explicit URL of what they have agreed to (and that becomes state in the
registration object) - then whether or not a change in the ToS can be fully
automated is *entirely* the decision of of the client side.

Which IMO is as it should be.  The end user should be the one to decide
whether a 'blind' change to the ToS is acceptable to them or not, not the
service provider.

And all the client software needs to do to provide that choice is to give
the end user a configuration option that indicates whether or not to
automatically register acceptance if the ToS ever does change, using the
same protocol mechanism they used the first time.

Having already implemented this myself, I know that it works and that it's
possible :)

What you are suggesting is that I'd have to replace that with some entirely
unknown, and unspecified, and possibly different process for every server
that ever needed this.  So unless I'm missing some key part of what you are
saying, _that_ is the option which would in fact be entirely impossible to
automate.

> > We could just provide a directory entry (which could even be 
> > optional) that indicates where the terms can be found
> 

Sorry, maybe I wasn't clear there - I meant *only* provide the directory
entry, as a convenience to client software, so the user doesn't have to hunt
for it at some out of band location.  And make acceptance implicit on
proceeding with registration.

Which would have about as much legal weight as including a hidden "I accept"
constant in the protocol - would delete useless code like you were
advocating - and has a lot more precedent in existing practice advocated by
the lawyers of network service providers.

> > that any other use of the service indicates acceptance of those 
> > terms (just like pretty much every other network service in 
> > existence does without needing to kludge a contentless 'accept' bit into
the protocol).
> 
> I understand this proposal is an unappealing compromise. I feel the 
> same way. I'd prefer to go all the way and remove explicit agreement 
> to terms. Unfortunately, the BRs don't seem compatible with this.

And I understand (and sympathise with) the barrel you are over with this.
I realise you are looking for the simplest and most foolproof thing that
will satisfy the CABF BRs - but I'm having a hard time seeing how this would
even roughly achieve either of the technical or legal aims.

It's the sort of compromise that has us trying to share a cocktail umbrella
to keep us out of the rain.  It ties up one hand without actually keeping
anyone any drier, while I think we do have other viable options here.

> strong are your objections? Are you willing to join the CA/Browser 
> Forum as an Interested Party and propose the necessary change to the BRs?

I certainly don't want to be a curmudgeon standing in the way of reaching a
consensus here, and the only thing I really object to with passion is "do
something half-assed" - I could be just as happy with either of "provide a
real mechanism" or "excise this from the ACME protocol entirely".  You said
you'd talk to your legal folk about whether they thought removing it was an
option, and I don't yet know for sure what the result of that was, which is
why I hadn't been pushing for one of those options over the other yet and
wanted to wait until we had more feedback again from you.

If proceeding with registration on its own constitutes explicit acceptance
regardless of the content of the protocol message which does that, then I'd
probably tip toward removing it.  If that's somehow not enough, then I think
we do need a real mechanism in the protocol that has some chance of being
flexible enough to work across not only a range of legal jurisdictions and
desired use cases - but might also survive a change in interpretation of the
CABF too.

Even if you and I were to lobby the CABF for a change to their BRs, or were
to agree that we think an extra magic constant in the protocol really would
add any legal weight to satisfying them as they are today - the opposite
could also happen, that enough of the CABF concludes that LE is an
existential threat to them and so tightens their rules in the other
direction.  Or a court actually rules that "no way is this sort of thing
even remotely binding".

Which is why I think that for making decisions about the protocol, we need
to think less about "what is the absolute minimum we can get away with for
the current BRs" - and more about "do we actually need a mechanism for this
at all or not?".

If we do need it, it should be a real mechanism for maintaining this as
shared state between client and server.  If we don't, we should get rid of
it so that we do have a clean slate to add a proper mechanism later if it
ever does become needed and what is needed becomes clearer.

The worst option I see is that we clutter the protocol now with a
lip-service policy decision that becomes a legacy wart stuck on the side of
whatever is actually needed to really solve this problem.

I have a really hard time seeing how the magic constant string that you
proposed adding would have any more legal weight than just saying in the RFC
that "a protocol message with a curly brace in it indicates acceptance of
the terms of service".

I understand what you are _trying_ to do with that, but I think a lot of
people would have to pretend pretty hard for it to have any substantial
difference from the "do nothing" option beyond being an additional
(re)implementation burden.

If we can get past that somehow, we should be able to converge on agreement
about all this pretty quickly.

  Best,
  Ron

---

From: Ron <[email-masked]>
Date: Tue, 20 Sep 2016 05:20:01 +0930

> providing the attestation of compliance and the CA.

Sorry.  What I really meant there was a more general "people" rather
than a j'accuse "they".  It really is a hard problem if you remove
"I know it when I see it" as an overriding principle.

> should permit a meaningful, binding experience.

That is exactly the assumption I'm interested in from the protocol design
standpoint though.

The key question for me is whether "you registered an account and used
the service, ergo you accept the ToS we presented, in a binding way" can
comply with the accepted spirit and letter of those requirements.

Certainly a lot of lawyers for other network services consider them
binding.  And if they aren't there's a whole lot of ToS documents out
there which have no force at all.

If that holds, it would let us simplify the protocol notably, and
possibly puts the acceptance into more well trodden legal territory
than if we invent something novel for that for ACME.

---

From: Jeremy Rowley <[email-masked]>
Date: Mon, 19 Sep 2016 20:49:23 +0000

>From our perspective (as a potential ACME adopter), we'll accept a click
through as valid if the user is presented the T&Cs or at least given a link
and option to accept them. I'd support automation as long as the user could
at least retrieve the terms at some point and indicate acceptance.

-----Original Message-----
From: Acme [mailto:[email-masked]] On Behalf Of Ron
Sent: Monday, September 19, 2016 1:50 PM
To: Jeremy Rowley <[email-masked]>
Cc: [email-masked]; Jacob Hoffman-Andrews <[email-masked]>
Subject: Re: [Acme] Simplifying ToS agreement

On Mon, Sep 19, 2016 at 03:43:14PM +0000, Jeremy Rowley wrote:
> For the record, the CAB Forum doesn't police anything and thus can't 
> "turn a blind eye" to any action. Whether a CA fulfills a give 
> requirement is in the discretion of the browser implementing the CAB 
> Forum BRs, the auditor providing the attestation of compliance and the CA.

Sorry.  What I really meant there was a more general "people" rather than a
j'accuse "they".  It really is a hard problem if you remove "I know it when
I see it" as an overriding principle.

> That said, I think there are many CAs interested in complying with 
> both the spirit and letter of the CAB Forum requirements while also using
ACME.

The key question for me is whether "you registered an account and used the
service, ergo you accept the ToS we presented, in a binding way" can comply
with the accepted spirit and letter of those requirements.

Certainly a lot of lawyers for other network services consider them binding.
And if they aren't there's a whole lot of ToS documents out there which have
no force at all.

If that holds, it would let us simplify the protocol notably, and possibly
puts the acceptance into more well trodden legal territory than if we invent
something novel for that for ACME.

> And that others required user intervention before performing the 
> actions to accept a changed ToS URL.
> 
> And the solution you are proposing to 'fix' that is for them to 
> instead hardcode "agreement":"yes", so that it still 'works' no matter 
> what random text is indicated in the directory at any point in time - 
> and so that doing it once implicitly agrees to any future ToS in advance.
> 
> Which is roughly equivalent to adding a line to my client software 
> that sends "btw":"You now agree to pay Ron One Beelion dollars tomorrow".
> 
> When the client blindly includes that in a protocol message without 
> the end user ever having seen it, you won't have to be a bookkeeper or 
> lawyer to correctly guess the chance of any court anywhere considering 
> either of those to form a binding contract.
> 
> 
> Will it satisfy the CABF?  Who knows, they turn a blind eye to all 
> sorts of things that are inconvenient - but in terms of protocol 
> design, it's not any sort of mechanism that provides people options 
> for meeting the requirement, or for indicating what you are agreeing 
> to.  It just says you're generically agreeable to anything.  And 
> doesn't give you a way to post-facto query what it was that some 
> employee of yours actually agreed to on your company's behalf, 
> possibly without your knowledge or consent or permission or authorisation.
> 
> 
> practice when LE changed its ToS.  What I don't want to see is that we 
> try to fix what was a relatively simple client implementation bug by 
> using the protocol to mandate people implement something which is 
> be harder and uglier to fix that later than if we just punted on this and
did nothing at all.
> > their users to agree to new terms, that can be readily be 
> > implemented with error codes and out-of-band URLs.
> > 
> > ACME is the Automated Certificate Management Environment. Why would 
> > we include extra plumbing that can only be used manually?
> 
> I don't see how it could possibly be worse to have _one_ well 
> specified mechanism which is suitable for _both_ initial agreement and 
> later re-agreement if a CA decides that is necessary, that can be 
> implemented _once_ in the same client and server software?
> 
> the ToS can be fully automated is *entirely* the decision of of the client
side.
> decide whether a 'blind' change to the ToS is acceptable to them or 
> not, not the service provider.
> 
> give the end user a configuration option that indicates whether or not 
> to automatically register acceptance if the ToS ever does change, 
> Having already implemented this myself, I know that it works and that 
> it's possible :)
> 
> entirely unknown, and unspecified, and possibly different process for 
> every server that ever needed this.  So unless I'm missing some key 
> part of what you are saying, _that_ is the option which would in fact 
> be entirely impossible to automate.
> 
> 
> 
> Sorry, maybe I wasn't clear there - I meant *only* provide the 
> directory entry, as a convenience to client software, so the user 
> doesn't have to hunt for it at some out of band location.  And make 
> acceptance implicit on proceeding with registration.
> 
> advocating - and has a lot more precedent in existing practice 
> I realise you are looking for the simplest and most foolproof thing 
> that will satisfy the CABF BRs - but I'm having a hard time seeing how 
> this would even roughly achieve either of the technical or legal aims.
> 
> We'd still have useless cruft that people need to implement, in 
> possibly buggy ways, and it would have even less legal standing than 
> what we currently have for the purpose of meeting the BRs.
> 
> actually keeping anyone any drier, while I think we do have other viable
options here.
> reaching a consensus here, and the only thing I really object to with 
> passion is "do something half-assed" - I could be just as happy with 
> either of "provide a real mechanism" or "excise this from the ACME 
> protocol entirely".  You said you'd talk to your legal folk about 
> whether they thought removing it was an option, and I don't yet know 
> for sure what the result of that was, which is why I hadn't been 
> pushing for one of those options over the other yet and wanted to wait
until we had more feedback again from you.
> somehow not enough, then I think we do need a real mechanism in the 
> protocol that has some chance of being flexible enough to work across 
> not only a range of legal jurisdictions and desired use cases - but 
> might also survive a change in interpretation of the CABF too.
> 
> Even if you and I were to lobby the CABF for a change to their BRs, or 
> were to agree that we think an extra magic constant in the protocol 
> really would add any legal weight to satisfying them as they are today 
> - the opposite could also happen, that enough of the CABF concludes 
> that LE is an existential threat to them and so tightens their rules 
> in the other direction.  Or a court actually rules that "no way is 
> this sort of thing even remotely binding".
> 
> 
> Which is why I think that for making decisions about the protocol, we 
> need to think less about "what is the absolute minimum we can get away 
> with for the current BRs" - and more about "do we actually need a 
> mechanism for this at all or not?".
> 
> If we do need it, it should be a real mechanism for maintaining this 
> as shared state between client and server.  If we don't, we should get 
> rid of it so that we do have a clean slate to add a proper mechanism 
> later if it ever does become needed and what is needed becomes clearer.
> 
> lip-service policy decision that becomes a legacy wart stuck on the 
> side of whatever is actually needed to really solve this problem.
> 
> 
> I have a really hard time seeing how the magic constant string that 
> you proposed adding would have any more legal weight than just saying 
> in the RFC that "a protocol message with a curly brace in it indicates 
> acceptance of the terms of service".
> 
> I understand what you are _trying_ to do with that, but I think a lot 
> of people would have to pretend pretty hard for it to have any 
> substantial difference from the "do nothing" option beyond being an 
> additional (re)implementation burden.
> 
> If we can get past that somehow, we should be able to converge on 
> agreement about all this pretty quickly.
> 
>   Best,
>   Ron
> 
>

---

From: Jacob Hoffman-Andrews <[email-masked]>
Date: Mon, 19 Sep 2016 17:52:34 -0700

> question is: Does this even remotely satisfy the actual requirement?
IANAL, but the feedback we've gotten so far is it is reasonable for
someone to agree to terms of service through an API.

There are a lot of philosophical issues of what it means to signal
agreement via an API, since we don't ultimately control all the clients
that get written. It will always be possible for someone to write code
that auto-agrees to certain terms of service. Such software may even be
written in good faith. For instance, if you've read the terms of
service, and want to install software on hundreds of machines that
agrees to those terms, the software doesn't need to prompt you every time.

However, having to be explicit about the agreement, whether through a
flag or a URL, means that the client author is more likely to at least
make an explicit decision about how and when to present the terms of
service to the user.

> that doing it once implicitly agrees to any future ToS in advance.
I think this may be where we are not understanding each other. This is
not the main problem I am trying to fix. I'm trying to fix:

 1. Registration is a two-step process, when it only needs to be one.
 2. Accounts can be created without agreeing to terms, which creates an
unnecessary indeterminate state.
 3. The protocol hints at the idea that the client could post new terms
of service URLs to the registration object, without specifying anything
about when it is permissible, when it is required, or what actions the
server should take on update.
 4. Similarly, the protocol doesn't make clear whether the server should
automatically update the terms of service URL stored in the registration
object.

Some of the problems we saw:
 - Clients that expected the terms of service URL in existing
registration objects to match the current directory, and failing if not.
 - Clients attempting to POST the new terms of service URL to update
their registration object, even though that was unnecessary and
unsupported by Boulder at the time. We added support to un-break these
clients.

Very specifically, I am trying to make life easier for clients that
hardcode the agreement URL. I am proposing it because it removes parts
of the protocol that are unnecessary and have proven to be confusing.
> be harder and uglier to fix that later than if we just punted on this
"Do nothing" is not an option. We need to either decide on new logic for
(3) and (4), and add that to the spec, along with all the attendant
complexity, or we can adopt the simpler agreement protocol that I am
proposing.

---

From: Hugo Landau <[email-masked]>
Date: Sun, 25 Sep 2016 02:03:21 +0100

I think the TOS URI mechanism should be preserved, and the specification
should be changed to state that if no new act of assent is required,
the URI stored in a registration should be updated to match it
automatically.

> unnecessary indeterminate state.
Agreed; fixing this seems desirable.

> automatically update the terms of service URL stored in the registration
My reading of the -02 spec is that a client must resubmit assent with
the new URI if it ceases to match the advertised URI.

> unsupported by Boulder at the time. We added support to un-break these
I certainly think not accepting agreement update would have been out of
compliance, even if it was actually unnecessary:

  If the server wishes to present the client with terms under which the
  ACME service is to be used, it MUST indicate the URI where such terms
  can be accessed in a Link header with link relation "terms-of- service".
  As noted above, the client may indicate its agreement with these terms
  by updating its registration to include the "agreement" field, with the
  terms URI as its value.  When these terms change in a way that requires
  an agreement update, the server MUST use a different URI in the Link
  header.

> hardcode the agreement URL.
How can hardcoding the URL ever be legitimate?

You've also mentioned that agreement URI updates can never be automated,
so having an in-band mechanism for agreement *update* (as opposed to
initial assent at registration time) is pointless, but this isn't true.
If a client user is informed of a new URI before it is deployed via an
out-of-band channel, they may be able to configure their clients ahead
of time to recognise and assent to it whenever they do see it. This
could be automated if a large number of client instances are used; the
only non-automatable work is a per-URI human-triggered approval.

---

From: Ron <[email-masked]>
Date: Mon, 26 Sep 2016 03:02:01 +0930

> the URI stored in a registration should be updated to match it

I'm inclined to think that the registration object should always reflect
what was explicitly accepted, and not be updated without a new explicit
assent being sent.

I don't see a problem with having the directory show that the current
ToS is "version 3", and the registration object show that explicit
assent was obtained for "version 1", and leaving it up to the legal
acrobatics in the text of version 1 to say that explicit assent isn't
required for the "or later version" terms to apply automatically at
some point in time.

The registration object should be a record of what was most recently
explicitly accepted if it's to play the part of the legally binding
bit of a contract agreement.  Changing it would be like someone else
pasting my signature onto a different document (as opposed to saying
that the document I originally signed allows parts of it to be updated
without explicit assent in the future if required).

> Agreed; fixing this seems desirable.

Yes, but this was an issue with Boulder's implementation, not the
protocol per-se.  I personally found it surprising that it allowed
this, but the protocol didn't force it to[1] - it could have refused
any new-reg request without an acceptance instead of just disallowing
later operations until one was received.

There were at least some clients that were submitting the acceptance
with the initial new-reg request.

[1] or if it did in some clause I'm forgetting, that wasn't fundamental
    to the mechanism employed and could be fixed without changing the
    existing mechanism in any way.

  Ron

---

From: Hugo Landau <[email-masked]>
Date: Mon, 26 Sep 2016 05:53:26 +0100

> required for the "or later version" terms to apply automatically at
In this case a client should have some way to determine if explicit
re-agreement is required. An "agreement-valid": bool field would
suffice for this.

> with the initial new-reg request.
Fairly sure the only way to determine the ToS URI is by registering
first so you can get it from the Link header. The ToS URI still isn't
available in boulder's directory:
  https://acme-v01.api.letsencrypt.org/directory

So if any clients were submitting the ToS URI they must have been
hardcoding it, which is a terrible practice.

---

From: Ron <[email-masked]>
Date: Mon, 26 Sep 2016 15:21:15 +0930

> re-agreement is required. An "agreement-valid": bool field would

Or just a suitable error code returned for the operation that actually
failed?  Since that won't likely be a query of the registration object,
it's more likely to be noticed when a cert renewal is requested if the
server won't honor that without re-agreement.

>   https://acme-v01.api.letsencrypt.org/directory

Ah yes, you're correct about that.  I even have a very special warning
in my code for the case where a user passes --accept-tos when it hasn't
yet been seen, to cover the case of current Boulder.

I do cache it on a per-CA basis though, so that would work if you'd
registered at least one account previously and the ToS hadn't changed.
(it's cached precisely so that the user can be warned if/when it does
ever change).

Unless I've forgotten something else, it is still a glitch in Boulder
rather than the protocol spec though.

> hardcoding it, which is a terrible practice.

At least one (very popular one) definitely was/is, and yes it is.

I didn't start writing a client of my own because I thought Good
Practice (for my use case) was already a solved problem :)

---

From: Hugo Landau <[email-masked]>
Date: Mon, 26 Sep 2016 14:48:34 +0100

> server won't honor that without re-agreement.
I think both should be done. But, separately, it should be possible to
determine the usability of a registration object, ToS-wise, though,
without making requests just to see if they return errors.

---

From: Jacob Hoffman-Andrews <[email-masked]>
Date: Mon, 26 Sep 2016 18:40:41 -0700

> How can hardcoding the URL ever be legitimate?

Sorry, this was one of those worst-case typos. It should have read:
"Very specifically, I am *not* trying to make life easier for clients
that hardcode the agreement URL." I agree that that's not legitimate.

> only non-automatable work is a per-URI human-triggered approval.

The most likely out-of-band channel is email, right? So the CA would
send out email informing their customers that there's a new ToS, and the
customer needs to explicitly agree to it in the next N days, or they
will be unable to use the service.

There are a couple of options the CA could ask their customer to do for
the next step:

 a) Click a link in the email, read the new ToS, and click "Agree" at
the bottom.
 b) Click a link in the email, read the new ToS, and copy and paste the
new ToS URL into the customer's ACME client config.

I think (a) is both more user-friendly and more likely to be what a CA
would actually implement.

---

From: Hugo Landau <[email-masked]>
Date: Tue, 27 Sep 2016 06:13:17 +0100

> would actually implement.
I agree that (a) would make sense for many users. However, providing an
e. mail address is not mandatory, and (b) is more automatable anyway. So
I'd expect most users to use (a) and users with large deployments or no
e. mail address registered to at least be able to use (b) if they
wanted.

---

From: Ron <[email-masked]>
Date: Tue, 27 Sep 2016 15:06:22 +0930

> e. mail address registered to at least be able to use (b) if they

And then there's the little question of emailing a few billion users vs'
setting a notification bit in a response when they next connect to the
service ...  assuming we want this to be ubiquitous and scalable.

---

From: Jacob Hoffman-Andrews <[email-masked]>
Date: Mon, 26 Sep 2016 22:55:46 -0700

> e. mail address registered to at least be able to use (b) if they
The notion generalizes to any out-of-band communication, whether it's
email, SMS, RSS, or carrier pigeon. If there's some out-of-band way for
the CA to communicate with its users, they can just provide a link to a
page where the user can agree to the new ToS.

On 09/26/2016 10:36 PM, Ron wrote:
> And then there's the little question of emailing a few billion users
> vs' setting a notification bit in a response when they next connect to
> the service ... assuming we want this to be ubiquitous and scalable.
I expect that the total Subscribers using ACME will number in the low
millions, not billions. And the capacity to email all of one's customers
is not generally a problem for even the largest services.

---

From: Hugo Landau <[email-masked]>
Date: Tue, 27 Sep 2016 08:17:32 +0100

> page where the user can agree to the new ToS.
But right now you can use Let's Encrypt without providing any means of
out-of-band communication, so it's not safe to assume that such a
mechanism — e. mail or otherwise — will be available.

You mention RSS, but that requires a web interface to have some way of
tying assent to a registration, which would require users to do special
and unusual things with their registration private key to prove they
hold it.

RSS becomes viable if combined with option b, where users can configure
their clients to assent to a new agreement in advance.

Or are you talking about cases where no new assent is required? I'm
arguing that both cases should be covered.

---

From: Jeremy Rowley <[email-masked]>
Date: Tue, 27 Sep 2016 17:00:36 +0000

Why not allow both? We'd use (a) over (b), but if email isn't required, then
(b) is certainly an acceptable method of confirming ToS acceptance.

-----Original Message-----
From: Acme [mailto:[email-masked]] On Behalf Of Hugo Landau
Sent: Monday, September 26, 2016 11:13 PM
To: Jacob Hoffman-Andrews <[email-masked]>
Cc: [email-masked]
Subject: Re: [Acme] Simplifying ToS agreement

> send out email informing their customers that there's a new ToS, and 
> the customer needs to explicitly agree to it in the next N days, or 
> they will be unable to use the service.
> 
> There are a couple of options the CA could ask their customer to do 
> for the next step:
> 
>  b) Click a link in the email, read the new ToS, and copy and paste 
> the new ToS URL into the customer's ACME client config.
> 
I agree that (a) would make sense for many users. However, providing an e.
mail address is not mandatory, and (b) is more automatable anyway. So I'd
expect most users to use (a) and users with large deployments or no e. mail
address registered to at least be able to use (b) if they wanted.

---

From: Jacob Hoffman-Andrews <[email-masked]>
Date: Thu, 29 Sep 2016 17:47:35 -0700

> mechanism — e. mail or otherwise — will be available.

This is exactly why we chose to write our Subscriber agreement such that
we can update without explicit opt-in.

> and unusual things with their registration private key to prove they

RSS is an extreme edge case of an edge case. We're imagining a CA that
require explicit assent to changes in the ToS, and additionally does not
require an email address for its customers, but *does* offer an RSS feed
for notifications about updates to their ToS. Even in such an edge case
of an edge case, they could create an individualized RSS URL for each
customer.

the bottom.
> (b) is certainly an acceptable method of confirming ToS acceptance.

Because no one will use (b), and it adds unnecessary complexity and
fragility to the protocol.

To further emphasize my point that "it will never be used," here are
some other examples of CA ToS:

-------------------------
https://www.symantec.com/content/en/us/about/media/repository/ssl-subscriber-agreement.pdf

Company may revise the terms of this Agreement at any time for the
following reasons: (i) it becomes necessary due to applicable laws or
industry standards, including, without limitation, any change of the
foregoing; (ii) it becomes necessary for technological reasons when any
changes is made without materially degrading the Service functionality;
(iii) it becomes necessary to maintain the operation of the Service when
any change is made without materially degrading the Service
functionality; or (iv) changes are in favor of the Subscriber. Any such
change will be binding and effective thirty (30) days after publication
of the change on Symantec’s website, or upon notification to Subscriber
by email.

-------------------------
https://www.digicert.com/docs/agreements/DigiCert_SA.pdf

DigiCert may amend any of its (i) website and any documents listed
thereon, (ii) CPS, (iii) fees, (iv) privacy policy, or (iv) the
conditions under which you receive a Certificate.  Amendments are
effective upon the earlier of DigiCert’s posting the amendment on its
website or your receipt of the amendment.

-------------------------
https://www.comodo.com/repository/docs/ssl_certificate_subscriber_agreement.pdf

Comodo may amend this agreement, the CPS, the Relying Party Agreement,
the Relying Party Warranty, its website, and any documents listed in its
Repository at any time by posting either the amendment or the amended
document in the Repository.  Subscriber shall periodically review the
Repository to be aware of any changes. Subscriber may terminate the
agreement if Subscriber does not agree to the amendment. Subscriber’s
continued use of the Services after an amendment is posted constitutes
Subscriber’s acceptance of the amendment.
-------------------------

It should be clear from these examples that effectively the entire CA
industry, like the entire Web industry, and indeed corporations in
general, rely on auto-updating terms of service. As I said in my initial
post on this topic, I think that's not a great. But pretending it's not
so, or trying to litigate that broad policy problem in a spec for
automating certificate issuance is both ineffective and worsens the
protocol.