Skip to main content

Volga webhook integration

Volga messages can be forwarded to webhook URLs by configuring webhooks in the volga configuration. Each webhook configured connects a volga topic to a webhook URL. Please see the Volga reference for a list of topics and their locations. Typical topics to forward would be alerts and audit logs.

This function provides a convenient way of forwarding Control Tower topics with minimal configuration. For more complicated scenarios, consider using the volga-webhooks application, which can be deployed to edge sites and offers more flexibility in terms of configuration.

Configuration

A typical scenario might be to forward messages on system:alerts to a Slack channel. After setting up Slack to receive webhooks (refer to the Slack documentation for more information) you will be given a webhook URL on the form https://hooks.slack.com/services/x/y/z. Data posted to this URL needs to come in the form of a JSON message with a field called text:

{
"text": "Hello!"
}

Setting this up using Volga webhooks requires just a few fields to be configured. However, since requests to the Slack URL require no authentication, the URL itself should be considered secret, and the first step is to store it in a Strongbox vault:

supctl create strongbox vaults <<EOF
name: webhooks
EOF

supctl create strongbox vaults webhooks secrets <<EOF
name: urls
data:
slack: 'https://hooks.slack.com/services/x/y/z'
EOF

See the Secrets Management for further information on managing secrets.

With the secret in place, the Volga webhook can be created:

supctl create volga webhooks <<EOF
name: slack-alerts
topic: system:alerts
url: '\${url}'
data: '{"text": "\${MSG_PAYLOAD}"}'
data-format: json
variables:
- name: url
value-from-vault-secret:
vault: webhooks
secret: urls
key: slack
EOF

Here is a breakdown of the configuration:

  • name - An identifier for this Volga webhook.
  • topic - The volga topic to forward.
  • url - The URL to forward messages to. In this case, the URL is contained in the variable url which will be defined below.
  • data - The POST data to be sent to the webhook URL. The variable payload is used to place the payload of the volga message in the text field of the JSON object.
  • data-format- Setting this to json ensures that when the data field is evaluated, all variable expansions are escaped in such a way that they can be placed within JSON strings. This is important since system:alerts is a JSON topic and its payload will contain JSON that would otherwise break the JSON format of the POST data.
  • variables - The variables needed by the above fields, in this example, the only variable needed is url, representing the Slack URL stored in Strongbox. Note that there is no need to define the MSG_PAYLOAD variable. It is a built-in variable defined as /payload by default.

Message forwarding will begin as soon as the configuration is submitted.

Headers and authentication

As mentioned, Slack webhooks require no authentication, but other services could, and that will typically require an authentication header. Headers are easily added using the headers list:

supctl merge volga webhooks my-webhook <<EOF
headers:
- name: Authorization
value: 'Bearer \${token}'
EOF

This assumes that token is a variable referencing a Strongbox secret, just like the url variable in the initial example. Headers can of course also contain simple constant values, and you are free to add as many as you like, such as Content-Type, User-Agent, etc.

JSON Pointer variables

Variables can also be defined as JSON Pointers (RFC 6901) that extract fields from the volga message. When your topic format is JSON, this can be useful to access fields inside the payload of the message:

supctl merge volga webhooks my-webhook <<EOF
variables:
- name: x
value-from-message:
json-pointer: /payload/a-list/1/a-value
default: No value!
EOF

The JSON Pointer above would pick out the value hello from a volga message with the following json payload:

{
"a-list": [
"The first element",
{
"a-value": "hello"
}
]
}

A pointer does not necessarily need to traverse the entire JSON tree
and reach a scalar value. It is also acceptable to pick out pieces of
the JSON object. For example, the pointer `/payload/a-list/1` would
result in a variable containing the following string:

```text
{
"a-value": "hello"
}

Managing webhooks

A running webhook can be restarted using the restart action. This will re-read any vault secrets required by the webhook. A webhook is automatically restarted if its configuration is changed in any way.

You can check the state of any configured webhook by issuing the following command:

supctl show volga webhooks my-webhook

Further configuration

For more details on webhook configuration, refer to the REST API reference guide.