CyberCLI

← All engines · Delivery

Webhook adapter

stable

v1.0.0 · last updated 2026-06-06 · source: cybercli.delivery.channels.webhook

§1

What it does

Generic outbound HTTPS POST with HMAC signing, retry-with-backoff on transient failures, and a configurable JSON body — the universal escape hatch for any destination that speaks HTTP and isn't worth its own adapter.

§2

Why you care

The WebhookAdapter is the engine's 'do anything HTTP' path. PagerDuty Events API, OpsGenie, custom Lambda functions, in-house SOAR triggers, internal webhooks — all of them can be wired with this one adapter instead of waiting for a per-destination integration.

HMAC signing is the differentiator from the naive 'POST a JSON' adapter many tools ship. Every payload carries an HMAC-SHA256 of the body in the `X-Cybercli-Signature` header; the receiving system verifies the signature against the shared secret. Replay attacks + spoofed payloads bounce at the receiver's signature check.

§3

How it works

The adapter pulls the URL + signing secret from the CredentialVault (AAD = `delivery:webhook:url:<destination_id>` + `delivery:webhook:secret:<destination_id>`), renders the operator-supplied JSON template against the signal payload, computes the HMAC, and POSTs with a 30-second connect timeout + a 60-second total timeout.

Retry policy on non-2xx + network errors is exponential backoff (1s, 4s, 16s, 60s capped) up to 4 attempts. The dispatcher passes the retry decision through the audit log — every retry writes a `notification_retried` row with the attempt index and the error class.

§4

Configure & observe

CLI

$ cybercli channels test <destination_id>

POST a test payload with a known body + signature; verify the receiver returns 2xx + accepts the signature.

Dashboard surfaces

/channels (webhook card)

Configure the URL, signing secret, body template, retry policy, and (for advanced) custom headers.

Audit row shape

Outcomes emitted
notification_sentnotification_failednotification_retried
Parameters block

parameters.channel: webhook + parameters.destination_id + parameters.http_status_code + parameters.signature_sha256 (NOT the secret) + parameters.attempt_index on retries.

§5

Status

Stable — HMAC-SHA256 + the retry policy + the template renderer have been the v1 design since 2026-04-22 and are unchanged. The receiver-side verification cookbook is in the doc site.

Shipped 2026-06-07: WebhookConfig.body_format accepts `"json"` (default), `"form"` (application/x-www-form-urlencoded), `"text"` (text/plain key=value), or `"xml"` (application/xml; flat <cybercli_event> root + one <field name="...">VALUE</field> per field, stable-sorted, stdlib-escaped). The same fields ship in every format and the HMAC signs the encoded bytes so receivers verify against whatever wire format they consume. Full ship — no remaining body-format backlog item.

How this engine talks to the rest

Upstream · feeds this engine
Downstream · this engine feeds