Appearance
mTLS and Certificate Management
Every connection between a sensor and the Console uses mutual TLS. The sensor presents a client certificate, and the Console presents its server certificate; both sides verify each other. There is no fallback to API keys or shared secrets for sensor communication.
Prerequisites
- Console already installed and running (Telovix self-hosted)
- TLS certificate files already generated (server cert, CA cert, issuer key)
adminrole to configure TLS settings- Each sensor must reach the Console on the configured port
Network topology
The sensor always initiates outbound connections to the Console. Two ports are involved:
| Port | Purpose |
|---|---|
| 15483 | HTTP API port (used by sensors for enrollment, heartbeat, and all sensor communication; also serves the operator UI and API) (Telovix self-hosted default) |
| 15484 | Dedicated mTLS sensor listener (alternate; configurable in Console Settings) |
The sensor's Console URL is set during sensor setup and points to port 15483 (Telovix self-hosted default). The Console configuration determines which listener handles sensor mTLS traffic. In the default configuration, sensor traffic goes to 15483.
The Console makes no inbound connections to sensors. Sensors connect out; the Console responds.
Enrollment: initial certificate issuance
What the sensor does
At first startup after the binary is installed, the sensor performs enrollment:
- Reads the configured Console URL and enrollment token from its configuration.
- Fetches the Console CA certificate from the trust bootstrap endpoint (using Bearer token auth).
- If a bootstrap CA certificate path is configured, loads that PEM as the CA trust anchor for the enrollment-only phase. If not set, accepts self-signed certs with a warning log.
- Generates an RSA key pair locally using
rcgen. - Creates a Certificate Signing Request with
CN=<node_name>, O=Telovix Sensor. - Submits the enrollment request with the enrollment token, CSR PEM, node name, declared role, tags, software version, and Kubernetes cluster name if applicable.
What the Console returns
json
{
"sensor_id": "...",
"control_plane_certificate_pem": "...",
"control_plane_ca_certificate_pem": "...",
"policy_signing_public_key_pem": "...",
"certificate_expires_at": "2026-06-01T00:00:00Z",
"certificate_reference": "..."
}The Telovix Console signs the CSR using its issuer key and returns the signed client certificate with a TTL of 720 hours (30 days) by default.
Store credentials
The sensor atomically writes credentials to the state directory (/var/lib/telovix-sensor by default):
/var/lib/telovix-sensor/
├── client.key.pem (mTLS client private key)
├── client.cert.pem (mTLS client certificate)
├── client.prev.key.pem (previous key kept for overlap period)
├── client.prev.cert.pem (previous cert kept for overlap period)
├── console-ca.cert.pem (Console CA certificate)
├── policy-signing.pub (Ed25519 public key for policy verification)
└── sensor-state.json (enrollment state, trust_state, cert expiry, renewal status)After successful enrollment, sensor-state.json records trust_state="trusted" and renewal_status="ok".
Subsequent connections
After enrollment, the sensor builds a reqwest::Client with the mTLS identity (client key + cert + Console CA). All heartbeats, WebSocket connections, policy downloads, and upgrade requests use this client. The enrollment token is never used again.
Steady-state: certificate use
The sensor sends a heartbeat every 30 seconds over mTLS. The client certificate identifies the sensor; the Console verifies it against the issuer CA on every request. The current certificate trust state is reported in every heartbeat payload and is visible on the sensor's detail page in Sensors.
The WebSocket stream for real-time event delivery also uses mTLS via tokio_tungstenite with a rustls connector.
Renew certificates
Triggers
| Trigger | Condition |
|---|---|
| Proactive | Certificate expiry is less than 72 hours away |
| Manual | Operator triggers renewal from Sensors > [sensor] > Renew Certificate (increments the manual_renewal_generation counter; sensor picks this up on the next heartbeat) |
Renewal process
- Sensor generates a new RSA key pair and CSR.
- Submits the renewal request over the existing mTLS connection.
- Console issues a new certificate with a fresh TTL.
- Sensor writes the new key first, then the certificate (atomic ordering). If the process crashes between these two writes, re-enrollment is triggered rather than a corrupt state.
- Previous credentials are retained as
client.prev.key.pemandclient.prev.cert.pemfor the overlap period.
The overlap period (default 86400 seconds) allows the previous certificate to remain valid during the transition.
Renewal timing
The following thresholds apply by default and are configurable in Console Settings:
| Setting | Default | Meaning |
|---|---|---|
| Certificate TTL | 720 hours (30 days) | Certificate TTL issued to sensors |
| Renewal recommended threshold | 259200 seconds (3 days) | Threshold for renewal_recommended trust state |
| Renewal due threshold | 86400 seconds (1 day) | Threshold for renewal_due trust state; sensor begins proactive renewal |
| Renewal overlap | 86400 seconds (1 day) | Previous cert validity after renewal |
| Trust error recent window | 900 seconds (15 min) | Window for classifying a trust error as recent |
Trust states
| State | Meaning |
|---|---|
trusted | Certificate is valid; renewal is not yet approaching |
renewal_recommended | Certificate expiry is within 3 days; renewal is advised |
renewal_due | Certificate expiry is within 1 day; sensor is initiating proactive renewal |
trust_revoked | Operator has revoked this sensor; mTLS requests are rejected |
Trust state is evaluated on every heartbeat. The Console maintains trust health at the fleet level, visible on the Fleet view trust summary, and exposes active trust alerts on the Trust Alerts page.
Revoke or disable a sensor
Both operations require the admin role and are recorded in the audit log.
Disable
In the Console, navigate to Sensors, click the sensor name to open its detail page, and click Disable Sensor.
Sets the sensor status to disabled. The sensor can no longer send accepted heartbeats. Telco snapshots are cleared asynchronously. The sensor identity is preserved and the sensor can be re-enabled.
Use disable for temporary suspension: planned maintenance, node rebuild, or investigation hold.
📸 Screenshot: sensor-detail-disable Sensor detail page showing the Disable Sensor action in the Actions menu.
Revoke
In the Console, navigate to Sensors, click the sensor name to open its detail page, and click Revoke Sensor.
Sets the sensor status to revoked and sets trust_state to trust_revoked. The Console rejects all mTLS requests from this sensor identity. Telco snapshots are cleared. The sensor is visible in the Console but cannot reconnect without a new enrollment.
Use revoke when a node is decommissioned, rebuilt from scratch, or its certificate material may be compromised. After revocation, generate a new enrollment token and re-enroll the rebuilt node.
Configure Console TLS
The Console requires several TLS files to operate the sensor mTLS listener. These are provided during Console installation and managed through the setup wizard.
| File | Required | Description |
|---|---|---|
| Server certificate | Yes | Console server certificate presented to sensors |
| Server private key | Yes | Console server private key |
| Client CA certificate | Yes | CA cert used to verify sensor client certificates |
| Issuer certificate | Yes | Issuer certificate used to sign sensor client CSRs |
| Issuer private key | Yes | Issuer private key used to sign sensor client CSRs |
| mTLS bind address | No | mTLS bind address (default: 0.0.0.0) |
| mTLS listener port | No | mTLS listener port (default: 15484) |
The issuer cert and key are what the Console uses to sign sensor CSRs during enrollment and renewal. The client CA cert is what the Console uses to verify incoming mTLS connections from sensors. In a standard deployment these are related: the issuer is the CA, so the issuer cert and the client CA cert are the same file.
The server cert and key are the Console's own identity, presented to sensors during TLS handshake so sensors can verify they are connecting to the right Console.
Monitor trust health
Fleet trust summary
In the Console, navigate to Fleet. The trust health summary is displayed in the header row, showing counts by trust state and sensors with active alerts.
📸 Screenshot: fleet-trust-summary Fleet view header showing trust state counts: trusted, renewal_recommended, renewal_due, and revoked sensors.
Trust alerts
In the Console, navigate to Fleet > Trust Alerts. This page lists all active trust alerts across the fleet. Alert types include certificate nearing expiry (renewal_recommended, renewal_due) and active trust errors.
Per-sensor trust detail
In the Console, navigate to Sensors, click a sensor name, and select the Trust tab. This shows enrollment status, certificate expiry timestamp, certificate reference, current trust state, renewal status, and any active trust alerts for that sensor.
📸 Screenshot: sensor-trust-tab Sensor detail Trust tab showing certificate expiry date, trust state badge, renewal status, and the manual renewal button.
Manual renewal trigger
In the Console, navigate to Sensors, click the sensor name, select the Trust tab, and click Trigger Renewal. This increments the manual_renewal_generation counter on the Console. The sensor reads this on its next heartbeat and initiates a renewal cycle.
Troubleshooting
Sensor fails enrollment
The enrollment token may have expired or already been used, or the Console URL is not reachable from the sensor node. Verify the token is still valid by checking its timestamp in the Console. Confirm the Console URL is reachable from the sensor host. If the Console uses a self-signed or private CA certificate, configure the bootstrap CA certificate path (set during sensor setup) to the Console's CA certificate PEM file before enrolling.
Sensor enrolled but heartbeats rejected
The client certificate may have expired or been revoked. Check sensor-state.json in the sensor state directory for the trust_state field. If the value is trust_revoked, re-enroll the sensor using a new token from the Console. If certificate_expires_at is in the past, trigger re-enrollment.
Clock skew causes certificate rejection
TLS certificate validation is sensitive to system clock accuracy. A sensor node with a clock significantly behind the real time will treat a valid certificate as not-yet-valid; a clock that is ahead will treat a valid certificate as already expired. Verify NTP synchronization on both the Console host and all sensor nodes:
bash
timedatectl statusExpected output on a synchronized host:
Local time: Thu 2026-04-26 14:22:00 UTC
Universal time: Thu 2026-04-26 14:22:00 UTC
RTC time: Thu 2026-04-26 14:22:00
Time zone: UTC (UTC, +0000)
System clock synchronized: yes
NTP service: active
RTC in local TZ: noIf System clock synchronized: no or NTP service: inactive, enable NTP synchronization before attempting enrollment or renewal.
Checking trust state from the sensor host
If the Console shows a sensor with an unexpected trust state, verify the sensor's local trust record:
bash
cat /var/lib/telovix-sensor/sensor-state.jsonExpected output on a healthy sensor:
json
{
"sensor_id": "tlvs_...",
"trust_state": "trusted",
"certificate_expires_at": "2026-06-01T00:00:00Z",
"renewal_status": "ok"
}If trust_state is trust_revoked, re-enroll the sensor using a new token from the Console. If certificate_expires_at is in the past, the sensor should have already attempted automatic renewal; check the sensor logs for renewal errors.
Renewal stuck in renewal_due
The sensor cannot reach the Console due to a network partition or firewall rule change, so proactive renewal is failing silently. The sensor continues to operate on the existing certificate until it expires. Restore connectivity between the sensor and Console and renewal will complete automatically on the next heartbeat attempt.