-
Notifications
You must be signed in to change notification settings - Fork 0
ADR 0009 delivery
wiki-sync[bot] edited this page Jul 23, 2026
·
1 revision
Status: Accepted (2026-07-23)
Each nightly run produces a full report — findings, drift classifications,
HRI/MRI counts, recommendations, and (in advisory_pr mode) a draft-PR link.
This must reach the team in two distinct forms: visibility (a digest people
read) and tracked work (HRIs as durable, deduplicated tickets).
Two constraints shape the delivery design:
- The agent processes untrusted input (HCL, tfstate), so third-party channel credentials (Slack/Jira tokens) must not live inside the agent (ADR-0002 / ADR-0007).
- Channels should be added or removed without changing the agent.
- Decouple the agent from delivery channels.
- Keep channel credentials out of the agent's blast radius.
- Thin payloads; durable, idempotent tracked work; multiple channels.
Amazon SNS as the delivery hub; channel adapters own the integrations.
-
The agent publishes one thin message to SNS — its only delivery scope is
sns:Publish(ADR-0007). The full report goes to S3; the SNS message is a summary + a link to the S3 report (respecting SNS's 256 KB limit and keeping payloads small), plus the draft-PR link when present. -
Channel adapters subscribe to SNS and own their own integration and
credentials (in Secrets Manager) — the agent never holds a channel
credential:
- Slack adapter → nightly digest + report link (visibility).
-
Jira adapter → idempotent tracked tickets: one ticket per finding
(keyed
check_id + resource), updated on recurrence and closed on resolution — never create-new-every-night. Honours the accepted-risk register (ADR-0008) so suppressed items don't reopen tickets. - Email adapter (SES) → a formatted digest for stakeholders who prefer email.
- Channels are configurable — subscribe/unsubscribe an adapter without touching the agent.
-
The agent is decoupled and minimal — one
sns:Publish, no channel secrets; the process that ingests untrusted input can't leak a Slack/Jira token because it never has one. - Thin payloads — the notification links to the S3 report rather than inlining it.
- No ticket spam — idempotent Jira keying gives one living ticket per finding; combined with the accepted-risk register, it avoids alert fatigue.
- Clear division of purpose — Slack/Email are visibility; Jira is the durable work record.
- More components to build and maintain — three adapters plus the topic. Accepted as the cost of decoupling and credential isolation.
| Option | Verdict | Why |
|---|---|---|
| SNS hub + Slack/Jira/Email adapters | Chosen | Decoupled, channel-agnostic, channel secrets isolated in adapters, thin payloads. |
| Direct API calls from the agent (Slack/Jira SDKs in-process) | Rejected | Couples the agent to each channel and puts third-party credentials in the process that handles untrusted input. |
| Email only (SES) | Rejected as sole channel | No tracked work items; email kept as one channel, not the whole delivery. |
| EventBridge hub (API Destinations) | Viable alternative | API Destinations could call Slack/Jira with less Lambda glue and content-based routing; SNS is simpler and sufficient for v1 — see revisit. |
- Move the hub to EventBridge if content-based routing, native API Destinations, or event archive/replay become valuable.
- Add PagerDuty (paging) if any finding class ever warrants urgent escalation — the nightly cadence is currently non-urgent by design.
- ADR-0006 (source of the report, HRI/MRI counts, milestone)
- ADR-0007 (
sns:Publish+ S3-write scope; channel credentials live in adapters, not the agent) - ADR-0008 (accepted-risk register the Jira adapter honours; advisory-PR link)
NWAF Agent repository · generated from docs/ — do not edit wiki pages directly.
Design
Decision Records