EST enrollment
EST (Enrollment over Secure Transport, RFC 7030) lets network devices, MDM systems and scripts request and renew certificates from a Taranac Internal CA without handling P12 files by hand. A client sends a certificate signing request (CSR) and receives the signed certificate in the reply. The key never leaves the client.
Taranac takes certificates over EST in two ways, and each has its own port:
| Step | Endpoint | Port | The client proves itself with |
|---|---|---|---|
| First enrollment | POST /.well-known/est/simpleenroll | web HTTPS port 443 (EDGE_HTTPS_PORT), or the EST gateway on 8445 | a username and password (HTTP Basic) of a local Taranac account |
| Renewal | POST /.well-known/est/simplereenroll | EST gateway only, 8445 (EST_GATEWAY_PORT) | its current certificate (mutual TLS), which this Taranac issued and still holds as active |
A certificate never obtains a first certificate, and a password never renews one.
- :443 POST /simpleenroll username + password · local account issued
- :8445 POST /simplereenroll current certificate · ours, active, on no CRL renewed
- :8445 POST /simplereenroll revoked, expired or foreign certificate refused · logged
Setting it up
Section titled “Setting it up”- Have an Internal CA to issue from. Create one on Settings → PKI / Certificates
(see PKI & trust). EST issues client certificates (
clientAuth). - Turn EST on. On Settings → PKI Settings → EST Enrollment, switch on Enable EST endpoint, pick the Issuing CA, and choose the Identity binding (below).
- Create the account that enrolls. First enrollment checks a local account’s password. Under Strict binding each person enrolls as themselves. Under Device binding, network equipment usually shares one service account.
- Give the device the CA chain. Click Copy full-chain CA next to the issuing CA and install the PEM on the device (or in the MDM profile) before its first enrollment.
- Open the ports from the devices to Taranac:
443and8445(TCP). See Ports and firewall. - Point the device at Taranac. The EST Endpoint URLs card, shown while EST is on,
lists the four paths. The base is
https://<taranac-address>for 443 andhttps://<taranac-address>:8445for the gateway.
Settings
Section titled “Settings”All on Settings → PKI Settings → EST Enrollment. Everything below the switch is inert until Enable EST endpoint is on.
| Setting | Default | Description |
|---|---|---|
| Enable EST endpoint | off | Turns /.well-known/est/ on. While it is off, every EST endpoint refuses. |
| Issuing CA | — | The Internal CA that signs EST certificates. Copy full-chain CA sits next to it. |
| Certificate validity (days) | 365 | 1–3650. Cut to the issuing CA’s own expiry. |
| Require admin approval | off | Requests wait for a person instead of being issued at once. See Approvals. |
| Approval group | — | Who is emailed about a waiting request. Notification only. LDAP groups work here. |
| Request lifetime (days) | 30 | 1–365. How long an undecided request lives before it is marked expired. |
| Allowed authentication methods | Enroll by password, renew by certificate | See What tls means. |
| Identity binding | Strict | Strict or Device. See Identity binding. |
| Allowed networks for IP SANs | empty | CIDR list, one per line. Device binding only. Empty means no restriction. |
| mTLS proxy secret | empty | Only for a TLS terminator of your own. Leave it empty for the bundled gateway. See The proxy key. |
| Enrollment (password) | 443 | Read-only, marked ENV: the web HTTPS port, EDGE_HTTPS_PORT in .env. |
| Re-enrollment (client certificate) | 8445 | Read-only, marked ENV: the EST gateway port, EST_GATEWAY_PORT in .env. |
Copy full-chain CA
Section titled “Copy full-chain CA”Copy full-chain CA copies one PEM to the clipboard. It holds the issuing CA’s chain up to its root, plus the CA that signs this node’s server certificates (the Taranac Infrastructure CA, which signs the EST gateway’s certificate). Each certificate appears once. This is what a device must trust before its first enrollment: the gateway’s server certificate and the CA that will sign the device’s own. The button is active once EST is on and an issuing CA is selected.
GET /.well-known/est/cacerts returns only the issuing CA’s chain, so it does not replace
this step for a device that checks the gateway’s certificate.
First enrollment: by password
Section titled “First enrollment: by password”/simpleenroll authenticates with HTTP Basic, checked the way the web login checks a
password:
- Local accounts only. A directory (LDAP/AD) account has no password in Taranac and is refused.
- A disabled account, a locked one and one outside its validity window are refused.
- Wrong passwords count toward the account’s lockout, the same counter the console login uses. A device that retries with a stale password can lock the account it enrolls with, and every device that shares that account with it.
- A group that denies web-console access does not stop EST. An enrollment account does not need console access.
Before the password is checked, the request must pass these checks, in order: EST is enabled, password enrollment is allowed, and the body is a valid CSR. A disabled EST therefore checks no passwords, and a request with a broken body fails the same way whatever the password.
A request that offers only a client certificate is refused as a method that is not allowed. When a request carries both a password and a certificate, the password authenticates and the certificate plays no part.
The endpoint allows 10 requests a minute per client address. Requests beyond that are
answered 429.
Renewal: by the current certificate
Section titled “Renewal: by the current certificate”/simplereenroll takes no password. The device presents the certificate it holds in the TLS
handshake on the EST gateway, and sends a new CSR. Renewal is granted only when all of these
hold:
- The chain verifies at the gateway against an enabled internal CA, the certificate is within its validity dates, and no certificate in the chain is on its CA’s CRL.
- This Taranac issued exactly that certificate. It is compared as a whole, not by serial number alone. A certificate from a Trusted CA or an LDAP domain CA never renews here, though EAP-TLS accepts it.
- Taranac still holds it as
active. A revoked or expired certificate is refused. - The CSR keeps the same subject. The order of the attributes does not matter, but a changed or added attribute is refused. Renewal renews an identity. It does not rename one.
The renewed certificate goes through the same issuance as a first one: the current Issuing CA, the current identity binding and allowed networks, and the approval queue when Require admin approval is on. Under Strict binding the identity is the CN of the presented certificate.
Renewal does not revoke the certificate it replaces. The old one stays active until it
expires. Revoke it on the PKI page if it must stop working at once.
A device whose certificate has already expired or been revoked cannot renew. It enrolls again by password.
Renewal works only through the EST gateway. On 443 the front end removes every
client-certificate header before the request reaches the API, so /simplereenroll there is
always refused. The endpoint allows 30 requests a minute per client address.
What tls in the allowed methods means
Section titled “What tls in the allowed methods means”Allowed authentication methods decides which of the two steps is open. basic is first
enrollment by password; tls is renewal by certificate.
| Option | Setting value | Effect |
|---|---|---|
| Enroll by password, renew by certificate | basic,tls | Both steps. The default. |
| Enroll by password only (no renewal) | basic | /simplereenroll is refused. Devices enroll again by password. |
| Renew by certificate only (no new enrollments) | tls | /simpleenroll is refused. Devices that already hold a certificate keep renewing. |
The EST gateway
Section titled “The EST gateway”The est-gateway container is the listener that verifies client certificates. It runs on
every node, on host port 8445 (EST_GATEWAY_PORT, container port 8443), and accepts
TLS 1.2 and 1.3. It forwards only /.well-known/est/ to the API on its own node and answers
404 to anything else. It always runs: while EST is off, the API refuses what it forwards.
The gateway asks for a client certificate but does not require one, and one that does not
verify does not fail the connection. It reports its verdict (SUCCESS, FAILED:<reason> or
NONE) to the API, and only SUCCESS counts. Anything else is treated as no certificate:
the request can still enroll by password, and it never renews.
The gateway passes on the address that connected to it and ignores any X-Forwarded-For
the client sends. Rate limits and the Activity Log use that address.
Its server certificate
Section titled “Its server certificate”The gateway presents its own certificate, est-gateway/server.crt with server.key, from
the node’s certificate volume (taranac_certs). It never presents the NAC (EAP) server
certificate, so changing what RADIUS shows to supplicants does not change what EST clients
must trust.
The generated certificate is signed by the node’s Taranac Infrastructure CA. Its
subject alternative names list the node’s addresses: TARANAC_NODE_IPS from .env, plus
TARANAC_DOMAIN and NODE_ADDRESS when set. Each time the api container starts, the
certificate is checked and reissued if it does not cover all of these addresses or expires
within 30 days. After the node’s address changes, edit TARANAC_NODE_IPS in .env and run
./taranac up -d. Until the certificate exists, the gateway starts with a temporary
self-signed one that clients will not trust.
Your own certificate. Replace the two files with a certificate from a CA your devices already trust, with every address devices use in its SANs and an unencrypted PEM key. The api container mounts the volume writable:
docker cp server.crt taranac-api:/opt/taranac/certs/est-gateway/server.crtdocker cp server.key taranac-api:/opt/taranac/certs/est-gateway/server.keyThe gateway checks its certificate, key and trust files every 30 seconds and reloads when one changes, with no restart. A new configuration that does not load cleanly (for example a certificate whose key has not arrived yet) is not applied: the running one stays, and the gateway tries again on the next check. A certificate you put in place is never replaced by the automatic reissue. Watch its expiry yourself.
What it trusts
Section titled “What it trusts”The gateway trusts only the enabled, active internal CAs, each with its CRL. It does not
use the EAP-TLS bundle (ca_clients.pem), which also holds Trusted CAs and LDAP domain CAs.
Their holders may join the network, but this Taranac never issued them anything to renew.
The API rewrites this trust and its CRLs whenever a CA’s CRL is re-signed (a revocation does this, and so does the daily run), when a CA is changed, disabled or deleted, and each time the api starts. The gateway picks the change up within 30 seconds, so a revoked certificate stops renewing without a restart.
The proxy key and the mTLS proxy secret
Section titled “The proxy key and the mTLS proxy secret”The gateway tells the API what it verified in request headers, and proves those headers are
its own with a shared key, EST_PROXY_KEY in .env. The installer generates it and
./taranac update adds it when it is missing, so there is nothing to configure. With the key
empty, the API ignores the gateway’s headers and renewal does not work. The gateway logs a
warning at start in that case. The key may contain only A–Z a–z 0–9 . _ ~ + / = -, or the
gateway refuses to start.
mTLS proxy secret on PKI Settings is only for a TLS terminator of your own that verifies
client certificates in place of the gateway. It must set X-SSL-Client-Verify (only
SUCCESS is believed), X-SSL-Client-S-DN, X-SSL-Client-Cert (the URL-encoded PEM
certificate) and X-Est-Proxy-Key (the secret). Client-certificate headers that arrive
without a valid key are ignored. Leaving the secret empty weakens nothing.
Identity binding
Section titled “Identity binding”The server always writes the certificate’s SAN. The requester never chooses it. EAP-TLS authorization reads the SAN, so a client that could pick it could take any other identity on the network. Identity binding decides which identity goes in.
| Binding | Subject | SAN | Stored as | Use it for |
|---|---|---|---|---|
| Strict (default) | The CSR’s subject, with the CN replaced by the authenticated username | The username as a UPN, plus an email entry when the username contains @ | user certificate | people and BYOD: the certificate is the person |
| Device | The CSR’s subject, CN kept | The DNS names and IP addresses from the CSR. At least one is required. | device certificate (reassignable) | network equipment enrolling through a shared service account |
Under Device binding a name or address the CSR repeats appears once in the certificate.
Allowed networks for IP SANs
Section titled “Allowed networks for IP SANs”Under Device binding the IP addresses in the certificate come from the device’s own request, so any account allowed to enroll could otherwise get a certificate naming any address. Fill in Allowed networks for IP SANs (CIDR, IPv4 or IPv6, one per line) to limit them:
- A request with an IP SAN outside every listed network is refused with a message naming the address, and the refusal is recorded in the Activity Log.
- DNS names are not restricted.
- An approval checks the list again when it is decided, since the list may have changed while the request waited.
- Empty means no restriction. Strict binding ignores the list: there the server writes the SAN itself and puts no IP address in it.
Approvals
Section titled “Approvals”With Require admin approval on, an enrollment produces a request, not a certificate.
This applies to renewals too. The client gets 202 Accepted with Retry-After: 30 and sends
the same CSR again, as RFC 7030 §4.2.3 describes. A request is identified by the SHA-256 of
its DER CSR, so a device that waits overnight leaves one row, not thousands.
| What the next poll finds | What the client gets |
|---|---|
pending | 202: keep waiting |
approved | 200 with the certificate the approval issued |
rejected | 403, so the client stops instead of polling forever |
expired | the request goes back to pending: a client still asking revives its own request |
The queue, EST enrollment requests, sits on the PKI page below the issued certificates, and is hidden while nothing is queued. Each row shows the subject, who requested it, from which address and when.
Deciding takes PKI edit rights (nac_pki.edit), not membership of the approval group.
The group is only a notification channel: each member with an email address gets a mail
saying what is being requested, by whom and from where, with a one-time link of their
own, valid for 7 days. A decision is therefore attributed to a person, not to whoever held
the link. No group means nobody is emailed, not that nothing is checked.
Opening a link decides nothing. Mail scanners and link previews open URLs on their own, so the link only shows the request, and the decision needs a button. A decision, by link or on the PKI page, spends every outstanding link for that request. A link stops working when its recipient’s account is disabled or deleted.
Approval puts a person in front of issuance and skips nothing. An approved request is signed
through the same path an automatic enrollment takes, with the same identity binding, the same
server-written SAN and the same allowed networks. Undecided requests older than the Request
lifetime are marked expired by the daily maintenance run (03:30).
Leave Require admin approval off for pilots and labs. Turn it on in production so a person reviews each request before a certificate is signed.
Refused enrollments in the Activity Log
Section titled “Refused enrollments in the Activity Log”Every EST outcome is recorded as one audit event type, NAC_PKI_EST_ENROLLMENT, so one
filter in the Activity Log shows the whole flow: issued, queued for approval, approved,
rejected and refused. Like every audit event, it is forwarded to the syslog destinations
bound to the audit stream (see Audit & syslog).
A refused request carries outcome: refused and a reason, plus the client’s address and
User-Agent, the endpoint, the gateway’s certificate verdict (for example
FAILED:certificate revoked) and the presented certificate’s serial and subject. EST clients
retry, and each refused request writes its own row.
reason | What happened |
|---|---|
est_disabled | EST is switched off |
est_ca_not_configured | No issuing CA is selected |
auth_method_not_allowed | The step is not allowed by Allowed authentication methods, or a first enrollment offered only a certificate |
csr_missing / csr_invalid | Empty body, or not a readable CSR with a valid signature |
basic_auth_malformed | The Authorization header is not valid HTTP Basic |
csr_identity_invalid | The identity binding cannot be applied, for example a Device-bound CSR with no DNS name or IP address |
ip_san_outside_allowed_networks | An IP SAN is outside Allowed networks for IP SANs |
reenroll_no_valid_client_cert | Renewal without a certificate the gateway verified: none, expired, revoked, foreign, or sent through 443 |
reenroll_cert_not_ours | The certificate is not one this Taranac issued |
reenroll_cert_not_active | Taranac holds the certificate as revoked or expired |
reenroll_subject_mismatch | The CSR’s subject differs from the certificate’s |
approval_rejected | The request was rejected, and the client polled again |
A wrong EST password is not an EST row. It is a failed login (USER_LOGIN_FAILED) marked
via: est, next to the console’s own failed logins. The first request without any
Authorization header is the normal challenge round trip and writes nothing.
Client compatibility
Section titled “Client compatibility”- Basic challenge. A refused
/simpleenrollanswers401withWWW-Authenticate: Basic realm="EST", so clients that send credentials only after a challenge (curl, libest and most embedded clients) enroll./simplereenrollsends no challenge: a password does not help there. - Base64 in 64-character lines. Certificates and CA chains are sent as base64 wrapped at
64 columns, which line-oriented clients such as Cisco IOS-XR need. Responses use
application/pkcs7-mime; smime-type=certs-onlywithContent-Transfer-Encoding: base64. - Each response header once. Strict clients reject a header that arrives twice.
- The request body is the base64 DER CSR (
application/pkcs10), at most 64 KB. - Cisco IOS-XE without a certificate of ours answers the gateway’s certificate request
with its own self-signed, often expired, HTTPS certificate, even for
/cacerts. The gateway treats that as no certificate, so the router enrolls by password like any other client. Such a certificate never renews. - TLS 1.2 and 1.3 are accepted on the gateway.
Ports and firewall
Section titled “Ports and firewall”Open these from the devices to every Taranac node they enroll with:
| Port | Proto | Serves | Variable |
|---|---|---|---|
443 | TCP | cacerts, csrattrs, simpleenroll (password) | EDGE_HTTPS_PORT |
8445 | TCP | all four, and the only place simplereenroll works | EST_GATEWAY_PORT |
To move the gateway, set EST_GATEWAY_PORT in .env and run ./taranac up -d. PKI Settings
shows the new value. Avoid ports other services on the node use: 8443 (MFA), 8444 (captive
portal) and 9443 (opened by ./taranac cluster add-node / add-witness for a join).
Troubleshooting
Section titled “Troubleshooting”| Symptom | Likely cause | Fix |
|---|---|---|
The device stops at the first 401 on /simpleenroll | The account is wrong, locked, disabled, outside its validity window, or a directory account | Check the account under Users and the USER_LOGIN_FAILED rows marked via: est. Use a local account. |
| The enrolling account keeps getting locked | A device retries with a stale password | Fix the password on the device, then unlock the account. |
422 on every request | EST is off, no issuing CA is selected, or the CSR is unreadable | Check the reason in the Activity Log. |
| The device does not trust the server on 8445 | It lacks the Infrastructure CA, or the address it uses is not in the gateway certificate | Install the bundle from Copy full-chain CA. Check TARANAC_NODE_IPS and run ./taranac up -d, or put in your own certificate with the right SANs. |
Renewal refused with reenroll_no_valid_client_cert | Renewal sent to 443; the certificate expired or was revoked; it comes from another CA; or EST_PROXY_KEY is empty | Send renewals to port 8445. An expired or revoked certificate enrolls again by password. Check that .env has EST_PROXY_KEY and the gateway logged no warning. |
Renewal refused with reenroll_cert_not_ours or reenroll_subject_mismatch | The certificate was not issued by this Taranac, or the new CSR changes the subject | Enroll by password. Keep the subject unchanged when renewing. |
ip_san_outside_allowed_networks | Device binding, and the CSR names an address outside the list | Correct the device’s address or extend Allowed networks for IP SANs. |
The client polls with 202 forever | Require admin approval is on and nobody decided | Decide the request on the PKI page. Set an Approval group so someone is emailed. |
429 | More than 10 enrollments or 30 renewals a minute from one address | Space the retries out. Many devices behind one NAT address share the limit. |
API endpoints
Section titled “API endpoints”The EST endpoints sit outside /api/v1, at the RFC 7030 well-known path, and answer only
while Enable EST endpoint is on.
| Endpoint | Authentication | Returns |
|---|---|---|
GET /.well-known/est/cacerts | none | The issuing CA’s chain up to its root, as PKCS#7 |
POST /.well-known/est/simpleenroll | HTTP Basic, local account | The issued certificate as PKCS#7, or 202 with Retry-After while a request awaits approval |
POST /.well-known/est/simplereenroll | the current client certificate, through the EST gateway | The renewed certificate as PKCS#7, or 202 as above |
GET /.well-known/est/csrattrs | none | The attributes a CSR should carry |
For the console and automation:
| Endpoint | Permission | Purpose |
|---|---|---|
GET /api/v1/nac/pki/settings/est-trust-bundle | nac_pki.view | The PEM that Copy full-chain CA copies |
GET /api/v1/nac/pki/est-requests | nac_pki.view | The approval queue |
POST /api/v1/nac/pki/est-requests/{id}/approve · …/reject | nac_pki.edit | Decide a request |
Why EST
Section titled “Why EST”Taranac uses EST rather than the older SCEP. EST runs over HTTPS, a first certificate is obtained with a password and a renewal with the certificate itself, and iOS, Windows, Android, ChromeOS and network operating systems support it.
Related
Section titled “Related”- PKI & trust: Internal CAs, revocation and CRLs, and the certificates EST issues.
- 802.1X authentication: how an EAP-TLS certificate becomes an identity.
- TACACS+ over TLS: devices that log in with a certificate enrolled over EST.
- Audit & syslog: the Activity Log and forwarding it to a SIEM.