Skip to content

Rotate every certificate before the two-year mark

Twenty months in, the certificate clock is the quiet risk: the web UI’s first-boot certificate expires at two years (DTM renews its own self-signed one only from 1.0.2, and never one you supplied), the API listener’s self-signed bootstrap certificate (a different one on every node) renews itself from 1.0.4, but under a new key each time, and by now a small crowd of scripts, scrapers, and resolvers has opinions about which certificates they trust. This tutorial is the campaign: inventory both surfaces and their consumers, rotate each surface once, and leave alerts behind so the next expiry is a calendar entry, not an outage.

If all you need is the API listener on a corporate CA ahead of a DoT/DoH rollout, the encrypted DNS tutorial is that slice on its own; this page is the both-surfaces campaign.

Two surfaces, two lifecycles (the full table). Measure both on every node:

Terminal window
# Web UI (8080): the first-boot 730-day certificate
openssl s_client -connect 10.0.250.4:8080 </dev/null 2>/dev/null \
| openssl x509 -noout -enddate -issuer
# API listener (8443): each node's self-signed bootstrap certificate
# until you upload your own. DoT 853 and DoH 443 serve the same certificate.
openssl s_client -connect 10.0.250.4:8443 </dev/null 2>/dev/null \
| openssl x509 -noout -enddate -issuer -serial

Write the table down: surface, per node, issuer, expiry. On a 20-month-old default deployment you will find a UI certificate a few months from death and a self-signed API certificate on each node, each with its own serial and expiry; both are what this campaign fixes.

Every consumer that pins or validates these certificates needs the new CA chain, and finding them now is what stops the rotation from becoming its own incident:

  • Prometheus scrape tls_config (or its insecure_skip_verify: true standing in for one; see observability).
  • curl -sk and --cacert flags in backup jobs, automation, and runbooks.
  • DoT and DoH clients, if enabled: estate resolvers and the VDI fleet validate the API surface’s chain.
  • Browsers and anything else hitting the UI on 8080.
  • The Terraform provider’s TLS settings.

From the corporate CA, issue for the names and IPs consumers actually use (SANs per surface: node names and stable IPs for the API/DoT surface; the UI’s reachable names for 8080), and stage through Key Vault per your CA workflow. For the API surface you need the certificate chain and its unencrypted private key as PEM files. If you install API certificate files by hand instead of uploading them, two rules bite later: the listener refuses to start on a group- or world-readable private key, and a missing file stops startup with a clear error rather than silently self-signing (with listen.tls.managed off, or when only one of the two files is missing).

This surface is first because its consumers are machines you can fix immediately. The procedure is the stable certificate step: upload the certificate and key once, to any node. The cluster replicates them, and every node serves the new certificate from its next full TLS handshake with no restart, so DNS never blinks.

Verify on every node: the certificate GET on that page should report the node’s apply outcome as matching the stored certificate, and the served serial should be the same on every node:

Terminal window
openssl s_client -connect <node>:8443 </dev/null 2>/dev/null \
| openssl x509 -noout -serial
kdig @<node> app.example.internal +tls +tls-ca=corp-ca.pem # if DoT is on

Per your deployment dialect, using the rotation procedure: Terraform-managed clusters add a new version of one cluster-wide Key Vault bundle, which every node applies within the hour; Marketplace clusters rotate per node. Then verify the new expiry everywhere:

Terminal window
for n in 10.0.250.4 10.0.250.5 10.0.250.6; do
openssl s_client -connect $n:8080 </dev/null 2>/dev/null \
| openssl x509 -noout -enddate
done

On the Terraform path nothing restarts, and on the per-node path only the UI service does; DNS never blinks.

Walk the step-2 inventory and retire every workaround the self-signed era forced: --cacert instead of -sk, the CA in Prometheus tls_config with insecure_skip_verify: false, provider TLS verification on. The encrypted DNS tutorial walks this sweep; the verification is that every consumer stays green because it now validates, not despite it.

The product will not remind you about the UI certificate, and it never renews a CA-issued one: the built-in Diagnose warning (at 30 days) and, from 1.0.4, the DTMTLSCertificateExpiringSoon alert (at 21 days) cover only the API certificate, and never the UI surface; and either is too late to start corporate-CA issuance anyway. So the guard is yours:

  • Record both new expiry dates where your team plans work.
  • Alert at 90 days out (a calendar entry, or a probe-based cert-expiry alert in your monitoring stack against both ports).
  • The quarterly maintenance pass carries the recurring expiry audit; with this campaign done, its certificate check becomes a ten-second confirmation.

Need a hand? Email [email protected].

Last validated: 2026-07-27