Historically, the way ACME has handled this use case is through External Account Binding. On the one hand, this mechanism fits your desired use-case well: the client can prove something to the server completely out-of-band, and the server can then decide whether or not to honor this particular certificate request based on that information. On the other hand, this is a cop-out: EAB is wholly unspecified, and obviously the point of this draft is to create an in-protocol interoperable standard for how to do these proofs. So I think we agree that suggesting this draft should use EAB is not the right direction to go.
Fundamentally, I think that ACME's *Authorization* flow fits this use-case perfectly. The ACME Server should attach one or more Authorizations to the order, and require the client to fulfill a challenge for each of them before it is willing to finalize the order. The difficulty is that, per RFC 8555, Authorizations can only represent an *Identifier*, and it's unclear what the identifier in this case would be. The definition of "Identifier" is woefully vague. There's no proper definition within the document itself; the term is only defined by inference. There's not even a standalone Identifier struct, it's only defined (redundantly!) as a sub-object within the Order and Authorization objects. Various gestures as definitions include "[something] that the account is authorized to represent" and something that the client can "prove possession of". Both of those are uselessly vague. The only other indication of what an Identifier can or cannot be comes from Section 7.4, which says that "The CSR MUST indicate the exact same set of requested identifiers as the initial newOrder request" and "Specifications that define new identifier types must specify where in the certificate signing request these identifiers can appear", suggesting that Identifiers must be things that are representable within a certificate. I see two usable "loopholes" here: 1. Section 7.4 only says that the CSR has to match the *requested* identifiers -- if the server added an extra RATS Authorization to the order due to server policy, the client is under no obligation to include the corresponding Identifier in the CSR. (And I want to make the Finalize CSR optional, anyway.) 2. As I mentioned in my first email, I think that RATS attestations could be represented in a certificate by Certificate Policy OIDs. I think the most straightforward approach here is to define a new Identifier type, and to spell out exactly how it is (or isn't! either way, up to you) encoded within the resulting certificate. Then say that ACME Servers MAY add an authorization for this Identifier type to any order they way, per server policy. Finally, define the challenges which can be used to validate Authorizations for this identifier type. I think that, as long as the draft is explicitly clear about what the new identifier type semantically represents, and how it is (or is not) encoded in the certificate, everything will be hunky dory. Aaron On Tue, Jul 22, 2025 at 11:43 AM Mike Ounsworth <[email protected]> wrote: > Hi Aaron, > > Right, so until today, I thought that the ACME Challenges were about > proving ownership of an identifier. If the ACME WG is ok with broadening > Challenges to other things, then our usecase fits right in and Challenges > would be the right place. > > > > I *believe* that the reason the design team has gone in this direction > is because the rats identifier does not appear in the final issued > certificate. Is that correct? > > So let's run this use-case: You want to enroll your phone for a corporate > S/MIME cert over ACME. You do the usual "email-reply-00" Challenge as > specified in RFC 8823, but ALSO the ACME server wants you to prove that you > are running the latest Windows patch and the corp anti-virus, for which it > wants a RATS attestation. The point of the attestation is about proving the > state of the device, and has nothing at all to do with device identifiers. > The other technical challenge we ran into is that 8555 only requires the > client to respond to ONE challenge. This is fundamental to ACME and as far > as we can tell, there is no way to say "Please do one of {http-01, dns-01} > AND {device-attest-02}. This is why we moved this to the /new-order, /order. > > TL;DR: ACME is fundamentally about identifiers that go into certs. We > (much like Kathleen's draft) are trying to do something in ACME that has > absolutely nothing to do with identifiers that go into the cert; but rather > about authorizing the whole cert issuance in the first place. > > > > On Tue, 22 Jul 2025 at 07:43, Aaron Gable <aaron= > [email protected]> wrote: > >> In the wake of the rushed IETF 123 meeting, I wanted to start a >> conversation here about the ACME RATS draft. I have a few thoughts, some >> large, some small, presented below in no particular order. >> >> --- >> >> The presentation said that the design team had come to the conclusion >> that the attestation evidence should be presented in the newOrder request, >> rather than as a traditional challenge. This design decision does not seem >> to be reflected in the current draft >> <https://www.ietf.org/archive/id/draft-liu-acme-rats-01.html>. nor in >> the main branch of the github repo >> <https://github.com/liuchunchi/draft-liu-acme-rats/blob/main/draft-liu-acme-rats.md>. >> Therefore I feel somewhat underprepared to discuss this design proposal in >> detail. >> >> That said, my gut reaction is that it is a bad idea. The beauty of ACME, >> in my opinion, is that it has an infinitely extensible collection of >> identifier types, and an infinitely extensible collection of challenges to >> validate those identifiers. If the thing that is semantically happening is >> that the server is validating a claim that the client is making, that >> should almost certainly take place as part of the existing extensible >> identifier/authorization/challenge mechanism, not get bolted on elsewhere >> in the protocol. >> >> I *believe* that the reason the design team has gone in this direction >> is because the rats identifier does not appear in the final issued >> certificate. Is that correct? >> >> If yes, *why* does no corresponding identifier appear in the cert? If >> the CA is enforcing that certain policies be met, then can't that be >> represented by a Certificate Policies extension? And then you're in an even >> better place, since enterprise clients can enforce that the specific >> Certificate Policy OID be present before they trust a cert. >> >> I'm imagining a world where the flow looks like this: >> 1. Enterprise client requests a new order for internal.tld >> 2. Enterprise CA says "sure, but only if you're up-to-date", and creates >> an order with two identifiers: >> a. {"type": "dns", "value": "internal.tld"} >> b. {"type": "policy", "value": "1.2.3.4.5"} (created by server policy, >> not because client requested it) >> 3. Enterprise CA creates a corresponding authorization object, too, with >> the same "policy"-type identifier, and two "rats-01" and "rats-02" >> challenges, representing different ways the client can prove that it >> complies with the policy. >> 4. The client fulfills one of the challenges, and the authorization gets >> marked as valid. >> 5. The CA issues the cert, and includes OID 1.2.3.4.5 in the Certificate >> Policies extension >> >> --- >> >> Regarding Q Misell's statement that RFC 8555 technically allows a server >> to require multiple challenges for a single authorization: the exact quote >> from Section 7.1.4 >> <https://datatracker.ietf.org/doc/html/rfc8555#section-7.1.4>, in the >> description of the `challenges` field, is: >> Each array entry is an >> object with parameters required to validate the challenge. A >> client should attempt to fulfill one of these challenges, and a >> server should consider any one of the challenges sufficient to >> make the authorization valid. >> There's a similar statement later in Section 7.5.1 >> <https://datatracker.ietf.org/doc/html/rfc8555#autoid-39>, which says >> The server is said to "finalize" the authorization when it has >> completed one of the validations. >> >> So I at least partially agree that it's acceptable for a server to >> require two different challenges to be fulfilled on a single authorization >> before it considers that authorization valid. However, I think doing this >> in practice would break virtually every ACME client in existence. In >> particular, most clients have very simple heuristics for selecting which >> challenge to fulfill on an authorization. I expect that, if a server >> accepted a challenge validation attempt but *didn't* mark the >> corresponding authorization as valid, most clients would get stuck in an >> infinite loop either polling the authorization until it becomes valid, or >> retrying the same challenge type over and over again. >> >> --- >> >> In Section 3, I think that bullet points 2 and 3 are unnecessary. This >> draft is defining a new identifier type and a new challenge type. The rest >> of the process -- i.e. how the server reflects that identifier within the >> Order and Authorization objects -- is identical to vanilla RFC 8555, and >> does not need to be repeated here. >> >> --- >> >> In Section 3, the last code block shows a challenge of type "rats", but >> then Section 4 defines two different "device-attest-02" and >> "device-attest-03" challenges. Those are the strings which should appear in >> the challenge objects in Section 3. Also, the URLs for each challenge need >> to be different: >> >> { >> "status": "pending", >> >> "identifier": { >> "type": "policy", >> "value": "1.2.3.4.5" >> }, >> >> "challenges": [ >> { >> "type": "rats-01", >> "url": "https://example.com/acme/chall/asdf", >> "status": "pending", >> "token": "DGyRejmCefe7v4NfDGDKfA", >> }, >> { >> "type": "rats-02", >> "url": "https://example.com/acme/chall/zxcv", >> "status": "pending", >> "token": "DGyRejmCefe7v4NfDGDKfA", >> }, >> ], >> } >> >> >> --- >> >> In Section 4.1, the "response sent to the url" is defined, but appears to >> be just a plain string (`token || '.' || cmw`). The object posted to a >> challenge URL is always a signed JSON blob; just a pair of empty curly >> braces for the original challenge types, but subsequent challenge types >> (such as onion-csr-01 >> <https://www.rfc-editor.org/rfc/rfc9799.html#name-new-onion-csr-01-challenge>) >> have added custom fields to that object. This draft needs to describe the >> whole payload which should be POSTed to the challenge URL, not just a >> single string. >> >> --- >> >> In Section 4.2, it's unclear what part of Section 4.1 is being replaced >> by the "Background Check Model". Is that just a different way of computing >> `cmw`? A little more verbiage here would be useful. >> >> --- >> >> In both Sections 4.1 and 4.2, it's unclear what steps the ACME server is >> supposed to take to verify that the challenge has been completed >> successfully / that the client has POSTed the correct content. >> >> --- >> >> I don't understand the purpose of Section 5. How are these hints >> presented to the client? I don't see any evidence of them in the >> authorization or challenge objects created by the server in Section 3. >> >> --- >> >> Overall, I like this draft. It's another simple example of adding a new >> identifier type, and a couple new challenges that can be used to validate >> that identifier type. This is exactly the kind of extension that ACME is >> built for. I think it just needs a bit of work to clarify how rats >> identifiers are represented in certificates, how rats challenges are >> fulfilled, and how ACME servers validate the challenges. >> >> Thanks, >> Aaron >> _______________________________________________ >> Acme mailing list -- [email protected] >> To unsubscribe send an email to [email protected] >> >
_______________________________________________ Acme mailing list -- [email protected] To unsubscribe send an email to [email protected]
