Alert destinations
Send alerts to an Amazon SNS topic or a signed HTTPS webhook, verify the setup, and check what arrives.
An alert destination is where Vigilfield sends an alert when it opens. There are two kinds:
- SNS topic: Vigilfield publishes to an Amazon SNS topic in an AWS account you own. From there you can fan out to email, chat, a queue or a function.
- HTTPS webhook: Vigilfield sends a signed
POSTto a URL you run.
A rule sends to up to 5 destinations. Pick them in the rule's Alerting section. Its New destination link opens the create form in a new browser tab, so the rule you are writing is kept; the list updates when you return. See Alerts.
Add an SNS topic
- Open Alerts, choose the Destinations tab and click New Destination.
- Set Kind to SNS topic.
- Enter the AWS Account ID, Region and Topic ARN, then click Create Destination.
- Open the new destination. Its Role setup panel shows what to deploy in
the topic's AWS account:
- Identity provider: a CloudFormation template to deploy once per AWS account, before any Vigilfield role. The panel shows it only when that account does not have it yet.
- Role stack: a CloudFormation template that creates the role Vigilfield publishes through. The panel shows its Role ARN and Token subject.
- Deploy the templates, then click Verify.
The role can do one thing: sns:Publish on exactly this topic. Vigilfield holds
no long-lived credentials for it. It signs in to the role through the identity
provider, and the role's trust policy admits only this destination.
The form's values must agree with each other, or the save is refused with the field named:
- The account ID is 12 digits.
- The region is an AWS region in the standard
awspartition. - The topic ARN has the form
arn:aws:sns:<region>:<account>:<name>, is at most 256 bytes, and its region and account match the two fields above.
Through the API, see Create an alert destination and Get the IAM template.
Add a webhook
- Open Alerts, choose the Destinations tab and click New Destination.
- Set Kind to HTTPS webhook.
- Enter the Webhook URL and a Signing secret, then click Create Destination.
- Open the new destination and click Verify.
Rules for the webhook:
- The URL must use
https, and is at most 2048 bytes. - The URL's host must not be a private, loopback or otherwise internal address. A host name that resolves to one is refused when Vigilfield sends to it.
- The signing secret is required when you create a webhook, and is at most 4096 bytes. Vigilfield stores it encrypted and never shows it again. Keep your own copy.
- To rotate the secret, edit the destination and type a new one. Leave the field empty to keep the current secret.
Verify a destination
Verify, on the destination's page, sends a test message through the same
path a real alert takes. It shows the outcome right there: success, or a failure
with a short reason code and a message. Verify changes nothing; run it as
often as you like.
The test message is this JSON:
{"type":"test","destination_id":"<destination id>","sent_at":"<time sent>"}A webhook's test message is signed differently from a real alert. The test
carries only X-Vigilfield-Signature, computed over the body alone, with no
timestamp. A real alert is signed over the timestamp and the body, as described
below.
What a destination receives
Every alert is sent as the same JSON document. SNS delivers it as the message; a webhook receives it as the request body.
{
"version": 1,
"alert_id": "alr_…",
"origin": "rule:<rule id>",
"severity": "high",
"title": "Repeated failed sign-ins: alice",
"description": "7 failed sign-ins since the last run",
"key": "alice",
"latest_row": { "Account": "alice", "failures": 7 },
"first_seen": "2026-09-24T10:00:00.000Z",
"link": "/alerts/alr_…"
}originisrule:<rule id>orsystem:<kind>.latest_rowis the matched row. A row over 32 KiB is replaced by{"vf_row_omitted":{"size_bytes":<n>}}.linkis the alert's path in the app, relative to your organization.- Title, description and row are your query's output, sent as data. Treat them as untrusted text on the receiving side.
Check a webhook signature
A real alert's request carries two headers:
X-Vigilfield-Timestamp: the send time, in Unix seconds.X-Vigilfield-Signature:sha256=followed by the hex HMAC-SHA256 of the timestamp, one., and the exact raw body, keyed with your signing secret.
To check it, build <timestamp>.<raw body> from the request, compute the
HMAC-SHA256 with your secret, and compare it with the header in constant time.
Use the raw bytes you received, not re-serialized JSON. Rejecting old
timestamps protects you against replayed requests.
import hashlib, hmac
def valid(secret: bytes, timestamp: str, body: bytes, header: str) -> bool:
material = timestamp.encode() + b"." + body
expected = "sha256=" + hmac.new(secret, material, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, header)Delivery
- An alert is sent when it opens, and only then. Later hits on the same alert are not sent again. A resolved alert's next hit opens a new alert, which is sent.
- Delivery is at least once. Your receiver can see the same alert twice. Use
alert_idto drop duplicates. - A webhook send succeeds on any 2xx answer within 10 seconds. Anything else counts as a failed attempt.
- Failed sends are retried about once a minute, for up to 5 attempts per
alert. After that, the destination's id is added to the alert's
delivery_failedlist in the API, and Vigilfield stops trying. - Redirects are not followed to another host, so point the destination at the final URL.
Edit and delete
- Edit changes where the destination points. The kind cannot be changed in the app. If you change an SNS topic, deploy the updated role stack from the destination's Role setup panel, because the role grants publish on one topic only.
- Delete is refused while any rule still names the destination. The error lists those rules. Remove the destination from each rule's Alerting section first.
Through the API, see Delete an alert destination and Verify an alert destination.