Skip to content

MessagingTemplate

An organisation's own message template, which a MessagingRoute uses instead of the system template for the event type. Fields, YAML, HCL and CLI samples, and how apply treats it.

Checked against config-schemas@v1.15.0, terraform-provider-resolve@82cb23c, cli@v4.9.1

An organisation’s own message template, which a MessagingRoute uses instead of the system template for the event type. One template renders for every provider: Slack, Teams, Discord and Google Chat get the title, summary, body, fields, actions and accent; Jira and GitHub Issues get the issue fields; a signed webhook gets the rendered text and, when asked, the event payload. Every text field is a Go text/template run in a sandbox: only the messaging functions are allowed, every value is escaped, and sizes are capped. Plan compiles each field and refuses a template with errors. Every change to content is saved as a new version, noted as applied as code, as a console edit is; earlier versions stay in the template’s history. Deleting it is refused while a route outside this apply still uses it.

apiVersion vulnetix.com/v1
kind MessagingTemplate
Group Integrations
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 MessagingTemplate in its kinds. See Management tokens.
Terraform resource vulnetix_messaging_template, imported by name (see Terraform and OpenTofu)
CLI vulnetix config apply, CLI v3.168.0 and later.
Pinned schema v1.15.0/MessagingTemplate.schema.json
Newest schema latest/MessagingTemplate.schema.json
First released in v1.5.0
Print the built-in copy vulnetix config schema MessagingTemplate

Minimal

Only the fields the kind requires. From examples/MessagingTemplate/minimal.yaml.

YAML

# yaml-language-server: $schema=https://github.com/Vulnetix/config-schemas/releases/latest/download/MessagingTemplate.schema.json
apiVersion: vulnetix.com/v1
kind: MessagingTemplate
metadata:
  name: plain-title
spec:
  content:
    title: "{{.event.title}}"

HCL (resource vulnetix_messaging_template)

# Only the arguments the kind requires. From config-schemas examples/MessagingTemplate/minimal.yaml.

resource "vulnetix_messaging_template" "plain_title" {
  name = "plain-title"
  content = {
    title = "{{.event.title}}"
  }
}

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/MessagingTemplate.schema.json
apiVersion: vulnetix.com/v1
kind: MessagingTemplate
metadata:
  name: plain-title
spec:
  content:
    title: "{{.event.title}}"
EOF

Advanced

Every field the kind supports, with a when expression where it takes one. From examples/MessagingTemplate/advanced.yaml.

YAML

# yaml-language-server: $schema=https://github.com/Vulnetix/config-schemas/releases/latest/download/MessagingTemplate.schema.json
apiVersion: vulnetix.com/v1
kind: MessagingTemplate
metadata:
  name: security-findings
  labels:
    team: security
  annotations:
    owner: appsec@acme.example
spec:
  displayName: Security findings
  description: Scan results for the security channel, with a link back to the scan.
  eventScope:
    - scan.completed
    - scan.build_broken
  baseSystemTemplate: generic
  content:
    title: "{{.event.title}}"
    summary: "{{with .subject.label}}{{.}}{{end}}"
    body: "{{range $k, $v := .data}}- **{{$k}}:** {{truncate 200 $v}}\n{{end}}{{with .mentions}}\n{{mentions .}}{{end}}"
    fields:
      - label: Severity
        value: "{{severityEmoji .event.severity}} {{severityLabel .event.severity}}"
        inline: true
    actions:
      - label: Open in Vulnetix
        url: "{{.event.url}}"
    accent: "{{.event.severity}}"
    issue:
      title: "[Vulnetix] {{.event.title}}"
      body: "{{.event.title}}"
      labels:
        - vulnetix
        - security
    digest:
      title: "{{.digest.count}} {{plural .digest.count \"event\" \"events\"}}"
      item: "{{.event.title}}{{with .subject.label}}: {{.}}{{end}}"
    webhook:
      includePayload: true

HCL (resource vulnetix_messaging_template)

# Every argument the kind supports. From config-schemas examples/MessagingTemplate/advanced.yaml.

resource "vulnetix_messaging_template" "security_findings" {
  name                 = "security-findings"
  base_system_template = "generic"
  content = {
    accent = "{{.event.severity}}"
    actions = [
      {
        label = "Open in Vulnetix"
        url   = "{{.event.url}}"
      },
    ]
    body = "{{range $k, $v := .data}}- **{{$k}}:** {{truncate 200 $v}}\n{{end}}{{with .mentions}}\n{{mentions .}}{{end}}"
    digest = {
      item  = "{{.event.title}}{{with .subject.label}}: {{.}}{{end}}"
      title = "{{.digest.count}} {{plural .digest.count \"event\" \"events\"}}"
    }
    fields = [
      {
        inline = true
        label  = "Severity"
        value  = "{{severityEmoji .event.severity}} {{severityLabel .event.severity}}"
      },
    ]
    issue = {
      body   = "{{.event.title}}"
      labels = ["vulnetix", "security"]
      title  = "[Vulnetix] {{.event.title}}"
    }
    summary = "{{with .subject.label}}{{.}}{{end}}"
    title   = "{{.event.title}}"
    webhook = {
      include_payload = true
    }
  }
  description  = "Scan results for the security channel, with a link back to the scan."
  display_name = "Security findings"
  event_scope  = ["scan.completed", "scan.build_broken"]
  labels = {
    team = "security"
  }
  annotations = {
    owner = "appsec@acme.example"
  }
}

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/MessagingTemplate.schema.json
apiVersion: vulnetix.com/v1
kind: MessagingTemplate
metadata:
  name: security-findings
  labels:
    team: security
  annotations:
    owner: appsec@acme.example
