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)

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

Silencing and acknowledgement (v0.10.0)

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.