KrakenKey is live with free and paid plans. Issue your first TLS certificate in minutes.

ACME's New Proof-of-Possession Extension Drops the CSR for KEM Keys

acmepost-quantumpki

The ACME working group published draft-ietf-acme-pop-00 on September 1. It defines an optional extension that lets a client prove possession of a certificate’s private key without constructing a PKCS#10 CSR. The motivation is specific: ACME’s finalize step has always assumed the client can self-sign a CSR with the key it wants certified, and that assumption fails outright for ML-KEM and other key-encapsulation keys, which cannot produce a signature at all.

What changed

RFC 8555 §7.4 requires a CSR at finalization: the client signs a CSR with the private key it wants certified, and the CA extracts the public key from that signature-verified structure. That works for RSA and ECDSA. It doesn’t work for ML-KEM, because a KEM key can encapsulate and decapsulate but cannot sign anything, including its own CSR.

draft-ietf-acme-pop-00 adds a parallel path. The client declares its public key directly in the newOrder request via a popKey field, paired with a new pop identifier type (empty-string value, purely a signal). The CA opens a dedicated pop-01 challenge with two modes: for signature-capable keys, the client signs a nonce; for KEM keys, the CA performs an ML-KEM encapsulation and returns challenge_ciphertext, the client decapsulates it, and both sides derive an HMAC via HKDF-SHA-256 that the client returns as proof. Once that authorization is valid, finalize takes an empty JSON payload, {}, instead of a CSR. Supported ML-KEM parameter sets (512/768/1024, per FIPS 203) are listed with their OIDs and key/ciphertext sizes in the draft’s Section 5.2.

Why it matters operationally

This isn’t shipping anywhere yet: it’s a -00 draft, first IETF revision, standards track. But it’s the piece that was missing for ML-KEM TLS certificates to be issuable through ACME at all, which is relevant if you’ve been tracking post-quantum certificate timelines: a CA can publish support for ML-KEM key types all it wants, but without something like this extension, no ACME client can actually request one, because the finalize step has no way to prove possession of a key that can’t sign.

Concretely, three things change if this lands:

Before/after: what finalize actually sends

RFC 8555 today, any key type:

POST /acme/order/1234/finalize
{
"protected": "<JWS header>",
"payload": "<base64url({ \"csr\": \"<base64url(DER CSR)>\" })>",
"signature": "<account-key signature>"
}

Under draft-ietf-acme-pop-00, once the pop-01 challenge has validated a KEM key, finalize carries no certificate data at all. The CA already has the validated popKey on file from the order:

POST /acme/order/1234/finalize
{
"protected": "<JWS header>",
"payload": "e30",
"signature": "<account-key signature>"
}

e30 is {}, base64url-encoded. The newOrder that started it looks like this:

{
"identifiers": [
{ "type": "dns", "value": "example.com" },
{ "type": "pop", "value": "" }
],
"popKey": "<base64url(DER SubjectPublicKeyInfo)>"
}

The client never builds a CSR or ASN.1-encodes a certificate request. That’s also why the draft calls out resource-constrained devices as a secondary motivation, independent of the KEM problem.

How KrakenKey’s approach relates

This doesn’t change anything in KrakenKey’s flow today. Our ACME issuance is signature-key only (RSA and ECDSA), and we don’t yet issue ML-KEM certificates, so there’s no finalize step to modify. It’s relevant if you’re running your own ACME client and have PQC certificate pilots on your roadmap: the draft is one WG revision old, the pop-01 mechanics could still change before it stabilizes, and building client support against -00 today means you should expect to revise it. We’d track it for now and hold off on implementing against it.