RBAC.md (alerts:read → monitoring:read): The example team-setup table told operators to issue API tokens with an "alerts:read" scope. That scope does not exist in pkg/auth/scopes.go; defined scopes are monitoring:read, settings:read, etc. /api/alerts/ is gated by RequireAuth (no specific scope required), so an integrator issuing a token would naturally pick the closest real scope — monitoring:read — and that is what the doc should have shown. OIDC.md (OIDC_GROUP_ROLE_MAPPINGS, OIDC_CA_BUNDLE): Both env vars were documented but zero code reads them. OIDC config is per-provider in internal/config/sso.go and OIDCProviderConfig in internal/config/oidc.go: groupRoleMappings is a map field; caBundle is a path field. Replace both env-var snippets with the actual UI/API path so operators following the secure-install flow don't silently get no group mapping or no custom CA trust. Same drift pattern as the earlier rc.1 → rc.5 PULSE_RELAY_* aspiration-without-implementation. WEBHOOKS.md (missing helpers): notifications.go's templateFuncMap registers jsonString and pathescape on every webhook template, but the helper list only documented title / upper / lower / printf / urlquery / urlencode / urlpath. Add both, with a short note that jsonString is the safe way to embed arbitrary string values inside a JSON payload — Pulse's shipped templates use it everywhere a value goes inside JSON, and operators writing custom templates were missing the canonical escape primitive. KUBERNETES.md (helm path + markdown fence): - "deployment.strategy.type=Recreate" was the wrong helm path. The chart's strategy block is at the top level (deploy/helm/pulse/values.yaml line 9), so `strategy.type=Recreate` is what operators must actually --set. Following the broken path produced no override and left RWO PVC deployments on the default RollingUpdate, the exact Multi-Attach failure mode the note was trying to warn against. - Trailing ```text on the helm-template code block closed the fence but tagged it as a language, breaking markdown rendering in some readers. Reduced to plain ```. All four are doc-only changes; no code reads the names they document.
3.6 KiB
🔔 Webhooks
Pulse includes built-in templates for popular services and a generic JSON template for custom endpoints.
🚀 Quick Setup
- Go to Alerts → Notification Destinations.
- Click Add Webhook.
- Select service type and paste the URL.
📝 Service URLs
| Service | URL Format |
|---|---|
| Discord | https://discord.com/api/webhooks/{id}/{token} |
| Slack | https://hooks.slack.com/services/... |
| Teams | https://{tenant}.webhook.office.com/webhookb2/{webhook_path} |
| Teams (Adaptive Card) | https://{tenant}.webhook.office.com/webhookb2/{webhook_path} |
| Telegram | https://api.telegram.org/bot{bot_token}/sendMessage?chat_id={chat_id} |
| PagerDuty | https://events.pagerduty.com/v2/enqueue |
| Pushover | https://api.pushover.net/1/messages.json |
| Gotify | https://gotify.example.com/message?token={token} |
| ntfy | https://ntfy.sh/{topic} |
| Generic | https://example.com/webhook |
🎨 Custom Templates
For generic webhooks, use Go templates to format the JSON payload.
Variables (common):
{{.ID}},{{.Level}},{{.Type}}{{.ResourceName}},{{.ResourceID}},{{.ResourceType}},{{.Node}}{{.Message}},{{.Value}},{{.Threshold}},{{.Duration}},{{.Timestamp}}{{.Instance}}(Pulse public URL if configured){{.CustomFields.<name>}}(user-defined fields in the UI){{.Metadata}}(alert metadata map){{.AlertCount}},{{.Alerts}}(grouped alerts){{.Mention}}(platform-specific mention, if configured)
Convenience fields:
{{.ValueFormatted}},{{.ThresholdFormatted}}{{.StartTime}},{{.Acknowledged}},{{.AckTime}},{{.AckUser}}
Template helpers: title, upper, lower, printf, urlquery/urlencode, urlpath/pathescape, jsonString
jsonString is the safe way to embed string values inside a JSON payload — it escapes quotes, backslashes, and control characters without wrapping the value in surrounding quotes, so you can write "text": "{{.Message | jsonString}}" and stay valid JSON even when the message contains " or newlines. Pulse's shipped templates use it extensively; prefer it over manual escaping in custom templates.
Service-specific notes:
- Telegram: include
chat_idin the URL query string. - Telegram templates:
{{.ChatID}}is populated from the URL query string. - PagerDuty: set
routing_keyas a custom field (or header) in the webhook config. - Pushover: add
tokenandusercustom fields (required). Legacyapp_tokenanduser_tokeninputs are migrated automatically.
Example Payload:
{
"text": "Alert: {{.Level}} - {{.Message}}",
"value": {{.Value}}
}
🛡️ Security
- Private IPs: By default, webhooks to private IPs are blocked. Allow them in Settings → System → Network → Webhook Security.
- Headers: Add custom headers (e.g.,
Authorization: Bearer ...) in the webhook config.
🧾 Audit Webhooks (Pro/legacy Pro+/Cloud)
Pro, legacy Pro+, and Cloud support dedicated audit webhooks for security event compliance. Unlike alert notifications, these webhooks deliver the raw, signed JSON payload of every security-relevant action (login, config change, group mapping).
Setup
- Go to Settings → Security → Webhooks.
- Add your endpoint URL (e.g.,
https://siem.corp.local/ingest/pulse).
Security
Audit webhooks are dispatched asynchronously. The payload includes a signature field which can be verified using the per-instance HMAC key stored (encrypted) at .audit-signing.key in the Pulse data directory. There is no PULSE_AUDIT_SIGNING_KEY override.