PROD Support for RFC8657 CAA constraints for accountURI and validationmethods

What's the status of this feature in the staging environment? Is it ready for people to try to hammer away at to try to find holes, like someone making some equivalent of for the new parameters that tries to find all the edge cases and see how the system deals with them? Or is there a lot of actual coding that still needs to happen too in addition to the careful spec-reading and confirming that it won't immediately lead to some Dreaded Incidents?


I'd also imagine of the the biggest wins administrators would get from this is being able to use Let's Encrypt certs, but not allow just anyone to issue them. So for instance an org doesn't have to worry about a contractor coming in, getting a "dev" VM setup with a web app and then disappearing once the link has been handed to a bunch of users shadow-IT style.


Yes, please! It’s available in staging and the more testing, the better.


As an aside, this apparently doesn't work with Cloudflare DNS because they override the CAA record if you specify one, presumably so all their auto cert stuff continues to work normally.


Turning off Universal SSL removes these CAA records, right?


Thanks, yes it does. Also tested with a subdomain zone on ClouDNS and staging behaved as expected for both accountURI and validationmethods restrictions.


Well, I did a little bit of ad-hoc testing of the "validationmethods" parameter, and it was working pretty well (once I realized that the official ACME Validation Methods Registry uses all-lowercase labels even though the standard in LE's documentation is all-uppercase). The main thing I found so far that I'm not even sure of the correct answer is if the "validationmethods" parameter is set more than once on an "issue". I think it might be a correct reading that all the parameters with that name would constrain the Property. So I created a CAA record just consisting of

0 issue "; validationmethods=dns-01; validationmethods=http-01"

Which I think should prevent all issuance for that name since no methods actually fulfill both constraints. But in fact, I could issue a certificate (using http-01) for that name.

With the parameters the other way around (http-01 first, and dns-01 second), trying to use http-01 did give me a CAA error. So I think that Boulder is just using the last validationmethods in the list. (I suppose I could look in the source code, but I guess I'm starting with just black-box testing for now if I want to call it an intentional choice rather than just laziness.) Maybe that's even correct; I couldn't find in RFC 8657 or 8659 any clear direction on how duplicate properties were supposed to be handled.

I may play around some more, including maybe with "accounturi" as well, when I get some more time, but I thought I'd share what I found so far.


You made me curious so I looked too. It does instruct to use the parameter with multiple values rather than using multiple parameters. The text below is from its main section. In Examples section it shows using two CAA records with a single validationmethods value as alternate to multiple values. I don't know the style of these RFC's well enough to know whether they get more specific than this in other cases.

This document also defines the "validationmethods" CAA parameter for the "issue" and "issuewild" Properties. The value of this parameter, if specified, MUST be a comma-separated string of zero or more validation method labels.

A value string with zero labels. Hmmm :slight_smile:

From Examples section: IN CAA 0 issue "; \

   The following shows an equivalent way of expressing the same
   restriction: IN CAA 0 issue "; validationmethods=dns-01" IN CAA 0 issue "; validationmethods=xyz-01"

If I look the CAA parameter parser correctly, this for loop does not check if a certain parameter already exists in the "saved" parameter list and just overwrites any previously set parameters with the "latest" one, being the rightmost parameter:


Sorry if I wasn't clear: Using commas for multiple allowed validation methods worked fine in my testing. I was trying to do things "wrong" to see what happened.

Yeah, having a plain validationmethods= meant that it blocked issuance, which I believe was correct.

I do wonder, upon thinking of it more, just how "cached" validations are supposed to work with CAA (which I didn't really try testing). Would an empty validationmethods mean that only still-cached validations should be used? Or is it checking the "most recent" validation or the like?

Yeah, I was guessing it was doing something along those lines.


does validation/accountURL per CA allowed and working as expected?
for exemple IN CAA 0 issue "; validationmethods=dns-01" IN CAA 0 issue "; validationmethods=http-01,dns-01"

would this CAA disallow cert by http-01 by LE while allowing someCA to use http challange?


I believe so, yes.


No, I understood that. I was reacting to your comment about the RFC not being clear. I thought the specs reasonably described acceptable syntax. It does not appear the CA is responsible for reporting syntax errors. And, those can lead to unexpected outcomes. A full syntax assessment is probably best done by a generalized "lint" tool or Let's Debug.

Good question on cached validations. LE should make that clear in their FAQ about them. I now wonder what happens if even the CAA issue value were changed during the cached period. Would LE check CAA or fully rely on cache?


CAA RR are cached MUCH shorter than valide authz (8 hours instead of 30 days). In fact, the lack of maintaining this shorter cache time in certain situations has lead to a quite serious incident: 2020.02.29 CAA Rechecking Bug


The CAA RFC specifically says:

The semantics of parameters to T issue Property Tag are determined by the Issuer alone.

So the results of specifying a single parameter multiple times in the parameters section of a single CAA Resource Record Property Value are unspecified. I don't necessarily think that taking the last one (as we currently do) is the best thing to do, but it does appear to be a completely valid thing to do... in general.

Of course, the accounturi and validationmethods parameters are further specified, so let's see what those have to say:

A Property with multiple "accounturi" parameters is unsatisfiable.

So for accounturi parameters the behavior is well defined: multiple disagreeing parameters means issuance cannot happen because you cannot satisfy all of them at the same time.

A CA MUST only consider a Property with the "validationmethods" parameter to authorize issuance where the validation method being used is identified by one of the validation method labels listed in the comma-separated list.

This is much less clear. But I think it should probably be interpreted in the same way as accounturi above: issuance can only happen if the validation method being used appears in all validationmethods parameters in the resource record. So basically, take the intersection of all of the lists of methods, and hope that intersection is non-empty to allow issuance :slight_smile:


Are you suggesting that for a single CAA record? Because the RFC Examples section shows below as identical to '=dns-01,xyz-01`. It two CAA records create a union then I think it odd if two on one CAA record would be treated as an intersection.


It's more that two CAA records create a union, the options within a validationmethods are also a union, but having multiple validationmethods are an intersection (assuming that @aarongable's reading and mine are correct).

And my questions are mainly around if a CAA record has unacceptable syntax, in what cases does that mean that no issuance is allowed and in what cases does it mean that any issuance is allowed.


Yeah, to be clear, I'm guessing/interpreting here just as much as everyone else. I don't have any magic insight.

Two separate CAA records must be treated as a union because there's no other reasonable interpretation: for example, the two separate CAA records might specify two different CA URLs, allowing two different CAs to issue for that name. Basically the interpretation is "if there is any CAA record that allows this issuance, then you're good".

It's only within a single CAA record that the questions arise. And that's where my supposition of "treat it like accounturi" becomes relevant. For that parameter, we are explicitly told that the set of valid account URIs is the intersection of the values of multiple accounturi parameters within a single record. So it seems reasonable to do the same for validationmethods.


You both make fair points yet I favor other options. TL; DR I think retaining only the last validationmethods is fine. My second favorite is to fail to issue if more than one exists on the same CAA regardless of their values (gasp, I know, read on).

accounturi can only have a single value. The spec needs to describe how to specify multiple values and that is done with multiple CAA records (see Examples section). It makes clear not to use multiple accounturi on one CAA. It actually says: A Property with multiple "accounturi" parameters is unsatisfiable. So, a strict reading means multiple parameters should fail even if the values are identical. That is, fail due to syntax failure and not because of an intersection. But, for me this is of lesser importance and the primary key is that accounturi is a single-value parameter.

validationmethods allows multiple values for one parameter. The spec also says multiple CAA records may be used. A discussion of what happens with two parameters on one CAA is not needed to describe practical usage. I don't think there is a compelling reason for doing any one particular thing. Multiple on one CAA is not an explicitly approved syntax so, for me, falls into section 5.8 about Misconfiguration Hazards and is CA discretion.

5.8. Misconfiguration Hazards

Because the "accounturi" and "validationmethods" parameters express restrictive security policies, misconfiguration of said parameters may result in legitimate issuance requests being refused.


This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.