API for Retrieving Let’s Encrypt Profile Configuration

Hello,

I'm implementing an ACME client that supports Let’s Encrypt certificate profiles. I can discover the available profiles from the ACME directory endpoint via meta.profiles , but I haven't found a way to retrieve the actual profile configuration in a machine-readable format.

Is there currently an API (or plans for one) that exposes profile metadata such as:

  • Certificate validity period
  • Maximum number of identifiers/SANs
  • Supported identifier types (DNS, IP, etc.)
  • Whether Common Name is included
  • Key Usage extensions
  • Extended Key Usage extensions (e.g. TLS Client Auth)
  • Subject Key Identifier behavior
  • Revocation information mechanisms
  • Authorization reuse period
  • Pending authorization lifetime
  • Order lifetime
  • Any other profile-specific constraints or certificate characteristics

Today it appears that ACME clients can discover profile names, but must maintain a hardcoded mapping of profile properties based on documentation. This makes it difficult to dynamically support new profiles or changes to existing profiles.

For example, I would ideally like to query something similar to:

{
  "profile": "shortlived",
  "validity_period": "160h",
  "max_names": 25,
  "identifier_types": ["DNS", "IP"],
  ...
}

Is there an existing endpoint, draft specification, or recommended approach for obtaining this information programmatically?

Thank you.

The current draft of the spec does not cover any sort of machine readable profile data. It's just the extension to the directory listing the available profiles and the extension to the order object to select a profile.

Let's Encrypt is the only CA I'm aware of currently implementing this draft spec and they've chosen to publish the profile details as human readable content on their website.

Thanks for your reply. So, the best approach right now is to manage this mapping locally on my side? How dynamic can this be in practice—can profiles be removed or changed unexpectedly? And if so, what’s the best way to track those changes over time?

Recalling previous discussions about this spec, I feel like the intent is that the client shouldn't really need to care about the profile details or even choose one by default. It's entirely on the user to understand what profiles are available and optionally choose to use one. Not specifying a profile at all lets the CA choose a default profile that should work for most users and change what that default might be over time which is the same way things worked prior to profiles being a thing.

And yeah, profile details can theoretically change at any time. But in the relatively short history of these profiles being implemented at LE, those changes have been announced via pretty well in advance.

Thx for the help!

Author of the profiles draft here: Yep, @rmbolger has it exactly right. We specifically don't want clients to be asking their operators for a whole bunch of potential configuration priorities, and then attempting to do best fit matching against the profiles advertised by the CA. That way lies negotiation, provably-unsolvable optimization problems, and sneaky bugs.

This is why the profiles advertised in the directory point to human-readable documentation. Just like a human decides which CA they want to use based on their own sense of that CA's operations and what services that CA provides, a human should decide which profile they want to use.

Nah, that's what AI is for, right?

Now I have to train my model on human readable stuff.

We'd be interested in this for CertKit as well. Whenever you publish a new profile, we'd like to auto-discover it and make it available without having to track it.

To be clear, there's always a machine-readable list of what profiles exist: that's in the Directory. You can simply poll the directory and take some sort of action when a new entry appears in the profiles list.

What we're not going to do is provide a machine-readable list of everything that a profile means: what validity period it has, what authorization reuse period it has, what extensions it has, what values those extensions have, etc. This is because any such machine-readable profile description will inevitably expand to cover every possible aspect of a certificate (and beyond!), which leads to three problems:

  1. We already have a format for expressing arbitrarily-detailed features of a certificate, including previously-unknown extensions: x509. We're unwilling to re-invent x509 in JSON; others have already tried. And x509 doesn't cover things like validation data reuse periods.
  2. For a client to choose between profiles, it will have to allow its user to configure preferences for various profile features. That means that client authors also have to reinvent x509 (and more) in their config format.
  3. As soon as a client has expressed two preferences (e.g. ECDSA over RSA, and 7d validity over 90d validity), it's possible for a server's set of advertised profiles (e.g. shortlivedRSA and longlivedECDSA) to be unsatisfiable.

Using LLMs to parse text descriptions of the profiles might get you past problem (1), but it does nothing to solve problems (2) and (3).