Wardengate

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

EventSeverityTypical use
session.start / session.endinfoSIEM forwarding, targeted "high-value target" alerts.
policy.denywarningTrack unexpected denials to catch mis-scoped roles.
mfa.fail / mfa.lockoutwarning / criticalSurfaces factor fatigue and targeted attacks.
approval.requestedinfoDrives the approval flow to reviewers.
breakglass.usedcriticalAlways page. Loud on purpose.
backup.success / backup.failinfo / criticalOperational health; forward failures to on-call.
cert.expiringwarningBase URL and gateway certs 30/14/7/1 days out.
recording.sealedinfoSignals the recording is immutable and audit-ready.
anomaly.detectedwarningHigh-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-pass

Slack

apiVersion: wardengate/v1
kind: NotificationChannel
metadata:
  name: slack-security
  organization: acme
spec:
  kind: slack
  webhookSecretRef: slack-security-hook
  channel: "#security"
  mentionOnCritical: "@security-oncall"
  threadByEvent: true

Microsoft Teams

apiVersion: wardengate/v1
kind: NotificationChannel
metadata:
  name: teams-sre
  organization: acme
spec:
  kind: msteams
  webhookSecretRef: teams-sre-hook
  adaptiveCard: true

PagerDuty

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: exponential

Webhooks 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: local4

Subscriptions

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: critical

perEvent 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-9241

Delivery 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.