Specification: RFC 7030
EST lets a client request an X.509 certificate over HTTPS. Versola uses it for one purpose: a client registered with tls_client_auth and estEnrollment obtains and renews the client certificate it authenticates with at /token (RFC 8705), with a key it generated. auth serves the endpoints and holds no CA credentials; central decides what is issued and has the CA behind client-certificates sign it. The how-to is Automatic client certificate renewal (EST), the concept is Client certificates and their renewal, and the API is est.yaml in the OpenAPI reference.
Status
Partially implemented. Checked claims: 16 of 20. The routes answer 404 unless the est block of auth enables them (Configuration reference).
Endpoints
-
GET /.well-known/est/cacerts(§4.1) — the client CA as a certs-only PKCS#7, no credentials needed -
GET /.well-known/est/csrattrs(§4.5) — answers204: the request is asked to carry no attributes -
POST /.well-known/est/simpleenroll(§4.2.1) — the first certificate, for a client that has none -
POST /.well-known/est/simplereenroll(§4.2.2) — a new certificate for the one the client holds - Request
application/pkcs10, base64 of the DER; responseapplication/pkcs7-mime; smime-type=certs-onlywithContent-Transfer-Encoding: base64 - The subject and alternative names of a renewal request must be identical to those of the certificate renewed (§4.2.2); a request that names another subject is refused with
400and the reason
Authentication
-
simpleenrollby HTTP Basic, the client id as user name and a one-time enrolment token as password (§3.2.3) -
simplereenrollby the client’s current certificate in the TLS handshake (§3.3.2), validated againstmutual-tls.trusted-certificates; a certificate in a request header is never read - The enrolment token is single-use, expires (24 hours by default, 168 at most), is stored only as a hash and is shown once. An unknown, spent, expired or another client’s token gives one and the same
401 - A request body is at most 16 KiB
What Versola decides
- The certificate carries the subject the client is registered by (
mtlsAuth, orCN=<client>,OU=<tenant>,O=Versolawhere it names none), never one the request names - Keys: EC P-256, or RSA of at least 2048 bits
- Every renewal needs a new key; a request that reuses the key of the certificate it replaces is refused with
400 - A certificate renews only in the last third of its life (
client-identity.renew-window); earlier is403, naming when the window opens - Renewals form a chain that ends at
client-identity.max-age; the end is in every answer asVersola-Chain-Ends-At - A re-enrolment, or
POST /configuration/clients/est/revoke, ends the right of every earlier certificate to renew (401)
Deviations from the RFC
- Two origins.
simpleenrollis on the issuer origin andsimplereenrollonly on the mutual-TLS origin (404on the other), so a client needs two base URLs, which §3.2.2 does not assume. A stock EST client configured with one base URL gets404forsimplereenrollon the issuer origin and a TLS handshake error forsimpleenrollon the mutual-TLS one; run it once per origin. - A new key at every renewal. §4.2.2 admits the same key (renew) as well as a new one (rekey); Versola refuses the same key. A client whose HSM cannot generate a new key for each certificate cannot use this profile.
- Bearer tokens. Besides Basic, the enrolment token may be sent as
Authorization: Bearer. This is an extension: §3.2.3 names Basic and Digest, andWWW-Authenticateadvertises Basic only. cacertsandcsrattrson both listeners. On the main listener they need no credentials, and that is where a client with no certificate fetches them. They are served on the mutual-TLS listener as well, but its handshake demands a client certificate, so there they are reachable only with a valid one.- Versola extensions in answers.
429withRetry-Afterfor more than 30simpleenrollattempts a minute per client id and replica, theVersola-Chain-Ends-Atheader, and403“too early” for a renewal before the window opens. - Channel binding. §3.5 requires a server to verify the
tls-uniquevalue a client includes, andtls-uniqueis not defined for TLS 1.3, so a request withchallengePasswordis refused with400. - Not advertised in
mtls_endpoint_aliases. The metadata document does not list the EST endpoints; a client is configured with both base URLs.
Not Implemented
- Channel binding (§3.5,
tls-unique): a request carrying achallengePasswordattribute is refused - Full CMC (§4.3,
fullcmc) - Arbitrary labels (
/.well-known/est/<label>/...): one CA, no hierarchy;csrattrsis always204 - Server-side key generation (§4.4,
serverkeygen): the key is always the client’s
Where to look
Client certificates and their renewal explains the chain, generations and revocation. RFC 8705 covers what the certificate is used for.