RFC 7030 — Enrollment over Secure Transport (EST) — Versola Docs
/docs
Pre-1.00.7.5versola.ioGitHub

RFC 7030 — Enrollment over Secure Transport (EST)

EST as Versola serves it so that an mTLS client obtains and renews its client certificate itself, with the checked claims and the deviations from the RFC.

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) — answers 204: 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; response application/pkcs7-mime; smime-type=certs-only with Content-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 400 and the reason

Authentication

  • simpleenroll by HTTP Basic, the client id as user name and a one-time enrolment token as password (§3.2.3)
  • simplereenroll by the client’s current certificate in the TLS handshake (§3.3.2), validated against mutual-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, or CN=<client>,OU=<tenant>,O=Versola where 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 is 403, naming when the window opens
  • Renewals form a chain that ends at client-identity.max-age; the end is in every answer as Versola-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. simpleenroll is on the issuer origin and simplereenroll only on the mutual-TLS origin (404 on 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 gets 404 for simplereenroll on the issuer origin and a TLS handshake error for simpleenroll on 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, and WWW-Authenticate advertises Basic only.
  • cacerts and csrattrs on 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. 429 with Retry-After for more than 30 simpleenroll attempts a minute per client id and replica, the Versola-Chain-Ends-At header, and 403 “too early” for a renewal before the window opens.
  • Channel binding. §3.5 requires a server to verify the tls-unique value a client includes, and tls-unique is not defined for TLS 1.3, so a request with challengePassword is refused with 400.
  • 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 a challengePassword attribute is refused
  • Full CMC (§4.3, fullcmc)
  • Arbitrary labels (/.well-known/est/<label>/...): one CA, no hierarchy; csrattrs is always 204
  • 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.