TLS certificates
DTM terminates TLS in two places, and they have different certificate lifecycles. This page covers what serves which certificate, the two-year clock on the first-boot certificate, how to watch expiry, and how to rotate or bring your own.
Certificate inventory
Section titled “Certificate inventory”| Surface | Port(s) | Certificate |
|---|---|---|
| Web UI | 8080 |
The managed UI certificate at /etc/dtm/tls/ on each node: self-signed with 2-year validity at first boot, or one you supply. |
| REST API | 8443 |
By default, a fresh self-signed certificate at every service start. Configurable; see below. |
| DNS-over-TLS and DNS-over-HTTPS | 853, 443 |
Share the API’s certificate material; there is no separate DoT or DoH certificate. |
How the UI certificate is provisioned depends on how you deployed:
- Terraform: the primary node generates the certificate and key at first
boot and publishes them to Key Vault as the
dtm-tlssecret (a single combined PEM bundle, certificate plus key); every node reads the same bundle, so the whole cluster serves one UI certificate. The private key never enters Terraform state. See Terraform provider setup. - Azure Marketplace: each node generates its own self-signed UI certificate at first boot, with the node’s IP as the subject alternative name.
The two-year clock
Section titled “The two-year clock”The first-boot UI certificate is valid for 730 days and there is no automatic renewal. When it expires, browsers refuse the UI outright (a harder stop than the self-signed warning you already click through), so plan a rotation before the two-year mark. A natural moment is your regular certificate-hygiene cycle, or the first rotation onto a corporate-CA certificate, which makes the warning disappear too.
The API’s default certificate has no such clock: it is regenerated at every
service start, which is exactly why the examples in these docs use curl -sk
and why production clients that verify TLS should
give the API a stable certificate.
Check expiry
Section titled “Check expiry”On a node (the certificate directory is group-restricted, so the read needs
sudo):
sudo openssl x509 -in /etc/dtm/tls/cert.pem -noout -enddateOr from anywhere that can reach the UI:
openssl s_client -connect <node-ip>:8080 </dev/null 2>/dev/null \ | openssl x509 -noout -enddateThe Diagnose page also runs a certificate-validity check against a configured API certificate: it warns when the certificate is within 30 days of expiry and fails once it has expired, so it shows up in routine health reviews and in support bundles.
Rotate the UI certificate
Section titled “Rotate the UI certificate”Terraform deployments (one cluster-wide certificate)
Section titled “Terraform deployments (one cluster-wide certificate)”-
Produce a new combined PEM bundle: the certificate and its private key concatenated into one file. From your CA, or self-signed again:
Terminal window openssl req -x509 -newkey rsa:4096 -nodes -days 730 \-keyout key.pem -out cert.pem \-subj "/CN=dtm-ui" -addext "subjectAltName=DNS:dtm-ui"cat cert.pem key.pem > bundle.pem -
Update the
dtm-tlsKey Vault secret with the new bundle:Terminal window az keyvault secret set --vault-name <vault> --name dtm-tls --file bundle.pemIf you deployed with the write-only certificate variable, update through Terraform instead so your configuration stays the source of truth: set the new bundle in
dtm_ui_tls_pem_wo, incrementdtm_ui_tls_pem_wo_version(write-only values are never stored in state, so the version counter is what tells Terraform to re-send the bytes), and apply. -
On each node in turn, remove the installed pair and re-run the secret bootstrap, which re-fetches the bundle from Key Vault, validates that the certificate and key match (a mismatched bundle is refused rather than served), and installs it with the right ownership:
Terminal window sudo rm /etc/dtm/tls/cert.pem /etc/dtm/tls/key.pemsudo systemctl restart dtm-bootstrap.servicesudo systemctl restart dtm-ui
Rotating the UI certificate never touches DNS: only the UI service restarts.
Marketplace deployments (per-node certificates)
Section titled “Marketplace deployments (per-node certificates)”Each node manages its own pair at /etc/dtm/tls/. On each node, either install
your own certificate and key over the existing files, or delete both files and
restart dtm-bootstrap.service to mint a fresh two-year self-signed pair; then
restart dtm-ui. If you install files by hand, match the expected ownership,
since the UI refuses to start on a group- or world-readable private key:
sudo chown root:dtm-ui /etc/dtm/tls/cert.pem && sudo chmod 0640 /etc/dtm/tls/cert.pemsudo chown dtm-ui:dtm-ui /etc/dtm/tls/key.pem && sudo chmod 0400 /etc/dtm/tls/key.pemsudo systemctl restart dtm-uiBring a certificate from your own CA
Section titled “Bring a certificate from your own CA”Enterprise deployments usually want the UI on a certificate their browsers already trust:
- At deploy time (Terraform): supply a combined PEM bundle through the
write-only
dtm_ui_tls_pem_wovariable. It is written straight to thedtm-tlsKey Vault secret and never persisted to Terraform state, and the cluster boots directly onto your certificate instead of self-signing. - After deploy: follow the rotation procedure with your CA-issued bundle.
Issue the certificate with subject alternative names covering however your operators reach the UI (a DNS name you publish for the nodes, or the node IPs).
Give the API a stable certificate
Section titled “Give the API a stable certificate”To stop the API regenerating its certificate on every start, and to let API
clients (including the Terraform provider) verify TLS properly, point
dtm-server at certificate files on disk in /etc/dtm/dtm-server.yaml on each
node:
listen: tls: cert_file: /etc/dtm/api-tls/cert.pem key_file: /etc/dtm/api-tls/key.pemBoth fields must be set together, the key file must be readable by its owner
only, and a missing or unreadable file stops startup with a clear error rather
than silently falling back to self-signing. Restart dtm-server one node at
a time to pick the files up: a node stops answering DNS while it restarts, so
treat it like a step of a rolling upgrade.
The DNS-over-TLS and DNS-over-HTTPS listeners serve
the same certificate, so configuring this once also gives resolvers a
verifiable certificate on ports 853 and 443. Include every node’s address (or a shared
DNS name) in the certificate’s subject alternative names.
Next steps
Section titled “Next steps”- Rotating secrets: the rest of the cluster’s credential lifecycle in one place.
- Security: the full protections-and-responsibilities picture.