The client
A device, server, or agent that needs a certificate and holds the private key.
- Generates the key pair (usually locally)
- Signs the PKCS#10 request → proof-of-possession
- Validates the EST server against a pinned trust anchor
Standards-track · RFC 7030 · updated by RFC 8951
EST is the IETF way for a device to ask a certificate authority for an identity certificate over ordinary HTTPS: one well-known URL, a PKCS#10 request, and a certificate back. No vendor agent, no PKCS#7 envelope gymnastics, no custom port.
Orientation
EST is a profile, not a product: it says how to move certificate management messages (CMC / PKCS#10) over HTTPS, and what the client is allowed to assume about the server. Architecturally the EST service plays the Registration Authority role, sitting between the client and the CA.
A device, server, or agent that needs a certificate and holds the private key.
Terminates HTTPS, authenticates the client, applies policy, and brokers the request.
/.well-known/est/…Signs the certificate. In practice an intermediate signer does the signing, chained to an offline root.
“The CA” is rarely a single machine. A typical deployment keeps the root offline and lets an intermediate — the intermediary signer — do the actual signing.
Clients receive the intermediate, and any chain above it, from /cacerts; the root
is the anchor they already pinned. Keep the root key offline, keep the intermediate
revocable, and remember /simpleenroll returns only the leaf.
RFC 7030 defines only the client↔EST-server leg. The server→CA protocol, revocation publishing, key archival, and identity proofing are left to the deployment. That is why two “EST servers” can behave very differently while both being compliant.
Each layer has a narrow job. Most production bugs come from confusing them — for example,
blaming the CSR when the real failure is TLS client authentication, or chasing a certificate
problem that is actually an HTTP 401 challenge.
The request and the certificate bag. Base64 text over HTTP. This is the only layer EST really “adds” semantics to.
Path selects the operation, Content-Type selects the message type, status codes carry control flow.
Server auth is mandatory; client auth is the recommended path. Also supplies the tls-unique channel binding.
CA policy decides issuance. EST only proves who is asking and what key they hold.
Both terms are used constantly in device PKI, and neither appears in RFC 7030. They describe roles, not protocol messages — so always ask what the other person means. Here is the mapping that makes the enrollment flow make sense.
The device's first identity, installed at manufacturing. Issued by the manufacturer's CA, with the private key generated in the factory and usually locked into a secure element.
In EST: this is the “previously installed certificate issued by a third party” from
§2.2.1, presented as the TLS client certificate on the very first
/simpleenroll. The EST server must trust the manufacturer's CA.
Usually just another name for the birth certificate — but vendors also use it for:
/cacerts — RFC 7030 calls that “Bootstrap Distribution of CA Certificates” (§4.1.1), and it is not a client certificate at all.What the device actually uses in production: 802.1X, mutual TLS, IPsec. Bound to a key generated on the device and issued by your CA, not the manufacturer's.
In EST: the result of /simpleenroll, later renewed or rekeyed with
/simplereenroll. This is the certificate that expires on a schedule.
Birth certificate = “who built me”. Operational certificate = “what this network lets me be”. The birth certificate is a long-lived skeleton key whose only job is to authorise enrollment, so scope it: which CA may it enroll with, which names may it request, and is every use logged? A stolen birth certificate lets an attacker mint operational identities until someone notices and revokes it.
It also normally cannot stand in for /simplereenroll, because that request must
carry the same subject and SAN as the certificate being renewed. Keep it — plus a fallback
auth path — for recovery when the operational certificate has expired.
Small clients, no user in the loop, long-lived devices, and environments where you already have PKI. It is deliberately boring: HTTPS plus two standard object types.
Not a discovery protocol, not a CA API, not a revocation protocol, and not a
substitute for identity proofing. A /simpleenroll that is open to the
internet will happily issue certificates to anyone who asks.
Roles & authority
EST is a conversation between two systems, but a certificate is a governance artifact. Before anything is signed, someone has to decide who may enrol, what they may ask for, and who is allowed to say no. Those are different jobs, held by different roles — and only some of them appear in the protocol.
| Role | What it decides / owns | Where you see it in EST |
|---|---|---|
| Policy authoritygovernance role, not a system | The rules. Certificate profiles (key type, curve, validity, EKU), which identities may enrol, which names and SANs are legitimate, renewal windows, revocation triggers, and who accepts the residual risk. Owns the certificate policy and CPS. |
Nowhere directly. RFC 7030 never uses the term — it talks about “local CA
policy” instead (§3.7). You meet the PA's decisions as /csrattrs hints,
4xx rejections, and the profile the CA will actually sign.
|
| Registration authorityoften the EST server itself | Individual requests. Proves that the requester is who it claims to be, decides whether this key may be bound to this identity, and approves, holds or denies. Can be fully automated, a human queue, or an RA client acting for others. |
Built in. RFC 7030 says the EST service performs “functions traditionally
allocated to the Registration Authority role”. A human approver shows up as
202 + Retry-After; an RA client presents a certificate with
the id-kp-cmcRA EKU and may use /fullcmc.
|
| Certification authorityroot + intermediate signer | Issuance mechanics. The root is an offline anchor; the intermediate (issuing) CA is the intermediary signer that actually signs leaf certificates. It assigns serial numbers and validity, enforces the profile, publishes CRL/OCSP, and manages rollover. |
Behind the curtain. The server↔CA protocol is explicitly out of scope.
/cacerts publishes the CA chain and rollover certificates; everything
else is an implementation detail.
|
| End entitydevice, workload, or person | Its own key. Generates and protects the private key, signs the CSR, renews before expiry, and reports compromise. It does not get to decide what it is allowed to be. |
The client. Authenticates with an existing certificate, HTTP credentials or
TLS-SRP; its CSR signature is the proof-of-possession; renewing means
/simplereenroll.
|
| Relying partyevery service that trusts the CA | Acceptance. Validates the chain to a trust anchor, checks revocation and name/policy constraints, and decides what the certificate is good for. | After the fact. Not part of enrollment at all — but the reason enrollment exists. EST says nothing about revocation, so CRL/OCSP and trust-store hygiene are still yours. |
| PKI operationsplatform / on-call | Keeping it running. Deploys and monitors the servers, works the approval queue, restores service, executes revocations, and rehearses renewal and CA rollover. |
The control plane. Operates the EST server and its CA connector, watches error
rates and the 202 backlog, and owns the pager when enrollment breaks.
|
| Auditorindependent of all of the above | Evidence. Checks that what was issued matches policy and that approvals happened — not that the cryptography is correct. | Logs. Needs a chain joining authenticated identity → request → decision → issued serial, retained long enough to answer “who got what, and who said yes”. |
There is no “policy” message in EST. Policy is expressed as configuration and enforced as
rejection: advisory hints in /csrattrs, eligibility checked at
/simpleenroll, a human in the loop via 202, and the CA profile
as the final arbiter.
The only role marker on the wire is the id-kp-cmcRA EKU on a client
certificate — everything else about authority is deployment convention.
One team writing the profile, approving its own exceptions, and holding unattended CA keys is how “any valid certificate can request any name” becomes policy. Keep approval separate from profile authorship, and keep both away from unattended CA key custody (HSM, dual control, split knowledge).
Practical test: can the person who approves an enrollment also change what the CA will sign? If yes, the separation is decorative.
Interactive walkthrough
Click any step — or use ← → while the diagram has focus — to see
what is sent, why it exists, and which part of the spec governs it. Rows are ordered the
way a well-behaved client behaves, including the two optional branches that confuse people:
the 401 retry and the 202 hold.
The CA lane is dashed on purpose: RFC 7030 does not define what happens between the EST server and the CA. In practice it is an intermediate signer, not the root.
Reference
Everything hangs off https://<host>/.well-known/est. The path suffix
selects the function; the HTTP method and Content-Type identify the message.
A server may insert an extra path segment to select between CAs
(/.well-known/est/label1/cacerts), and must still serve the unlabelled form.
On the wire
EST bodies are DER, base64-encoded, with no PEM armour and — since RFC 8951 — no
meaningful Content-Transfer-Encoding. These are illustrative exchanges;
the request and response bodies are shortened.
Retry-After is mandatory. Re-send the same request after the interval; the server keeps the state./csrattrs: no attributes to offer. Treat as “empty”.WWW-Authenticate). Retry with credentials — but only over TLS./fullcmc, /serverkeygen) not implemented.-----BEGIN lines.Content-Transfer-Encoding is deprecated. Do not require it, do not break when it is absent.application/pkcs7-mime responses carry smime-type=certs-only./cacerts is the opposite: root plus every intermediate needed to build a path, plus optional rollover certs.
This is the actual base64 body from RFC 7030 Appendix A.2, decoded in your browser. Click a
node to see which bytes it occupies. The CA is asking for challengePassword
(identity/POP linking), a P-256 key, SHA-256 signatures — plus two made-up attributes
(2.999.x) that a client must ignore.
The heart of it
A certificate request proves you hold the private key. EST adds an optional twist: you can bind that proof to the TLS session you are currently using, so the server knows the key was exercised inside the authenticated tunnel — not replayed from somewhere else.
The client pulls the tls-unique channel binding (RFC 5929) from its TLS
stack, base64-encodes it, and puts it in the PKCS#9
challengePassword attribute of the CSR. Because that attribute is inside the
signed request, it cannot be altered without breaking the signature.
Presence of the attribute is the signal. If it is there, the server must verify it against the live session. If it is absent, the client chose not to link.
One wrinkle: tls-unique is defined for TLS 1.2 and earlier. TLS 1.3 has no
such value — RFC 9266 defines tls-exporter instead — so estates that insist
on POP linking tend to pin TLS 1.2, or accept enrollment without the binding.
Any TLS-terminating middlebox — a load balancer, reverse proxy, or inspection appliance — breaks the binding, because the server sees a different session than the client signed. Same thing if the client tears down and rebuilds the connection between CSR generation and POST.
Fix: rebuild the CSR (not the key) on the same connection, or have the server accept
POP without linking. Retries after a 202 are exactly where this bites.
challengePassword is overloaded across PKI history. RFC 7894 added distinct
attributes so a server can tell them apart — worth knowing when you see a CSR rejected for
“wrong password” when no password was ever configured.
Context
All four get a certificate onto a device. They disagree about transport, encoding, authentication, and how much state the server keeps. None of them is universally better — the choice is usually dictated by what the device already speaks.
| Property | EST RFC 7030 | SCEP legacy | CMP / CMPv2 RFC 4210 | ACME RFC 8555 |
|---|---|---|---|---|
| Transport | HTTPS only, GET/POST to fixed paths | HTTP or HTTPS, GET with base64 in the query, plus POST | Usually HTTPS; also TCP, or in-message transport | HTTPS with JSON |
| Message format | PKCS#10 + CMS/PKCS#7 certs-only, base64 | CMS enveloped PKCS#7, base64 in URLs (size limits) | CMS PKI messages, richer controls | JSON + JWS, PEM output |
| Client auth | TLS client cert (recommended), HTTP Basic/Digest, TLS-SRP | Shared secret in challengePassword (weak) |
Certificate, shared secret, or MAC | Account key + JWS; domain validation |
| Proof-of-possession | CSR signature, optionally bound to TLS session | CSR signature inside CMS | CSR signature, or central key generation | CSR signature |
| Server-generated keys | yes /serverkeygen, optional |
yes | yes, common in telco | no |
| Async / approval | 202 + Retry-After, replay same request |
Poll with CertPoll |
Polling, ir/ip, or push |
Authorization polling |
| Renewal | /simplereenroll, subject/SAN must match |
RenewalReq |
Same message with new keys | Re-order; new cert |
| Client complexity | low — HTTPS + two encoders | low, but many dialect quirks | high — large ASN.1 surface | medium — JSON/JWS stack |
| Typical home | Network gear, IoT, utilities (IEC 62351), BRSKI, industrial | Legacy MDM, Windows estates, older appliances | Telco, large enterprise PKI, 3GPP | Web servers, public TLS, ACME-capable appliances |
You control the firmware, you can ship a trust anchor, and you want standards-based enrollment with no proprietary agent.
An existing fleet only speaks SCEP. It is everywhere, but treat the shared secret as a weakness and plan a migration.
Automated web TLS with domain validation. ACME is not designed for device identity or private-key escrow.
BRSKI (RFC 8995) bootstraps trust for brand-new devices using manufacturer-installed certificates and a voucher, then hands off to EST for the actual enrollment. EST-coaps (RFC 9148) carries the same payloads over CoAP/DTLS for constrained networks. Both reuse the endpoint model described on this page.
Production reality
EST failures are rarely cryptographic. They are almost always trust, session, or policy mismatches — and the error message is usually a single status code with no explanation.
Cause: the client has no trust anchor for the CA that signed the EST server certificate, so validation fails before HTTP is even reached.
Fix: use bootstrap distribution — fetch /cacerts over a provisional connection and have a human confirm the CA fingerprint out-of-band (SHA-256 of the whole cert), then install it as an explicit trust anchor and reconnect.
Don’t: leave the client permanently in “trust anything” mode. RFC 7030 requires the ability to disable implicit anchors.
Cause: the server wants HTTP Basic/Digest and the client never answers the challenge, or the client certificate is not being sent (wrong keystore, missing intermediate, server not requesting it).
Fix: check WWW-Authenticate, configure credentials, and verify the client chain the server actually receives. The server may require both a client cert and a password.
Cause: policy rejection. When there is no Content-Type, RFC 7030 says the body is human-readable text — read it, it is the only diagnostic you get.
Fix: call /csrattrs and honour it: required curve, hash, SAN, or extra attributes. A missing challengePassword is a common one when the CA requires POP linking.
Cause: the request is queued for manual approval, or waiting on an upstream CA. The server is holding state; the client just needs to keep asking.
Fix: wait at least Retry-After, then re-send the identical request. Do not regenerate the key on each attempt. If the TLS session was closed and you used tls-unique, rebuild the CSR but keep the key pair.
Cause: the CSR was signed over a different TLS session than the one that delivered it. Load balancers, TLS inspection, connection reuse across hosts, and retry loops all cause this.
Fix: generate and submit the CSR on a single connection; terminate TLS on the EST server itself (or forward session info); disable renegotiation-style optimisations between those two points.
Cause: the issued cert is fine; the chain is incomplete. /simpleenroll returns only the leaf, and the client usually lacks the intermediate that signed it.
Fix: fetch and distribute the chain from /cacerts, and make sure your trust store has the root, not just an intermediate.
Cause: embedded clients often lack TLS client auth, a real clock, or the ability to hold more than one trust anchor.
Fix: check time sync first (a wrong clock breaks both validation and signatures), then fall back to HTTP auth or certificate-less TLS (SRP) if policy allows, and confirm the device can parse base64 bodies without PEM headers.
Cause: /simplereenroll requires the subject and SubjectAltName to be identical to the certificate being renewed. Any drift — a new hostname, a reordered RDN, a different SAN encoding — is a mismatch.
Fix: copy the identity from the existing certificate byte-for-byte, or use the CMC ChangeSubjectName attribute if a rename is genuinely intended.
Cause: RFC 7030 used MIME headers; RFC 8951 deprecated Content-Transfer-Encoding because real implementations omit or ignore it.
Fix: emit base64 bodies without relying on the header, and on the client side accept bodies with or without it. Whitespace handling should be equally lenient.
/cacerts open only if you must./serverkeygen off unless there is a hard requirement; if on, require CMS encryption of the key.202 hold./cacerts.An enrollment endpoint that authenticates but does not authorise. If any valid client certificate can request any subject name, one compromised device can mint identities for the whole fleet. Bind the requested identity to the authenticated one, every time.
Check yourself
Instant feedback, with the reasoning. No score is stored anywhere.
Reference
The bits you end up looking up twice.
/.well-known/estapplication/pkcs10, base64 DERapplication/pkcs7-mime + smime-type=certs-onlyapplication/csrattrs, base64 DER CsrAttrsapplication/pkcs7-mime + smime-type=CMC-request|CMC-responsemultipart/mixed: pkcs7-mime + application/pkcs8challengePassword = base64(tls-unique), ≤ 255 bytes202 + Retry-Afterid-kp-cmcRAid-kp-cmcRA on a client cert means RA privileges/cacerts must hand out./cacerts.Examples on this page are illustrative and simplified. Where they conflict with the RFCs, the RFCs win — in particular RFC 8951 supersedes RFC 7030 on transfer encoding and ASN.1 details.