spec:
  displayName: Security findings
  description: Scan results for the security channel, with a link back to the scan.
  eventScope:
    - scan.completed
    - scan.build_broken
  baseSystemTemplate: generic
  content:
    title: "{{.event.title}}"
    summary: "{{with .subject.label}}{{.}}{{end}}"
    body: "{{range $k, $v := .data}}- **{{$k}}:** {{truncate 200 $v}}\n{{end}}{{with .mentions}}\n{{mentions .}}{{end}}"
    fields:
      - label: Severity
        value: "{{severityEmoji .event.severity}} {{severityLabel .event.severity}}"
        inline: true
    actions:
      - label: Open in Vulnetix
        url: "{{.event.url}}"
    accent: "{{.event.severity}}"
    issue:
      title: "[Vulnetix] {{.event.title}}"
      body: "{{.event.title}}"
      labels:
        - vulnetix
        - security
    digest:
      title: "{{.digest.count}} {{plural .digest.count \"event\" \"events\"}}"
      item: "{{.event.title}}{{with .subject.label}}: {{.}}{{end}}"
    webhook:
      includePayload: true
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 MessagingTemplate Always MessagingTemplate.
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 120 The name the console shows, unique among the organisation’s templates. Defaults to metadata.name.
spec.description string no length 0 to 1000 What the template is for.
spec.eventScope array of string no 0 to 50 items; items unique; each item: pattern ^(\*|[a-z0-9_]+(\.[a-z0-9_]+)*(\.\*)?)$; length 0 to 128 The event types the template is meant for: a type (scan.completed), a family (pix.*), or *. The console uses it to offer the template; a route may still use it for any event.
spec.baseSystemTemplate string no pattern ^[a-z0-9_.]{1,64}$ The key of the system template this one was copied from (generic, findings.report, scan.build_broken and so on). It is recorded so the console can say when that system template has a newer version; it does not change the content.
spec.content object yes no other keys The template itself. Each text field is a template over the event view (.event, .subject, .actor, .data, .mentions, and .digest for a digest).
spec.content.title string yes length 1 to 16384 The message title. Required.
spec.content.summary string no length 0 to 16384 One line under the title.
spec.content.body string no length 0 to 16384 The message body, in markdown-lite.
spec.content.fields array of object no 0 to 25 items Name and value pairs shown beside the body. At most 25.
spec.content.fields[].label string yes length 1 to 16384 The field’s name.
spec.content.fields[].value string yes length 0 to 16384 The field’s value.
spec.content.fields[].inline boolean no false Show the field beside the previous one where the provider can.
spec.content.actions array of object no 0 to 10 items Buttons or links. At most 10. A URL that does not render to an https URL is dropped from the message.
spec.content.actions[].label string yes length 1 to 16384 The button text.
spec.content.actions[].url string yes length 1 to 16384 Where it goes.
spec.content.accent string no length 0 to 16384 The colour bar: a severity (info, notice, warning, critical) or a #rrggbb colour, usually {{.event.severity}}.
spec.content.issue object no no other keys What an issue tracker target gets. A field left out falls back to the message’s own.
spec.content.issue.title string no length 0 to 16384 The issue title.
spec.content.issue.body string no length 0 to 16384 The issue body.
spec.content.issue.labels array of string no 0 to 10 items; each item: length 1 to 16384 Labels to put on the issue. At most 10.
spec.content.digest object no no other keys How a batch of events is summed up when a route sends a digest.
spec.content.digest.title string no length 0 to 16384 The digest title, over the batch view (.digest.count).
spec.content.digest.item string no length 0 to 16384 One line per event in the batch.
spec.content.webhook object no no other keys What a signed webhook target receives.
spec.content.webhook.includePayload boolean no false Send the event’s payload, reduced to the fields the catalogue allows, beside the rendered text.

Applying this kind

  • Command. vulnetix config apply -f <file>; the CLI line above says from which release. Plan first with vulnetix config plan: it shows each object as create, update, delete or no change, with a planHash that apply then holds to. Apply writes in one transaction.
  • Manager. Each object records the manager that applied it (terraform, console or gitops:<repo>). --prune deletes only objects its own manager owns. See The manager and the config engine.
  • Status. Applied, Unchanged or Deleted, with no other status fields. The phases the engine reports are explained under status phases.

How apply treats it

The template is compiled at plan with the messaging centre’s template compiler, so an error shows before anything is written. Every change saves a new version.

Terraform and OpenTofu

The resource is vulnetix_messaging_template 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_messaging_template.

Import an object that already exists by its name:

# Import an existing MessagingTemplate by its name (metadata.name).
terraform import vulnetix_messaging_template.plain_title plain-title

Install, authentication and how state is read: Terraform and OpenTofu.

Check a file with vulnetix config validate -f <file>. See Validate documents. In an editor, start the file with the schema comment.

Edit this pageSources: config-schemas/schemas/MessagingTemplate.schema.json, config-schemas/schemas/common.schema.json, config-schemas/examples/MessagingTemplate/minimal.yaml, config-schemas/examples/MessagingTemplate/advanced.yaml, terraform-provider-resolve/examples/resources/vulnetix_messaging_template/minimal.tf, terraform-provider-resolve/examples/resources/vulnetix_messaging_template/advanced.tf, vdb-site/docs/platform-iac-engine.md, vdb-site/api/internal/handler/config_engine_kinds.go, vdb-site/api/internal/config/messagingtemplate.go
esc
↑ ↓ move↵ openSearches in your browser. A key like autonomy.max or a code like threshold_required jumps straight to it.