Alerting
When drift is detected, cfgdrift can notify you through six channels —
webhook, email, script, Slack, Microsoft Teams and PagerDuty — with debounce, dedup and
rule-level retry.
Channels
cfgdrift alert add --name nginx-webhook --type webhook --url http://ops/webhook
cfgdrift alert add --name ops-email --type email --smtp-host smtp.example.com --from a@x --to ops@x
cfgdrift alert add --name notify --type script --script /usr/local/bin/notify.sh
Native channels (v0.15.0)
Three native channels — Slack Incoming Webhook, Teams Workflow Webhook (MessageCard) and
PagerDuty Events API v2 — share the same dispatcher chain (retry / debounce / audit).
Severity is mapped consistently: CRITICAL → #e11d48 / critical,
WARN → #f59e0b / warning, INFO → #64748b /
info.
# Slack
cfgdrift alert add --name ops-slack --type slack --severity WARN \
--webhook-url https://hooks.slack.com/services///
# Microsoft Teams (Workflow webhook)
cfgdrift alert add --name ops-teams --type teams --severity WARN \
--webhook-url https://tenant.webhook.office.com/webhookb2/<token>/IncomingWebhook/<id>/<key>
# PagerDuty (Events API v2 routing key; {env:VAR} keeps the key out of alerts.yaml)
cfgdrift alert add --name oncall --type pagerduty --severity CRITICAL \
--routing-key "{env:CFGDRIFT_PD_ROUTING_KEY}"
cfgdrift alert test --rule ops-slack # connectivity check (exit 0 / 2)
- Webhook URLs / routing keys support
{env:VAR}expansion at send time; secrets are never persisted in plaintext - Error messages expose only
scheme://host— webhook tokens / routing keys never leak into errors or logs - Without any new-channel rule, all outputs stay byte-identical to v0.14.0 (zero-noise)
Rule-level retry
# 5 total attempts, default wait schedule (1s/5s/30s)
cfgdrift alert add --name nginx-webhook --type webhook --url http://x --retry-count 5
# only delays → attempts = len(delays) + 1 (here 4)
cfgdrift alert add --name ops-email --type email --smtp-host ... --retry-delay 2,10,60
# comma-separated and repeated flags are equivalent
cfgdrift alert add --name x --type webhook --url http://x --retry-delay 1 --retry-delay 5 --retry-delay 30
retry_count= total attempts (default 3, ≥ 1);retry_delays= waits between attempts (elements ≥ 0)- Rule-level settings override the global default;
alert listshowsretry=3/1,5,30orretry=default - Debounce cooldown is 600s
Silencing and acknowledgement (v0.10.0)
- Rule-level
--mute-until: silence a rule until a timestamp - Event-level ack: acknowledge individual alert events (CLI and Web interoperable)
- 14-day alert trend chart (pure SVG) in the dashboard
Sensitive-value masking in payloads
Alert payloads pass through the same SensitiveMasker as every other display channel:
password / token / secret etc. (13 key categories) are masked to
*** before leaving the process. The database always stores raw values. Customize with
masking.yaml — remember its patterns follow glob semantics
(not regex).
Payload (v0.13.0)
Every drift_items entry carries a 9th hint field (expected value + fix
action + provenance). Template variables ({severity}, {baseline},
{drift_count}…) are unchanged.
See README.en.md — Features at a Glance for the full alert-rule grammar.