Skip to content

Security Trust Model

Telovix separates four independent trust domains: control-plane trust between sensors and the Console, policy trust for runtime behavior, operator access trust for the Console UI and API, and commercial trust for entitlements. Each domain has distinct mechanisms and failure modes. Understanding the boundaries prevents misdiagnosis when something goes wrong and prevents incorrect assumptions about what a compromised component can affect.


The four trust domains

DomainWhat it governsMechanism
Control-plane trustSensor identity and communication with ConsoleMutual TLS with per-sensor client certificates
Policy trustWhether a delivered runtime policy is trustedEd25519 signature verification per policy file
Operator access trustWho can read and write Console stateSession authentication, RBAC, optional SSO and MFA
Commercial trustWhether a deployment is entitled to runOffline Ed25519-signed license bundles

These four domains are intentionally independent. A compromised enrollment token does not affect policy trust. A license expiry does not revoke sensor certificates. A rogue operator session cannot bypass policy signature verification on the sensor.


Control-plane trust: sensor to Console

Enrollment

During enrollment, the sensor generates a local RSA key pair using rcgen and creates a Certificate Signing Request with CN=<node_name>, O=Telovix Sensor. It presents an enrollment token alongside this CSR to the Console enrollment endpoint. The Console verifies the token and signs the CSR, issuing a client certificate with a 720-hour (30-day) TTL by default.

The enrollment token is a bootstrap secret only. It is consumed at enrollment time. After enrollment, the durable sensor identity is the client certificate, not the token.

The Telovix Console returns:

  • control_plane_certificate_pem: the signed client certificate
  • control_plane_ca_certificate_pem: the Console's CA certificate
  • policy_signing_public_key_pem: the Ed25519 public key for policy verification
  • certificate_expires_at: expiry timestamp in RFC3339 format
  • certificate_reference: internal reference ID

The sensor atomically writes all of these to the state directory (/var/lib/telovix-sensor by default). The sensor-state.json file records trust_state="trusted" and renewal_status="ok".

All subsequent communication

Every heartbeat, WebSocket connection, and policy download uses outbound mTLS. The sensor presents its client certificate on every request. The Console validates the certificate against its CA on every request. There is no API key or session token fallback for sensor communication.

Renew certificates

Renewal is triggered automatically:

TriggerCondition
Proactive renewalCertificate expiry is less than 72 hours away

The renewal process generates a new CSR and submits it to the Console renewal endpoint. The Console issues a new certificate. The sensor writes the new key first, then the certificate, so that a crash mid-write triggers re-enrollment rather than leaving a corrupt state.

The default certificate TTL is 720 hours (30 days). The renewal-due threshold defaults to 86400 seconds (1 day).

Read trust states

StateMeaning
trustedCertificate is valid; mTLS is working
renewal_recommendedCert is approaching expiry but still within tolerance
renewal_dueCert expiry is within the renewal threshold; renewal should happen immediately
trust_revokedConsole revoked this sensor; mTLS will stop working

When trust state is trust_revoked, the Sensor stops forwarding events and the Console rejects requests from that identity. Review trust alerts and status from Sensors > Fleet and Sensors > Health Center.

Understand trust state and enforcement

Resolve sensor trust problems before changing enforcement. Confirm the intended rule and its sensor-reported delivery result in Runtime Blocks; a requested state alone does not establish active protection.


Policy trust: runtime behavior

Verify policy delivery

Runtime policies are delivered from the Console to the sensor as YAML files. Each policy file may be accompanied by a .sig sidecar file containing an Ed25519 signature, base64-encoded.

The Console holds an Ed25519 signing key at the path configured during setup (default: policy-signing.ed25519). The sensor receives the corresponding public key during enrollment and stores it at policy-signing.pub.

When loading a policy file, the sensor follows this logic:

  1. If a .sig sidecar exists: load the public key from policy-signing.pub, verify the signature against telovix-policy-v1:{policy_name}\n{yaml_content}, and reject the policy if verification fails.
  2. If no .sig sidecar exists but a signing key is present: log a warning and proceed (backward compatibility with pre-signing deployments).
  3. If no .sig sidecar and no signing key: skip verification.

The signature format telovix-policy-v1:{name}\n{content} binds the policy name to its content. A policy file cannot be renamed and applied under a different name without invalidating the signature.

This means a policy injected by an attacker who can write to the sensor's state directory but does not have the Console's Ed25519 private key will be rejected at load time.


Operator access trust

Authentication

Console users authenticate with email and password. Sessions are issued as secure, HTTP-only cookies. TOTP-based MFA is available for local accounts. The Console supports OpenID Connect (OIDC) for SSO through Okta, Microsoft Entra ID, Google Workspace, and generic OIDC providers. Administrators manage SSO from Settings > SSO.

