Skip to content

Policy Signing

The Telovix Console signs policy files before delivering them to sensors. Each sensor verifies the signature before loading or activating any policy. This prevents a policy from being tampered with after the Console dispatches it and ensures that a policy active on a sensor can be traced back to a specific reviewed and authorized artifact.

This matters most for enforcement-mode deployments. When a policy controls whether processes are killed or network connections are dropped, operators need to know that what is running on the sensor is exactly what was reviewed in the Console.

Prerequisites

  • Console already installed and running
  • Ed25519 signing key generated (or use existing key)
  • admin role to configure the signing key path

How signing works

Signing side (Console)

The Console holds an Ed25519 private key at the path configured during setup (default: policy-signing.ed25519). When a policy is prepared for delivery, the Console signs each policy YAML file using this key.

The signed message for each policy file is:

telovix-policy-v1:{policy_name}\n{yaml_content}

The policy name is the filename without path. The YAML content is the full text of the policy file. Binding the name to the content means a valid signature for policy-1.yaml cannot be applied to a policy with a different name. The resulting signature is base64-encoded and written to a sidecar file with the same name and a .sig extension.

Verification side (sensor)

During enrollment, the Console returns the corresponding Ed25519 public key (policy_signing_public_key_pem). The sensor stores it as policy-signing.pub in the state directory.

When the sensor loads delivered policies, it applies this logic to every YAML file:

  1. If a .sig sidecar exists alongside the policy YAML:
    • Load the public key from policy-signing.pub
    • Base64-decode the signature from the sidecar
    • Reconstruct the message: telovix-policy-v1:{policy_name}\n{yaml_content}
    • Verify the signature using Ed25519
    • If verification fails: reject the policy file (not loaded, not applied)
  2. If no .sig sidecar exists but a signing key is present in the state directory:
    • Log a warning
    • Proceed with loading (backward compatibility with pre-signing deployments)
  3. If no .sig sidecar and no signing key present:
    • Skip verification and load the policy

Case 1 is the production behavior. Cases 2 and 3 exist to avoid hard failures in configurations that were deployed before policy signing was introduced.


Legacy policy pack file structure

Older Policy Pack assignments remain on the sensor after the assignment screen is retired. Their policy files are stored locally at the sensor in compiled-policies/{pack_id}/{pack_version}/. Each policy YAML has a corresponding .sig sidecar when signing is active:

compiled-policies/
└── pack-security-v2/
    └── 2.0.0/
        ├── policy-1.yaml
        ├── policy-1.yaml.sig
        ├── policy-2.yaml
        ├── policy-2.yaml.sig
        └── ...

The sensor reads all .yaml files in the directory. For each one it checks for a .sig sidecar before proceeding. The public key is loaded from policy-signing.pub in the root state directory, not from within the pack directory.


TLS uprobe auto-generated policies

The TLS monitoring module generates policy files at sensor startup from /proc inspection and writes them to compiled-policies/tls-uprobe-*.yaml. These auto-generated files are not signed because they are created locally by the sensor process itself, not delivered from the Console. The sensor does not attempt signature verification on files it generated locally.


Configure Console signing

Configure the policy signing key path during Console setup (default: policy-signing.ed25519). The Console loads the signing key at startup. If the file is missing or unreadable at startup, policy signing is disabled and the Console delivers all policies unsigned (case 3 behavior on sensors).

Generate the signing key

The Console requires an Ed25519 private key in PEM format. Generate one with:

bash
openssl genpkey -algorithm Ed25519 -out policy-signing.ed25519

Store this file at the path configured during setup. The Console derives the public key from the private key internally; you do not need to provide the public key separately. The public key is distributed to sensors during enrollment.


Sensor state files

FileContents
policy-signing.pubEd25519 public key received from Console at enrollment
compiled-policies/Directory containing policy packs by {pack_id}/{pack_version}/
assigned-pack.jsonLegacy assignment metadata, when present

The public key in policy-signing.pub is set once at enrollment. It is updated if the sensor re-enrolls. It does not change during normal certificate renewal.


What happens when verification fails

If a policy file's signature does not verify against the known public key, the sensor rejects that policy file. It is not applied to the runtime engine. The sensor logs a rejection at error level including the policy name and the nature of the failure.

The remaining policy files in the same pack are evaluated independently. A tampered file is excluded from the Sensor's active rule set until the pack is redelivered with a valid signature.

This behavior is intentional. Failing silently (loading the policy anyway) would make signing useless for security. Failing hard for the entire pack would create a denial-of-service vector where any corrupted file removes all policy protection.


Rotate the signing key

When the policy signing key must be rotated (Console host compromise, key material exposure, or scheduled rotation):

  1. Generate a new Ed25519 private key and replace the file at the configured signing key path.
  2. Restart the Console to load the new key.
  3. Re-sign and re-deliver affected policies. Policies already deployed to sensors carry signatures from the old key; review legacy assignments separately.
  4. Sensors that already have the old public key in policy-signing.pub will reject policies signed with the new key until they re-enroll and receive the updated public key.
  5. Trigger re-enrollment for all sensors, or manually push the new public key to policy-signing.pub on each sensor if re-enrollment is impractical.

After key rotation, sensors operating in case 2 mode (no .sig sidecar) will continue loading policies with a warning until new signed packs are delivered. This is the window of reduced policy integrity assurance; minimize it by completing full re-deployment promptly.


Relationship to enforcement mode

Inspect the configured rule in Runtime Blocks and review each target sensor's delivery result before relying on protection. Legacy Policy Pack readiness states are not the activation workflow for current runtime rules.

Best practice: require that all packs used in enforcement mode carry .sig sidecars. Verify this by checking the compiled-policies directory on the sensor before enabling enforcement.


Review the audit trail

Review policy and enforcement changes in Reports > Audit Log. Older records can include Policy Pack assignments even though new assignments are no longer offered in the Console. Use the actor, time, target, and recorded result to investigate changes in sensor protection.

The audit log is available under Reports > Audit Log and can be exported from that page.


Operational guidance

Protect the signing key: Restrict access to the configured key file and include it in your protected backup procedure. The Console needs the private key to sign delivered policies; a signature does not protect against compromise of that signer.

Verify before enforcing: Before enabling enforcement mode on a sensor, confirm that the sensor's compiled-policies directory contains both .yaml and .yaml.sig files for all active policies. A policy loaded in case 2 (unsigned, warning logged) provides behavioral detection but no tamper protection.

Do not edit policy files on the sensor host: Any modification to a .yaml file on the sensor invalidates its .sig sidecar and will cause the policy to be rejected on next load. Edit custom enforcement policies in Runtime Blocks and review their delivery results. Do not use the retired assignment screen to manage current rules.


Further reading

Released under the Telovix Commercial License.