Administer
Notifications
Notifications are how Wardengate tells humans and other systems about things worth knowing. They sit on top of the audit stream and add the delivery layer: channels, templates, throttling, and quiet hours. This page covers the event catalogue, the supported channels, and the patterns that keep the signal-to-noise high.
Event types
| Event | Severity | Typical use |
|---|---|---|
| session.start / session.end | info | SIEM forwarding, targeted "high-value target" alerts. |
| policy.deny | warning | Track unexpected denials to catch mis-scoped roles. |
| mfa.fail / mfa.lockout | warning / critical | Surfaces factor fatigue and targeted attacks. |
| approval.requested | info | Drives the approval flow to reviewers. |
| breakglass.used | critical | Always page. Loud on purpose. |
| backup.success / backup.fail | info / critical | Operational health; forward failures to on-call. |
| cert.expiring | warning | Base URL and gateway certs 30/14/7/1 days out. |
| recording.sealed | info | Signals the recording is immutable and audit-ready. |
| anomaly.detected | warning | High-entropy or unusual command stream on a live session. |
Channels
Each channel is a NotificationChannel resource. Events subscribe to channels by selector — most teams end up with half a dozen channels and a dozen or so subscriptions.
Email (SMTP)
apiVersion: wardengate/v1
kind: NotificationChannel
metadata:
name: secops-email
organization: acme
spec:
kind: email
to: ["secops@acme.example"]
from: "wardengate@acme.example"
smtp:
host: smtp.internal.acme.example
port: 587
startTls: true
usernameRef: smtp-user
passwordRef: smtp-passSlack
apiVersion: wardengate/v1
kind: NotificationChannel
metadata:
name: slack-security
organization: acme
spec:
kind: slack
webhookSecretRef: slack-security-hook
channel: "#security"
mentionOnCritical: "@security-oncall"
threadByEvent: trueMicrosoft Teams
apiVersion: wardengate/v1
kind: NotificationChannel
metadata:
name: teams-sre
organization: acme
spec:
kind: msteams
webhookSecretRef: teams-sre-hook
adaptiveCard: truePagerDuty
apiVersion: wardengate/v1
kind: NotificationChannel
metadata:
name: pd-security-oncall
organization: acme
spec:
kind: pagerduty
routingKeyRef: pd-security-routing
severityMap:
critical: critical
warning: warning
info: info
dedupKey: "wg-{{ event.id }}"Generic webhook
apiVersion: wardengate/v1
kind: NotificationChannel
metadata:
name: internal-webhook
organization: acme
spec:
kind: webhook
url: https://events.internal.acme.example/wardengate
method: POST
headers:
Authorization: "Bearer {{ secret:internal-webhook-token }}"
signingSecretRef: internal-webhook-sig
retry:
attempts: 5
backoff: exponentialWebhooks are signed with an HMAC-SHA256 over the payload, sent in an X-Wardengate-Signature header alongside a X-Wardengate-Timestamp. Verify both before trusting the payload; reject anything more than five minutes skewed.
Syslog
apiVersion: wardengate/v1
kind: NotificationChannel
metadata:
name: syslog-siem
organization: acme
spec:
kind: syslog
protocol: tcp-tls
host: siem.internal.acme.example
port: 6514
format: rfc5424
caBundleRef: internal-ca
facility: local4Subscriptions
A subscription wires an event pattern to one or more channels. The same event can fan out to multiple channels; the same channel can carry multiple event types. Keep subscriptions explicit and narrow — "everything to one channel" is how teams learn to ignore notifications.
apiVersion: wardengate/v1
kind: NotificationSubscription
metadata:
name: breakglass-alerts
organization: acme
spec:
events:
- breakglass.used
- mfa.lockout
severity: [">=", "critical"]
channels:
- pd-security-oncall
- slack-security
filter:
match: "target.tags.env == 'prod'"Templates
Every channel has a default template and can accept a custom one. Templates are Go-template-flavoured with a small set of helpers for time formatting, duration rendering, and target-tag lookup. A well-written template answers the three things the recipient wants to know — who, what, and whether to act — in the first line.
template: |
[{{ .Severity | upper }}] {{ .Event }} by {{ .User.Email }}
target: {{ .Target.Name }} ({{ .Target.Protocol }})
account: {{ .Account }}
when: {{ .Time | rfc3339 }}
reason: {{ .Reason | default "-" }}
link: {{ .ConsoleURL }}Quiet hours and throttling
Non-critical notifications can respect quiet hours at the channel or subscription level. Critical events never honour quiet hours — there is no condition under which a break-glass use should wait until Monday morning.
throttle:
perEvent: 1m
burst: 10
quietHours:
timezone: Europe/Berlin
blocks:
- days: ["sat", "sun"]
all: true
- days: ["mon-fri"]
between: "22:00-07:00"
bypassSeverity: criticalperEvent throttles duplicate events with the same identity — a flaky target that produces one policy.deny every five seconds will collapse to one notification per minute.
Testing a channel
wgctl notification test slack-security --event breakglass.used
# dispatched 2026-04-20T14:12:08Z
# channel slack-security
# delivery ok (202 in 148ms)
# payload console.example.com/audit/evt/sample-evt-9241Delivery status and retries
Every notification dispatch produces an audit record with the HTTP response, latency, and any error. Retries follow the per- channel schedule, default three attempts with exponential backoff. After the final failure the event is flagged and surfaced on the notifications dashboard so an operator can decide whether to retry or accept the drop.
Related
- Approval workflows — how approval prompts ride these channels.
- SIEM export — forwarding the full audit stream rather than picked events.
- Alerts — the operational alerting overlay that builds on notifications.