API keys are scoped alternatives to session authentication for programmatic access. API keys are created by authenticated users and can be revoked individually.

Role-based access control

RoleLevelWhat it can do
viewer1Read-only access to sensors, events, and reports
analyst2All viewer permissions plus investigation and alert management
sensor_owner3All analyst permissions plus sensor management for owned sensors
operator3All analyst permissions plus policy management, enforcement changes, and exercise creation
admin4Full access including user management, settings, and license import

Role levels are enforced server-side on every request. The require_operator and require_admin middleware functions gate the relevant API routes. Role elevation requires an admin user.


Commercial trust: license validation

License structure

The Portal issues signed license bundles. Each bundle is a JSON envelope with the structure:

json
{
  "schema_version": 1,
  "signature_algorithm": "ED25519",
  "payload": {
    "customer_id": "...",
    "workspace_id": "...",
    "license_id": "lic-...",
    "plan": "growth",
    "max_protected_nodes": 250,
    "valid_from": "...",
    "valid_until": "...",
    "grace_until": "...",
    "issued_at": "..."
  },
  "signature": "<base64-encoded-ed25519-signature>"
}

The grace_until field extends the license beyond valid_until for a configurable grace period (default: 30 days). During the grace period, the deployment remains operational but the Console displays an expiry warning.

Signing

The Portal's license signing service exposes a single internal endpoint at POST /internal/v1/sign-license. This service is not reachable from the public internet. It loads the Ed25519 signing key from the path configured at deployment time, serializes the payload to canonical JSON, signs it, and returns the envelope. Communication between the Portal and the signing service is authenticated with a shared secret compared using constant-time comparison.

Console validation

The Console validates license bundles offline. It does not contact the Portal or any external service at validation time. The operator imports the signed bundle via the setup wizard or from Settings > License in the Console. The Console verifies the Ed25519 signature against its embedded public key and checks valid_until and grace_until against the current time.

This offline model means the Console continues operating in air-gapped or network-isolated environments as long as the imported license has not expired. The Console does not depend on Stripe connectivity, Portal availability, or any cloud service for runtime entitlement decisions.

Understand why commercial trust is separate

The Stripe payment flow, Portal workspace state, and billing webhook processing all feed the Portal. The Portal issues a signed license. The Console trusts only the signature on that license bundle, not any runtime state from Stripe or the Portal. This means:

  • Stripe refunds, disputes, or service outages do not affect the Console's license state
  • A compromised Portal cannot issue a license with capabilities beyond what the Ed25519 signing key authorizes
  • A stolen or replayed license bundle is only as dangerous as the private key that signed it

Trust boundary violations and what they mean

ViolationWhat is affectedWhat is not affected
Stolen enrollment tokenCan enroll a rogue sensor during the token's valid windowDoes not compromise existing sensors; revoke the token immediately
Stolen sensor client certificateCan send forged heartbeats from that sensor identityDoes not affect other sensors; revoke via Console trust management
Compromised policy signing keyCan inject arbitrary policy into sensors that trust this keyDoes not affect sensors with no signing key (they skip verification with a warning); rotate the key and re-enroll
Expired licenseConsole blocks new sensor enrollments above the node limit; grace period provides 30-day bufferDoes not revoke sensor certificates or stop active monitoring on enrolled sensors
Stolen operator sessionAttacker has operator-level Console accessCannot bypass mTLS on existing sensors; cannot forge signed policy without the Ed25519 key

Monitor trust from the Console

Console pageWhat it shows
Sensors > FleetFleet-wide trust summary, filters, and active trust-alert status
Sensors > Health CenterTrust, connectivity, and reporting diagnostics across the fleet
Sensor detail > OverviewTrust state and current Sensor identity summary
Settings > LicenseImport a signed license bundle; view current license status

Operational guidance

Do not share enrollment tokens across hosts. Each token should enroll one Sensor. Generate one token per node or cluster from Sensors > Deploy, then verify that the Sensor appears in Sensors > Fleet after enrollment.

Protect the policy signing key. Restrict access to the Console's signing key and include it in your protected backup procedure. If it is compromised, follow Policy Signing to rotate trust and replace signed policies.

Separate the license signing key from the Portal. The signing service runs as a separate process (backend-license). The key path should point to a key stored on a separate host or HSM. A compromised Portal cannot issue fraudulent licenses unless it can also reach the signing service and knows the shared secret.

Monitor trust alerts. Use the trust filters in Sensors > Fleet and the diagnostics in Sensors > Health Center to identify certificate expiry or revocation. Configure notifications so trust failures reach the responsible operators.


Further reading

Released under the Telovix Commercial License.