Notifications
Out-of-app delivery for alerts. Enterprise plan. Configure at Settings → Notifications.
Pro includes in-app alert triage only. Upgrade to Enterprise for Slack, Teams, email, and signed webhooks.
See also: Scheduled compliance reports, CSV exports.
Channel kinds
| Kind | Secret format |
|---|---|
slack |
Slack incoming-webhook URL (plain text) |
teams |
Teams incoming-webhook URL (plain text) |
email |
JSON: { "api_url": "https://api.resend.com/emails", "api_key": "...", "from": "alerts@msp.com", "to": "oncall@msp.com" } |
webhook |
JSON: { "url": "https://...", "signing_secret": "..." } |
Secrets are stored in Supabase Vault and never re-displayed. To change a secret, delete the channel and re-create.
Filters
Per channel:
- Minimum severity -
info/warning/critical. An alert fires on this channel only if its severity ≥ minimum. - Kind allowlist - comma-separated list. Empty = all kinds. Use this to e.g. send only
breakglass.signinto a high-priority Slack channel.
How delivery works
The alert table has an INSERT trigger that fires the alert-dispatch Edge Function via pg_net. Dispatch reads every enabled channel for the alert's MSP, filters by severity + kind, and POSTs to each. Successes and failures are recorded in notification_delivery.
Dedupe-merged alerts (same dedupe_key updates the existing row instead of inserting a new one) do not re-trigger dispatch - only the first occurrence in a dedupe window sends.
Signed webhooks
For the generic webhook kind, if signing_secret is in the JSON, every POST includes an X-Policytab-Signature header with the HMAC-SHA256 of the body (hex). Verify in your receiver:
const expected = crypto
.createHmac('sha256', SIGNING_SECRET)
.update(rawBody)
.digest('hex');
if (expected !== req.headers['x-policytab-signature']) reject();
Slack message format
*[critical] breakglass.signin* on _Tenant A_ at 2026-05-19T13:42:00Z
plus a code block with the alert payload (user, app, IP, status).
Teams message format
A MessageCard themed by severity colour: critical=red (#DC2626), warning=amber (#D97706), info=blue (#2563EB).