RuntimeSensorPolicy
The configuration runtime sensors enroll with and keep pulling: mode, hold, rule feeds, forwarding and tamper protection. Fields, YAML, HCL and CLI samples, and how apply treats it.
The configuration runtime sensors enroll with and keep pulling: mode, hold, rule feeds, forwarding and tamper protection, and which people or MDM systems it applies to. It is a sensor provisioning profile. A device takes the enabled profile with the highest priority that matches it, and picks up a change on its next config pull. Sensors configured by hand with an ApiKey do not read profiles; a person changes their mode from the console. A profile with enrolled devices cannot be deleted.
apiVersion |
vulnetix.com/v1 |
kind |
RuntimeSensorPolicy |
| Group | Virtual patching |
| Status | Served. The config engine plans and applies it. |
| Objects per tenant | many, keyed by metadata.name |
| Token and role | An owner or admin session, or a vmt_ config management token with the owner or admin role that lists RuntimeSensorPolicy in its kinds. See Management tokens. |
| Applied after | DetectionRuleFeed (deleted before them) |
| Terraform resource | vulnetix_runtime_sensor_policy, imported by name (see Terraform and OpenTofu) |
| CLI | vulnetix config apply, CLI v3.165.1 and later. |
| Pinned schema | v1.15.0/RuntimeSensorPolicy.schema.json |
| Newest schema | latest/RuntimeSensorPolicy.schema.json |
| First released in | v1.3.0 |
| Print the built-in copy | vulnetix config schema RuntimeSensorPolicy |
Minimal
Only the fields the kind requires. From examples/RuntimeSensorPolicy/minimal.yaml.
YAML
# yaml-language-server: $schema=https://github.com/Vulnetix/config-schemas/releases/latest/download/RuntimeSensorPolicy.schema.json
apiVersion: vulnetix.com/v1
kind: RuntimeSensorPolicy
metadata:
name: engineering-laptops
spec: {}
HCL (resource vulnetix_runtime_sensor_policy)
# Only the arguments the kind requires. From config-schemas examples/RuntimeSensorPolicy/minimal.yaml.
resource "vulnetix_runtime_sensor_policy" "engineering_laptops" {
name = "engineering-laptops"
}
CLI (applies it)
export VULNETIX_CONFIG_TOKEN=vmt_... # a config management token
vulnetix config apply -f - --manager gitops:acme/platform --auto-approve <<'EOF'
# yaml-language-server: $schema=https://github.com/Vulnetix/config-schemas/releases/latest/download/RuntimeSensorPolicy.schema.json
apiVersion: vulnetix.com/v1
kind: RuntimeSensorPolicy
metadata:
name: engineering-laptops
spec: {}
EOF
Advanced
Every field the kind supports, with a when expression where it takes one. From examples/RuntimeSensorPolicy/advanced.yaml.
YAML
# yaml-language-server: $schema=https://github.com/Vulnetix/config-schemas/releases/latest/download/RuntimeSensorPolicy.schema.json
apiVersion: vulnetix.com/v1
kind: RuntimeSensorPolicy
metadata:
name: engineering-laptops
labels:
fleet: laptops
annotations:
ticket: https://jira.example.com/browse/SEC-2210
spec:
description: Every engineer's laptop, in guard mode, plus the security team by address.
enabled: true
priority: 200
match:
emails: [alice@acme.example, bob@acme.example]
domains: [acme.example]
mdmIntegrations: [5e4d3c2b-1a09-4f8e-9d7c-6b5a4f3e2d1c]
credentialMode: device-key
mode: guard
hold: 15m
feeds:
- feedRef: edge-waf
- https://vulnetix.com/feeds/0b6f2c1e-4d3a-4e5f-8a9b-7c6d5e4f3a2b/9c8b7a6f-5e4d-4c3b-8a2f-1e0d9c8b7a6f
- sensorFeed: 7d6c5b4a-3f2e-4d1c-9b8a-7f6e5d4c3b2a
feedKey: KymtMlKOJvj2IkhUbMpXRl/JBmmOwu/LIj8BekwmQXk=
egressListen: 127.0.0.1:8181
dnsListen: 127.0.0.1:5353
forward: [siem]
inventoryEvery: 6h
protection: hardened
allowUserStop: false
heartbeatAlertMinutes: 30
allowMajorUpdate: true
---
apiVersion: vulnetix.com/v1
kind: RuntimeSensorPolicy
metadata:
name: servers-locked
spec:
description: Production servers enrolled by MDM, blocking every match on a block-mode rule.
priority: 10
match:
mdmIntegrations: [5e4d3c2b-1a09-4f8e-9d7c-6b5a4f3e2d1c]
credentialMode: org-key
mode: enforce
feeds:
- feedRef: edge-suricata
protection: locked
heartbeatAlertMinutes: 5
autoUpdate: false
HCL (resource vulnetix_runtime_sensor_policy)
# Every argument the kind supports. From config-schemas examples/RuntimeSensorPolicy/advanced.yaml.
resource "vulnetix_runtime_sensor_policy" "engineering_laptops" {
name = "engineering-laptops"
allow_major_update = true
allow_user_stop = false
credential_mode = "device-key"
description = "Every engineer's laptop, in guard mode, plus the security team by address."
dns_listen = "127.0.0.1:5353"
egress_listen = "127.0.0.1:8181"
enabled = true
feed_key = "KymtMlKOJvj2IkhUbMpXRl/JBmmOwu/LIj8BekwmQXk="
feeds = jsonencode([{
feedRef = "edge-waf"
}, "https://vulnetix.com/feeds/0b6f2c1e-4d3a-4e5f-8a9b-7c6d5e4f3a2b/9c8b7a6f-5e4d-4c3b-8a2f-1e0d9c8b7a6f", {
sensorFeed = "7d6c5b4a-3f2e-4d1c-9b8a-7f6e5d4c3b2a"
}])
forward = ["siem"]
heartbeat_alert_minutes = 30
hold = "15m"
inventory_every = "6h"
match = {
domains = ["acme.example"]
emails = ["alice@acme.example", "bob@acme.example"]
mdm_integrations = ["5e4d3c2b-1a09-4f8e-9d7c-6b5a4f3e2d1c"]
}
mode = "guard"
priority = 200
protection = "hardened"
labels = {
fleet = "laptops"
}
annotations = {
ticket = "https://jira.example.com/browse/SEC-2210"
}
}
resource "vulnetix_runtime_sensor_policy" "servers_locked" {
name = "servers-locked"
auto_update = false
credential_mode = "org-key"
description = "Production servers enrolled by MDM, blocking every match on a block-mode rule."
feeds = jsonencode([{
feedRef = "edge-suricata"
}])
heartbeat_alert_minutes = 5
match = {
mdm_integrations = ["5e4d3c2b-1a09-4f8e-9d7c-6b5a4f3e2d1c"]
}
mode = "enforce"
priority = 10
protection = "locked"
}
CLI (applies it)
export VULNETIX_CONFIG_TOKEN=vmt_... # a config management token
vulnetix config apply -f - --manager gitops:acme/platform --auto-approve <<'EOF'
# yaml-language-server: $schema=https://github.com/Vulnetix/config-schemas/releases/latest/download/RuntimeSensorPolicy.schema.json
apiVersion: vulnetix.com/v1
kind: RuntimeSensorPolicy
metadata:
name: engineering-laptops
labels:
fleet: laptops
annotations:
ticket: https://jira.example.com/browse/SEC-2210
spec:
description: Every engineer's laptop, in guard mode, plus the security team by address.
enabled: true
priority: 200
match:
emails: [alice@acme.example, bob@acme.example]
domains: [acme.example]
mdmIntegrations: [5e4d3c2b-1a09-4f8e-9d7c-6b5a4f3e2d1c]
credentialMode: device-key
mode: guard
hold: 15m
feeds:
- feedRef: edge-waf
- https://vulnetix.com/feeds/0b6f2c1e-4d3a-4e5f-8a9b-7c6d5e4f3a2b/9c8b7a6f-5e4d-4c3b-8a2f-1e0d9c8b7a6f
- sensorFeed: 7d6c5b4a-3f2e-4d1c-9b8a-7f6e5d4c3b2a
feedKey: KymtMlKOJvj2IkhUbMpXRl/JBmmOwu/LIj8BekwmQXk=
egressListen: 127.0.0.1:8181
dnsListen: 127.0.0.1:5353
forward: [siem]
inventoryEvery: 6h
protection: hardened
allowUserStop: false
heartbeatAlertMinutes: 30
allowMajorUpdate: true
---
apiVersion: vulnetix.com/v1
kind: RuntimeSensorPolicy
metadata:
name: servers-locked
spec:
description: Production servers enrolled by MDM, blocking every match on a block-mode rule.
priority: 10
match:
mdmIntegrations: [5e4d3c2b-1a09-4f8e-9d7c-6b5a4f3e2d1c]
credentialMode: org-key
mode: enforce
feeds:
- feedRef: edge-suricata
protection: locked
heartbeatAlertMinutes: 5
autoUpdate: false
EOF
Fields
Paths use dots for nesting and [] for the items of a list. Required means required whenever the parent object is present. A default is what the server uses when the field is left out.
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
apiVersion |
string | yes | exactly vulnetix.com/v1 |
The document format version. Every kind in this release is vulnetix.com/v1. | |
kind |
string | yes | exactly RuntimeSensorPolicy |
Always RuntimeSensorPolicy. | |
metadata |
object | yes | no other keys | ||
metadata.name |
string | yes | pattern ^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$ |
The object’s name, unique per kind within a tenant. It is the natural key: plan, apply, export and the Terraform provider all address an object by kind and name. | |
metadata.org |
string | no | format uuid |
The tenant (organization UUID) the document belongs to. When set, plan and apply refuse to run against any other tenant. | |
metadata.labels |
object | no | map of string to string (length 0 to 256); keys match ^[a-z0-9]([a-z0-9._/-]{0,61}[a-z0-9])?$ |
Free key/value labels. Stored with the object, never interpreted by the server. | |
metadata.annotations |
object | no | map of string to string (length 0 to 4096) | Free key/value notes for people and tools, such as a ticket link. | |
spec |
object | yes | no other keys | ||
spec.description |
string | no | length 0 to 1000 | ||
spec.enabled |
boolean | no | true |
||
spec.priority |
integer | no | 100 |
0 to 100000 | Highest wins when several profiles match a device; ties go to the oldest. |
spec.match |
object | no | no other keys | Who enrolls with this profile: a person by exact email or email domain (* for everyone), or a device an MDM integration enrolls. | |
spec.match.emails |
array of string | no | 0 to 200 items; items unique; each item: format email |
||
spec.match.domains |
array of string | no | 0 to 50 items; items unique; each item: pattern ^(\*|@?[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)+)$ |
||
spec.match.mdmIntegrations |
array of string | no | 0 to 20 items; items unique; each item: format uuid |
MDM integrations, by uuid. | |
spec.credentialMode |
string | no | device-key |
device-key, user-key, org-key |
The credential an enrolled device gets. device-key: a key that works on the sensor routes only, of which the server keeps a hash. user-key: the enrolling person’s. org-key: the organization’s. |
spec.mode |
string | no | monitor |
monitor, guard, enforce |
monitor: report matches, block nothing. guard: hold a match on a rule safe to block (a request denied, an exec refused, a connection dropped) until a person confirms a block or marks a false positive, or the hold lapses; an action that cannot be undone is never held. enforce: block every match on a block-mode rule, a running process included. In every mode a rule from a feed whose signature does not verify only detects. |
spec.hold |
string | no | 15m |
pattern ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$ |
How long guard mode holds a match, as a Go duration from 1s to 24h. |
spec.feeds |
array of object or string | no | 0 to 20 items; items unique | The feeds the sensor pulls: a DetectionRuleFeed by name, which the server resolves to its published URL; one of the organization’s own indicator feeds, by uuid; or an https URL, which must be a published Vulnetix rule feed (https://vulnetix.com/feeds/ |
|
spec.feeds[].feedRef |
string | yes | pattern ^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$ |
The metadata.name of a published DetectionRuleFeed. | |
spec.feeds[].sensorFeed |
string | yes | format uuid |
One of the organization’s own indicator feeds (SensorFeed), by uuid. | |
spec.feedKey |
string | no | pattern ^[A-Za-z0-9+/]{43}=$ |
The base64 Ed25519 public key feed manifests must be signed with. Left out, the sensor’s built-in key. | |
spec.egressListen |
string | no | pattern ^[^\s'"$;&|]*:[^\s'"$;&|]*$; length 0 to 64 |
Where the egress proxy listens. | |
spec.dnsListen |
string | no | pattern ^[^\s'"$;&|]*:[^\s'"$;&|]*$; length 0 to 64 |
Where the DNS guard listens. | |
spec.forward |
array of string | no | items unique; each item: exactly siem |
siem: send every DNS and egress decision to Guardian as dns_events and net_events rows. | |
spec.inventoryEvery |
string | no | 6h |
pattern ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$ |
How often the sensor reports the packages on its host, installed and loaded by a running process, as a Go duration from 1m to 168h. |
spec.protection |
string | no | hardened |
standard, hardened, locked |
How hard the install resists being stopped or removed on the host. standard: a plain service. hardened: a guard restores a sensor that was stopped, disabled or masked, and the user cannot stop it unless allowUserStop. locked: as hardened, and uninstalling needs a one-time code from the console. |
spec.allowUserStop |
boolean | no | false |
Let the device’s user stop the sensor. | |
spec.heartbeatAlertMinutes |
integer | no | 15 |
1 to 10080 | Alert when an enrolled sensor has been silent this long. |
spec.autoUpdate |
boolean | no | true |
Let enrolled sensors install new CLI releases themselves. The guard checks the latest release about every 6 hours, verifies its checksum, keeps the previous binary as .prev and restarts onto the new one. false holds a sensor on its installed version, for hosts that take releases on a change window. | |
spec.allowMajorUpdate |
boolean | no | false |
Let enrolled sensors take a release with a higher major version. Off by default: a major release can change the profile format, the units and the protocol, so a sensor stays on its major version until the profile says otherwise. Has no effect when autoUpdate is false. |
Applying this kind
- Command.
vulnetix config apply -f <file>; the CLI line above says from which release. Plan first withvulnetix config plan: it shows each object as create, update, delete or no change, with aplanHashthat apply then holds to. Apply writes in one transaction. - Manager. Each object records the manager that applied it (
terraform,consoleorgitops:<repo>).--prunedeletes only objects its own manager owns. See The manager and the config engine. - Order. Applied after
DetectionRuleFeed, so a document that refers to one bymetadata.namecan be in the same apply. Deleted before them. - Status. Applied, Unchanged or Deleted, with no other status fields. The phases the engine reports are explained under status phases.
How apply treats it
- This is a provisioning profile as code.
metadata.nameis the profile name. - The console’s normalisation and feed reference checks run on every document, so a document is refused where the provisioning form is.
feedsitems are one of:feedRef(aDetectionRuleFeed, stored as itshttps://vulnetix.com/feeds/<org>/<feed>URL, which must be published when the policy is applied; a feed in the same apply is published first),sensorFeed(an indicator feed, stored asorg:<uuid>), or an https URL (a published Vulnetix rule feed or a catalogue feed, stored ascatalog:<id>). Read renders each stored reference back in that order. Left out,feedsare the catalogue defaults, as for a console-created profile.- A profile with enrolled, unrevoked devices cannot be deleted or pruned. Plan blocks it and names the count.
Terraform and OpenTofu
The resource is vulnetix_runtime_sensor_policy in the vulnetix/resolve provider. Its arguments are the spec in snake case, beside name, labels and annotations from metadata. The Minimal and Advanced HCL are above. The provider’s own reference is vulnetix_runtime_sensor_policy.
Import an object that already exists by its name:
# Import an existing RuntimeSensorPolicy by its name (metadata.name).
terraform import vulnetix_runtime_sensor_policy.engineering_laptops engineering-laptops
Install, authentication and how state is read: Terraform and OpenTofu.
More examples
examples/RuntimeSensorPolicy/policies.yaml from Vulnetix/config-schemas:
# yaml-language-server: $schema=https://github.com/Vulnetix/config-schemas/releases/latest/download/RuntimeSensorPolicy.schema.json
apiVersion: vulnetix.com/v1
kind: RuntimeSensorPolicy
metadata:
name: engineering-laptops
spec:
description: Every engineer's laptop, in guard mode.
priority: 200
match:
domains: [acme.example]
credentialMode: device-key
mode: guard
hold: 15m
feeds:
- feedRef: edge-waf
- https://vulnetix.com/feeds/0b6f2c1e-4d3a-4e5f-8a9b-7c6d5e4f3a2b/9c8b7a6f-5e4d-4c3b-8a2f-1e0d9c8b7a6f
forward: [siem]
inventoryEvery: 6h
protection: hardened
heartbeatAlertMinutes: 30
---
apiVersion: vulnetix.com/v1
kind: RuntimeSensorPolicy
metadata:
name: servers-monitor
spec:
priority: 10
match:
mdmIntegrations: [5e4d3c2b-1a09-4f8e-9d7c-6b5a4f3e2d1c]
mode: monitor
protection: locked
Check a file with vulnetix config validate -f <file>. See Validate documents. In an editor, start the file with the schema comment.