SavedSearch
A Guardian saved search. Fields, YAML, HCL and CLI samples, and how apply treats it.
A Guardian saved search. It is the source of a ScheduledReport, an AlertTrigger, or a DetectionRule with searchRef. The text is compiled when it is saved, so a search that does not compile is refused. The tenant always comes from the caller’s token. A tenant keeps at most 500. Deleting one that a ScheduledReport or AlertTrigger still uses is refused.
apiVersion |
vulnetix.com/v1 |
kind |
SavedSearch |
| Group | SIEM |
| Status | Served. The config engine plans and applies it. |
| Objects per tenant | many, keyed by metadata.name |
| Token and role | A vmt_ config management token that lists SavedSearch in its kinds. The owner or admin role writes; the member role reads only. A console session or an ApiKey is refused with kind_not_allowed, because the kind is written in Guardian with the caller’s own token. |
| Terraform resource | vulnetix_saved_search, imported by name (see Terraform and OpenTofu) |
| CLI | vulnetix config apply, CLI v3.165.1 and later. |
| Pinned schema | v1.15.0/SavedSearch.schema.json |
| Newest schema | latest/SavedSearch.schema.json |
| First released in | v1.3.0 |
| Print the built-in copy | vulnetix config schema SavedSearch |
Minimal
Only the fields the kind requires. From examples/SavedSearch/minimal.yaml.
YAML
# yaml-language-server: $schema=https://github.com/Vulnetix/config-schemas/releases/latest/download/SavedSearch.schema.json
apiVersion: vulnetix.com/v1
kind: SavedSearch
metadata:
name: dynamic-dns-lookups
spec:
text: |
dns_events
| where qname endswith ('.duckdns.org', '.no-ip.org', '.ddns.net')
HCL (resource vulnetix_saved_search)
# Only the arguments the kind requires. From config-schemas examples/SavedSearch/minimal.yaml.
resource "vulnetix_saved_search" "dynamic_dns_lookups" {
name = "dynamic-dns-lookups"
text = "dns_events\n| where qname endswith ('.duckdns.org', '.no-ip.org', '.ddns.net')\n"
}
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/SavedSearch.schema.json
apiVersion: vulnetix.com/v1
kind: SavedSearch
metadata:
name: dynamic-dns-lookups
spec:
text: |
dns_events
| where qname endswith ('.duckdns.org', '.no-ip.org', '.ddns.net')
EOF
Advanced
Every field the kind supports, with a when expression where it takes one. From examples/SavedSearch/advanced.yaml.
YAML
# yaml-language-server: $schema=https://github.com/Vulnetix/config-schemas/releases/latest/download/SavedSearch.schema.json
apiVersion: vulnetix.com/v1
kind: SavedSearch
metadata:
name: dynamic-dns-lookups
labels:
team: secops
annotations:
ticket: https://jira.example.com/browse/SEC-2215
spec:
displayName: Dynamic DNS lookups
mode: dsl
text: |
dns_events
| where qname endswith ('.duckdns.org', '.no-ip.org', '.ddns.net')
rangeMs: 86400000
---
# yaml-language-server: $schema=https://github.com/Vulnetix/config-schemas/releases/latest/download/SavedSearch.schema.json
apiVersion: vulnetix.com/v1
kind: SavedSearch
metadata:
name: console-sign-ins
spec:
displayName: AWS console sign-ins
mode: sigma
text: |
logsource:
product: aws
service: cloudtrail
detection:
selection:
eventName: ConsoleLogin
condition: selection
rangeMs: 604800000
HCL (resource vulnetix_saved_search)
# Every argument the kind supports. From config-schemas examples/SavedSearch/advanced.yaml.
resource "vulnetix_saved_search" "dynamic_dns_lookups" {
name = "dynamic-dns-lookups"
display_name = "Dynamic DNS lookups"
mode = "dsl"
range_ms = 86400000
text = "dns_events\n| where qname endswith ('.duckdns.org', '.no-ip.org', '.ddns.net')\n"
labels = {
team = "secops"
}
annotations = {
ticket = "https://jira.example.com/browse/SEC-2215"
}
}
resource "vulnetix_saved_search" "console_sign_ins" {
name = "console-sign-ins"
display_name = "AWS console sign-ins"
mode = "sigma"
range_ms = 604800000
text = "logsource:\n product: aws\n service: cloudtrail\ndetection:\n selection:\n eventName: ConsoleLogin\n condition: selection\n"
}
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/SavedSearch.schema.json
apiVersion: vulnetix.com/v1
kind: SavedSearch
metadata:
name: dynamic-dns-lookups
labels:
team: secops
annotations:
ticket: https://jira.example.com/browse/SEC-2215
spec:
displayName: Dynamic DNS lookups
mode: dsl
text: |
dns_events
| where qname endswith ('.duckdns.org', '.no-ip.org', '.ddns.net')
rangeMs: 86400000
---
# yaml-language-server: $schema=https://github.com/Vulnetix/config-schemas/releases/latest/download/SavedSearch.schema.json
apiVersion: vulnetix.com/v1
kind: SavedSearch
metadata:
name: console-sign-ins
spec:
displayName: AWS console sign-ins
mode: sigma
text: |
logsource:
product: aws
service: cloudtrail
detection:
selection:
eventName: ConsoleLogin
condition: selection
rangeMs: 604800000
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 SavedSearch |
Always SavedSearch. | |
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.displayName |
string | no | length 1 to 160 | The name the console shows. Defaults to metadata.name. | |
spec.mode |
string | no | dsl |
dsl, sigma |
dsl: the Guardian search language. sigma: a Sigma rule’s detection, run as a search. |
spec.text |
string | yes | length 1 to 16384 | The search, in the language mode names. | |
spec.rangeMs |
integer | no | 86400000 |
60000 to 2592000000 | How far back the search reads when it is opened or run by hand, in milliseconds: 1 minute to 30 days. |
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, except for the second phase below. - 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. - Second phase. This kind is not written inside the apply transaction. The other kinds apply and commit first, then each SavedSearch is written on its own, in Guardian. One that fails reports
status.phase: Failedand amessage, and nothing is recorded for it. The others stay applied and the apply answers 207. Plan again to see what is left. A singlePUTfrom the Terraform provider answers 502external_failedinstead. - Status. A failed second-phase write reports phase
Failedwith amessage. The phases the engine reports are explained under status phases.
How apply treats it
Written in Guardian, in the second phase; see SIEM kinds. Everything can change in place. Guardian refuses to delete a search that an AlertTrigger or a ScheduledReport still uses.
Terraform and OpenTofu
The resource is vulnetix_saved_search 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_saved_search.
Import an object that already exists by its name:
# Import an existing SavedSearch by its name (metadata.name).
terraform import vulnetix_saved_search.dynamic_dns_lookups dynamic-dns-lookups
Install, authentication and how state is read: Terraform and OpenTofu.
More examples
examples/SavedSearch/searches.yaml from Vulnetix/config-schemas:
# yaml-language-server: $schema=https://github.com/Vulnetix/config-schemas/releases/latest/download/SavedSearch.schema.json
apiVersion: vulnetix.com/v1
kind: SavedSearch
metadata:
name: dynamic-dns-lookups
spec:
displayName: Dynamic DNS lookups
mode: dsl
text: |
dns_events
| where qname endswith ('.duckdns.org', '.no-ip.org', '.ddns.net')
rangeMs: 86400000
---
apiVersion: vulnetix.com/v1
kind: SavedSearch
metadata:
name: console-sign-ins
spec:
mode: sigma
text: |
logsource:
product: aws
service: cloudtrail
detection:
selection:
eventName: ConsoleLogin
condition: selection
Check a file with vulnetix config validate -f <file>. See Validate documents. In an editor, start the file with the schema comment.