Notification Channels
Imposed rule: Work of this type or tasks of this type on this component must also be applied everywhere else it should be applied.
Last updated: 2026-05-19 (Sprint 20260518_053 T5 partial)
Supported channel types
- Slack / Teams: webhook-based with optional slash-command ack URLs.
- Email (SMTP/SMTPS): relay-only; secrets provided via
secretRefin Authority. - Generic webhook: signed (HMAC-SHA256) payloads with replay protection and allowlisted hosts.
- Pager duty-style escalation webhooks: same contract as generic webhooks but with escalation metadata.
- Console in-app: stored delivery rendered in UI; always enabled for each tenant.
- Audit anomaly routing (
audit_anomaly): additive PostgreSQLnotify.channel_typeliteral reserved for Timeline anomaly dispatch. The first T5 phase does not add a new external connector; anomaly subscriptions route to existing channel ids innotify.anomaly_subscriptions.
audit_anomaly is additive-only. Downgrade recovery ignores the unused enum literal or restores PostgreSQL from snapshot; the enum value is not removed by a rollback migration.
Channel resource schema (Notify API)
{
"id": "uuid",
"tenant": "string",
"type": "slack|teams|email|webhook|pager|console",
"purpose": "general|dora-incident|dora-roi-distribution|dora-info-sharing|nis2-csirt|enisa-cra",
"endpoint": "https://..." ,
"secretRef": "authority://secrets/notify/slack-hook", // optional per type
"labels": { "env": "prod", "team": "sre" },
"throttle": { "windowSeconds": 60, "max": 10 },
"quietHours": { "from": "22:00", "to": "06:00", "timezone": "UTC" },
"enabled": true,
"createdUtc": "2025-11-25T00:00:00Z"
}
- Determinism: channel ids are UUIDv5 seeded by
(tenant, type, endpoint)when created via manifests; server generates new IDs for ad-hoc API calls. - Validation: endpoints must be on the allowlist; secretRef must exist in Authority; quiet hours use 24h clock UTC.
- Purpose routing:
purposeis optional for legacy payloads and defaults togeneral. The v1 values are capped togeneral,dora-incident,dora-roi-distribution,dora-info-sharing,nis2-csirt, andenisa-cra; channel list APIs may filter by this field for minimised regulatory feeds.
Connector rules
- No secrets are stored in Notify DB; only
secretRefis persisted. - Per-tenant allowlists control outbound hostnames/ports; defaults block public internet in air-gapped kits.
- Payload signing:
- Slack/Teams: bearer secret in URL (indirect via secretRef) plus optional HMAC header
X-Stella-Signaturefor mirror validation. - Webhook/Pager: HMAC
X-Stella-Signature(hex) over body with nonce + timestamp; receivers must enforce 5-minute skew.
- Slack/Teams: bearer secret in URL (indirect via secretRef) plus optional HMAC header
Offline posture
- Offline kits ship default channel manifests under
out/offline/notify/channels/*.jsonwith placeholder endpoints. - Operators must replace endpoints and secretRefs before deploy; validation rejects placeholder values.
Observability
- Emit
notify.channel.deliverycounter with tags:channel_type,tenant,status(success/fail/throttled/quiet_hours),rule_id. - Store delivery attempt hashes in the delivery ledger; duplicate payloads are de-duplicated per
(channel, bodyHash)for 24h.
Safety checklist
- [ ] Endpoint on allowlist and TLS valid.
- [ ]
secretRefexists in Authority and scoped to tenant. - [ ] Quiet hours configured for non-critical alerts; throttles set for bursty rules.
- [ ] HMAC signing verified in downstream system (webhook/pager).
