Webhooks
The generic webhook channel POSTs a JSON document to a URL you control whenever a subscribed event fires. This page is the contract.
Request shape
| Aspect | Value |
|---|---|
| Method | POST |
| Path | The URL you configured for the channel |
| Content type | application/json; charset=utf-8 |
| User agent | HarborGuard-Webhook/1.0 |
| Timeout | 10 seconds |
Headers
| Header | Description |
|---|---|
Content-Type | Always application/json |
User-Agent | HarborGuard-Webhook/1.0 |
X-HarborGuard-Signature | sha256=<hex> HMAC of the raw body using your channel signing secret. Present only when the channel has a secret configured. |
Body schema
Additional event-specific keys are included alongside the core fields. The event field is the event type; severity is one of CRITICAL, HIGH, MEDIUM, LOW, INFO.
Example payloads
scan_complete
sla_breach
cve_watch_kev
Signature verification
Compute HMAC-SHA256 over the raw request body using the channel's signing secret. Compare the result to the hex value in X-HarborGuard-Signature after stripping the sha256= prefix. Use a constant-time comparison to avoid timing attacks. Verify before parsing JSON; never trust an unverified payload.
Acknowledgement and retries
HarborGuard treats any 2xx status as a successful delivery. Anything else — 4xx, 5xx, network error, TLS failure, or timeout (>10 s) — is a failure.
| Aspect | Value |
|---|---|
| Success codes | 200, 201, 202, 204 |
| Retry policy | Exponential backoff at 30 s, 2 m, 10 m, 1 h |
| Max attempts | 5 |
| Per-endpoint circuit breaker | Opens after 5 failures in 60 s, cools down for 60 s |
When the circuit breaker is open, deliveries to that endpoint are short-circuited as failed without a network call. The breaker probes again after the cooldown.
Every delivery (success or failure) is logged with status code, response time, and error message. View the history in Settings -> Notifications -> [channel] -> Deliveries.
Idempotency
Some events fire from multiple producers (e.g. a CVE detected by both Trivy and Grype). HarborGuard deduplicates at the source so you receive one event per (image, CVE), but retries can cause your endpoint to see the same event body twice. Treat your handler as idempotent: key on (event, timestamp, target) or include your own dedupe table.
Rotating the signing secret
- Generate a new secret in your secret manager.
- Update the channel in HarborGuard: Settings -> Notifications -> [channel] -> Edit -> Signing secret.
- The very next delivery uses the new secret. There is no overlap window.
To rotate without downtime, run two channels (old and new URL or old and new secret) for a brief overlap, then delete the old channel.
HarborGuard does not currently publish a static IP allowlist for outbound webhook traffic. Authenticate by HMAC signature, not by source IP.