TLS and Certificates
The Director's HTTP configuration server terminates TLS for agent check-in, pipeline delivery, CA distribution, and installer downloads. TLS is configured through the proxy_tls block delivered via node or cluster properties on the platform. Users do not edit vmetric.yml for TLS — all settings are managed through the web interface.
This page documents the web interface that manages these settings, then the certificate authorities involved, the proxy_tls fields, the certificate resolution order, and the bootstrap endpoints used by agents to trust a self-signed Director. Cluster inter-node TLS is a separate concern, documented under Environment Files.
Which CA Do You Need?
DataStream has no global certificate authority store. A CA is never added to the Director as a whole — it is always attached to one specific connection. Three distinct settings are all called a CA, and they solve different problems:
| Goal | Configured on | Field |
|---|---|---|
| Agents must trust this Director | the Director | proxy_tls.ca_name |
| The Director must trust a private CA on a device or target it connects to | that device or target | tls.ca_name |
| Incoming client certificates must be validated (mTLS) | that device | tls.client_ca_name |
Setting ca_name replaces the trust store for that connection rather than adding to it. Once a CA is named, certificates issued by public authorities are no longer accepted on that connection. A connection that reaches both an internal and a public endpoint needs both authorities in a single PEM bundle. Apache Kafka is the sole exception: it appends the named CA to the host trust store.
TLS material fields (cert_name, key_name, ca_name, client_ca_name) accept any of the following:
- File name — resolved relative to the service root directory. Nested paths such as
certs/prod/server.pemare supported. - Absolute path — honored only if it resolves inside the service root. Any path that escapes the root is refused.
- Inline PEM content — used verbatim when the value contains
-----BEGIN. - Environment variable —
${ENV_VAR}. - Vault reference —
$secret{id=...}or$secret{store=...,ref=...}.
A path outside the service root is refused, and the field is reported as unresolvable. To use a CA held elsewhere on the host — /etc/ssl/certs/, for example — copy it under the service root first, or paste its PEM content inline.
Configuring TLS in the Web Interface
TLS is set on the TLS Configuration step of the Director creation wizard, and can be changed afterwards from the TLS Configuration tab of the Director detail view.
Under proxy_tls.mode values they write:
| Tile | proxy_tls.mode | Description |
|---|---|---|
self-signed | The director manages its own certificate authority (CA) and certificates. | |
custom | The director uses your certificate and private key. Ideal for organizations with an existing PKI. | |
offloaded | TLS termination is handled by your load balancer. |
Switching tiles clears every field belonging to the previous mode.
The web interface covers a subset of the proxy_tls surface. A PKCS#12 (PFX) bundle can only be supplied through node properties — the interface offers no PFX upload or PFX password control, and no ca_name control. Those remain configuration-only, as does insecure_skip_verify.
Auto-generated
The Director issues its own certificate. No certificate input is required, and the interface displays the issuer as VirtualMetric Director Root CA, the server certificate lifetime as 90 days, and the CA lifetime as 10 years.
| Field | Required | Default | Description |
|---|---|---|---|
| Y | 443 | Handles all agent check-ins, configuration updates, and data transfers | |
| N | Enabled | Provides the installation script and CA certificate required for enrolling new agents | |
| Y* | 80 | Used exclusively for initial agent onboarding and discovery |
* = Required when the Discovery Endpoint is enabled
Disabling the Discovery Endpoint means agents cannot retrieve the root certificate automatically. Download it from the Director after setup and install it on each agent before deployment.
Custom certificate
Supply your own certificate and private key. Each carries a
| Type | Value supplied as |
|---|---|
| PEM content, pasted into the field or loaded with | |
| An existing multi-line vault secret, selected from a list | |
| A path to the file on the Director host |
| Field | Required | Default | Description |
|---|---|---|---|
| Y | - | Certificate in PEM format, a vault secret, or a path | |
| Y | - | Private key in PEM format, a vault secret, or a path | |
| N | - | Passphrase protecting the private key. Supplied as | |
| Y | - | The host name agents use to connect. Must match a SAN in the certificate | |
| Y | 443 | As above | |
| N | Disabled | As above |
The passphrase applies to the private key only; the certificate itself carries no passphrase control.
The Path type is documented as a web interface control only, and its YAML equivalent is unresolved. The interface writes a path-typed value using a token form the frontend source itself marks as provisional, and the Director's certificate resolution recognizes no such token — it accepts an environment reference, a vault reference, inline PEM, or a path under the service root, and nothing else.
Until the platform team confirms the intended token, do not assume a path selected in the interface has a hand-writable YAML form. For configuration written by hand, supply the certificate as inline PEM, a vault reference, or a path under the service root, all of which are confirmed. This section changes if the token is settled or dropped.
The interface parses the certificate and lists its issuer, subject, expiry and SANs. When the certificate carries usable SANs, the Director address is chosen from them; when it carries none, or only a wildcard, enter a
A certificate that has already expired blocks the wizard — the step cannot be completed until a valid one is supplied.
If your certificate is issued by an intermediate CA, include the full chain in the file, server certificate first. All agent machines must trust your CA before the agent is deployed; for machines outside your domain, including Linux hosts, install the CA certificate manually beforehand.
TLS offloading
An upstream load balancer terminates TLS and forwards plain HTTP to the Director.
| Field | Required | Default | Description |
|---|---|---|---|
| Y | 80 | Receives traffic from a trusted load balancer after TLS termination | |
| N | Disabled | The external address presented to agents, used in enrollment instructions and agent configuration | |
| Y* | - | The FQDN or IP agents use to connect |
* = Required when the external URL is enabled
Selecting this mode changes the port default from 443 to 80.
In this mode the Director accepts unencrypted connections on its agent communication port. Ensure the connection between the load balancer and the Director is on a trusted network.
Editing TLS after creation
Open the Director from the table and select the TLS Configuration tab. Certificate, private key and passphrase are masked until you click
The private key is never displayed. Where a certificate or key is stored as a vault secret, the interface cannot parse it to show the certificate details.
Changing the mode raises a
The tab is unavailable on Directors below version 2.0 and displays an upgrade notice instead. No separate permission governs TLS — editing requires the same permission as any other Director change.
Root CA Certificates
Distributing the Director CA to agents
An agent will not connect until it trusts the certificate the Director serves. In self-signed mode this happens automatically; in custom mode it is your responsibility.
| Mode | How agents obtain the CA |
|---|---|
self-signed, Discovery Endpoint enabled | Automatically, from the plain-HTTP discovery endpoint /ca.pem during enrollment |
self-signed, Discovery Endpoint disabled | Manually — download it from the Director and install it on each agent before deployment |
custom | Manually — every agent machine must already trust your CA before the agent is deployed |
To download the CA, open the Director from the table, select the TLS Configuration tab, and click ca.crt. The same control is available on the Cluster detail view, where it serves the cluster's CA. It appears in the detail view only, not in the creation wizard, since no CA exists until the Director is created.
Agents that have already connected recover on their own: when a Director's certificate changes and the agent's stored CA no longer verifies it, the agent re-bootstraps the CA over its existing channel. See Agent bootstrap below.
Trusting a private CA
When the Director connects out — to a device it polls, or a target it delivers to — and that endpoint presents a certificate from an internal authority, name the authority on that device or target, not on the Director:
tls:
status: true
ca_name: internal-root-ca.pem
The field is tls.ca_name on most devices and targets. A few target families read it at the top level rather than nested under tls:, and the flat-schema targets engage TLS from an https:// endpoint scheme instead of a status field — the field tables on each device and target page are authoritative. Devices that terminate TLS rather than dial out have no ca_name at all; they use tls.client_ca_name to validate incoming client certificates, which is a different job.
Both traps described under Which CA Do You Need? apply here: the named CA replaces the host trust store for that connection, and the file must resolve under the service root.
Modes
The Director listener operates in one of three TLS modes, selected by proxy_tls.mode:
| Mode | Description |
|---|---|
self-signed | Default. Director serves its own certificate. Agents bootstrap the CA through the plain-HTTP discovery endpoints (/ca.pem, /install.ps1, /install.sh). |
custom | Operator provides a certificate as a PEM pair or a PKCS#12 (PFX) bundle, supplied either inline in the node configuration or as files on disk. |
offloaded | An upstream load balancer terminates TLS. The Director skips its own HTTPS listener and serves plain HTTP to the upstream tier. |
Configuration
The proxy_tls block carries the listener configuration delivered through node or cluster properties. Cluster-scoped values override node-scoped values, and node-scoped values override system defaults.
proxy_tls:
mode: self-signed # self-signed | custom | offloaded
status: false # enable the HTTPS listener
cert_name: cert.pem # PEM cert file under the Director root, or inline PEM starting with "-----BEGIN"
key_name: key.pem # PEM key file under the Director root, or inline PEM starting with "-----BEGIN"
pfx_name: cert.pfx # PKCS#12 bundle file under the Director root
pfx_password: "" # PFX password; overridden by VMETRIC_PFX_PASSWORD env var
ca_name: ca.pem # CA file under the configuration directory, or inline PEM
port: 443 # HTTPS listener port
discovery_enabled: true # serve /ca.pem, /install.ps1, /install.sh on plain HTTP
external_url: "" # public URL used in install scripts when Director is behind a load balancer or NAT
| Field | YAML Path | Type | Default | Required |
|---|---|---|---|---|
| Mode | proxy_tls.mode | string | self-signed | Y |
| Status | proxy_tls.status | bool | false | N |
| Cert Name | proxy_tls.cert_name | string | -- | Y* |
| Key Name | proxy_tls.key_name | string | -- | Y* |
| PFX Name | proxy_tls.pfx_name | string | -- | Y* |
| PFX Password | proxy_tls.pfx_password | string | -- | N |
| CA Name | proxy_tls.ca_name | string | -- | N |
| Port | proxy_tls.port | int | 443 | N |
| Discovery Enabled | proxy_tls.discovery_enabled | bool | true | N |
| Discovery Port | proxy_tls.discovery_port | int | -- | N |
| External URL | proxy_tls.external_url | string | -- | N |
* = Conditionally required. In custom mode, supply either cert_name + key_name or pfx_name (with pfx_password where applicable). In self-signed mode, the Director generates its own material. In offloaded mode, no certificate is read.
proxy_tls.ca_name is the certificate agents download and trust — the authority the Director publishes, not an authority it trusts. When it is unset, the Director extracts the issuing chain from the certificate it serves and publishes that instead.
The two file-path bases in this block differ. cert_name, key_name and pfx_name resolve against the Director root; ca_name resolves against the configuration directory beneath it. A bare file name is the reliable form for all four.
When the Director sits behind a load balancer or NAT and its bind address differs from the address agents use to reach it, set external_url to the public base URL (e.g., https://lb.example.com). The Director substitutes this URL into the generated install scripts (/install.ps1, /install.sh) instead of the listen address. In offloaded mode the public port is embedded in external_url itself and proxy_tls.port is not appended; in self-signed and custom modes proxy_tls.port is appended when external_url omits a port.
The cert_name, key_name, pfx_password, and ca_name fields support Vault credential references. Instead of embedding a literal value, supply an environment variable (${VAR_NAME}) or a vault token ($secret{store=<name>,ref=<value>} or $secret{id=<id>}). The Director resolves the reference at startup with a 30-second timeout. If resolution fails, the HTTPS listener does not start and the error is logged with the specific field that failed.
Certificate resolution
Before evaluating the priority chain below, the Director resolves any credential references in the proxy_tls field values (environment variables and vault tokens). Resolution uses a 30-second timeout per field. On failure, the Director logs a field-specific error and aborts HTTPS startup.
Once references are resolved, certificate material is selected in the following order. The first step that yields a usable pair is used; later steps are not consulted.
- Node PFX --
proxy_tls.pfx_nameresolved relative to the Director root. The password comes from theVMETRIC_PFX_PASSWORDenvironment variable if set, otherwise fromproxy_tls.pfx_password. - Node inline PEM --
proxy_tls.cert_nameandproxy_tls.key_namevalues that start with-----BEGINare treated as inline PEM content and consumed in memory without writing to disk. When no explicit CA is configured, the Director extracts intermediates and the root from the cert chain. - Node PEM files --
proxy_tls.cert_nameandproxy_tls.key_nametreated as file paths. Relative names are joined onto the Director root; an absolute path is honored only while it stays inside that root. Any value that escapes the root is rejected and the step is skipped. - Disk fallback --
cert.pem,key.pem, and optionalca.pemplaced directly in the Director configuration directory. Ifca.pemis absent, the Director attempts to extract the CA chain from the certificate file.
If no certificate material is available, the Director logs a single warning and continues polling every five seconds until the platform API delivers one. The HTTPS listener does not start until resolution succeeds.
Certificate reload
File-based certificates reload automatically on the next TLS handshake after the file modification time changes. The Director pre-loads material at startup so configuration errors surface immediately rather than on first connection. Inline PEM material delivered through node configuration is static until the platform re-delivers the node properties.
The TLS listener enforces a minimum protocol version of TLS 1.2.
Agent bootstrap
In self-signed mode with discovery_enabled: true, the Director serves three discovery endpoints over plain HTTP so that agents can trust the self-signed certificate before establishing an HTTPS session:
| Endpoint | Purpose |
|---|---|
/ca.pem | CA certificate used to verify the Director during the initial TLS handshake. |
/install.ps1 | PowerShell installer. The embedded Director URL is substituted from the request host. |
/install.sh | POSIX shell installer. Line endings are normalized to LF before delivery. |
User-Agent routing on the /dl/ path serves install.ps1 to PowerShell clients, install.sh to curl or wget, and redirects any other client to the VirtualMetric website.
Bootstrap only ever acquires a CA the agent does not have; it never replaces one already in place. An agent configured with an explicit CA does not bootstrap at all.
The legacy plain-HTTP routes /status and /ws respond with the Deprecation: true header and an X-VirtualMetric-Upgrade header instructing agents to upgrade to the HTTPS channel. These routes are removed in the next major version.
Download limits
Both the CA and agent-binary download endpoints are semaphore-protected. When the concurrency cap is reached, the Director responds with HTTP 503 and a Retry-After header; the installer scripts respect this backoff automatically.
| Endpoint | Max Concurrent | Retry-After |
|---|---|---|
/dl/cert.pem | 50 | 10 s |
/dl/agent/{os}/{arch} | 5 | 30 s |
Supported operating systems for agent binary download: aix, darwin, freebsd, linux, netbsd, openbsd, solaris, windows. Supported architectures: amd64, arm64, 386, ppc64, ppc64le. An optional /dl/agent/{os}/{arch}/sign path serves the detached signature.
Messaging TLS
The VMMQ messaging client automatically adapts its connection scheme to match the Director listener: http:// becomes ws://, and https:// becomes wss://. When the Director is configured with TLS, the client enforces TLS 1.2 or higher and attaches client certificates when mutual TLS is enabled on the platform.
When the client encounters the NATS error certificate signed by unknown authority and no CA certificate is available locally, it automatically bootstraps the CA by:
- Waiting a random interval between 0 and 30 seconds to avoid thundering herd on large fleets.
- Downloading
/dl/cert.pemfrom the Director withInsecureSkipVerifyenabled for the duration of the bootstrap handshake. - Validating the returned PEM block and persisting it locally as
ca.pem. - Rebuilding NATS options with the new CA and retrying the connection. Backoff for subsequent retries is
5s * errCount, capped at 30 seconds.
Hostname verification is intentionally skipped on the self-signed path because the Director certificate omits SANs by design; chain verification against the bootstrapped CA still runs on every connection.
Resolving certificate errors
| Symptom | Cause | Resolution |
|---|---|---|
certificate signed by unknown authority | The presenting party's CA is not trusted. On a connection that already names a ca_name, the host trust store has been replaced, so a publicly issued certificate fails here too. | Add the issuing authority. Where both an internal and a public authority are needed on one connection, concatenate them into a single PEM bundle. |
| A certificate, key or CA is reported as unresolvable, and the HTTPS listener does not start | The configured path escapes the service root. Absolute paths outside the root are refused rather than read. | Copy the file under the service root and reference it by name, or paste its PEM content inline. |
| Agents cannot connect after a certificate change | The address agents use is not present as a SAN in the new certificate. | Reissue the certificate with that address as a SAN, or set |
A certificate in use can be inspected without stopping the service. See Director CLI for the cert mode, which reports the active TLS mode, the material source, and the leaf and chain details.
Examples
Self-signed (default) -- the Director generates its own certificate and agents bootstrap the CA through the discovery endpoints... | |
Custom PEM with explicit CA -- operator-supplied certificate, key, and CA delivered through node properties. The names resolve under the Director root, with the CA taken from the configuration directory... | |
Custom with vault -- certificate and key fetched from a credential store at startup; the PFX password sourced from a secrets registry entry... | |
Custom PKCS#12 bundle -- single PFX file under the Director root with the password sourced from the environment... | |
Offloaded -- TLS terminates at the upstream load balancer and the Director skips its own HTTPS listener... | |