Webhooks
Webhooks liefern HTTP-Push-Benachrichtigungen in Echtzeit, wenn Scan-Ereignisse eintreten, und eliminieren die Notwendigkeit von Polling. Wenn ein Scan abgeschlossen wird, fehlschlägt oder andere Ereignisse auslöst, sendet die Cert-IX-Plattform eine HTTP-POST-Anfrage an Ihre registrierte URL mit dem Ereignis-Payload.
Warum Webhooks verwenden?
- Sofortige Benachrichtigungen — Keine Polling-Verzögerung
- Reduzierung von API-Aufrufen — Kein Kontingent für Statusprüfungen verbraucht
- Ereignisgesteuerte Architektur — CI/CD-Gates, Benachrichtigungen, Ticketerstellung automatisch auslösen
- Zuverlässige Zustellung — Automatische Wiederholungsversuche mit exponentiellem Backoff
Webhook registrieren
Endpunkt
POST /api/v1/webhooks
Erforderlicher Bereich: webhooks:create
Anfrage
curl -X POST https://api.cert-ix.com/scan-api/api/v1/webhooks \
-H "X-API-Key: $CERTIX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "CI/CD-Benachrichtigungen",
"url": "https://ihr-server.example.com/webhooks/certix",
"events": ["scan.completed", "scan.failed"]
}'
Anfrageparameter
| Feld | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
name | string | Ja | Lesbarer Name des Webhooks (max. 255 Zeichen) |
url | string | Ja | HTTPS-Endpunkt zum Empfang von Ereignissen (max. 2048 Zeichen) |
events | string[] | Nein | Zu abonnierende Ereignistypen (Standard: scan.completed, scan.failed) |
Antwort (201 Created)
{
"success": true,
"data": {
"id": "wh-a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "CI/CD-Benachrichtigungen",
"url": "https://ihr-server.example.com/webhooks/certix",
"secret": "whsec_a8b2f1d92ffb23344a943df2b6a001fb1028d002e3f4a5b6c7d8",
"events": ["scan.completed", "scan.failed"],
"isActive": true,
"isHealthy": true,
"createdAt": "2026-03-06T10:00:00Z"
}
}
Das Feld secret wird nur bei der Erstellung zurückgegeben. Speichern Sie es sicher — Sie benötigen es zur Verifizierung der Webhook-Signaturen.
Webhook-Ereignisse
| Ereignis | Auslöser | Beschreibung |
|---|---|---|
scan.completed | Scan wird erfolgreich abgeschlossen | Ergebnisse sind abrufbereit |
scan.failed | Scan stößt auf schwerwiegenden Fehler | Fehlerdetails im Payload enthalten |
scan.started | Scan beginnt die Ausführung | Übergang von queued zu running |
scan.cancelled | Scan wird abgebrochen | Teilergebnisse möglicherweise verfügbar |
Payload-Format
Header
Content-Type: application/json
X-Webhook-Signature: sha256=a1b2c3d4e5f6...
X-Webhook-Event: scan.completed
X-Webhook-Delivery: del-uuid-hier
X-Webhook-Timestamp: 2026-03-06T10:02:15Z
Body
{
"event": "scan.completed",
"timestamp": "2026-03-06T10:02:15Z",
"tenantId": "7b5b0610-2947-412f-a869-4683da321fcf",
"data": {
"scanId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"scanType": "nmap",
"name": "Wöchentliches Netzwerk-Audit",
"target": "example.com",
"status": "completed",
"progress": 100,
"resultCount": 12,
"durationMs": 135000
}
}
Signaturverifizierung
Jede Webhook-Zustellung ist mit Ihrem Webhook-Secret mittels HMAC-SHA256 signiert. Verifizieren Sie immer die Signaturen, um sicherzustellen, dass die Anfrage von Cert-IX stammt und nicht manipuliert wurde.
Verifizierungsalgorithmus
X-Webhook-Signature-Header extrahieren- Rohen Anfragekörper erhalten (vor jeglichem JSON-Parsing)
HMAC-SHA256(secret, body)berechnen und hexadezimal kodieren- Mit der Signatur aus dem Header vergleichen (zeitkonstanten Vergleich verwenden)
Python-Beispiel
import hmac
import hashlib
def webhook_verifizieren(anfrage_body: bytes, signatur_header: str, secret: str) -> bool:
"""Cert-IX Webhook-Signatur verifizieren."""
if not signatur_header.startswith("sha256="):
return False
empfangen = signatur_header[7:]
erwartet = hmac.new(secret.encode("utf-8"), anfrage_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(empfangen, erwartet)
Go-Beispiel
func webhookVerifizieren(body []byte, signatureHeader, secret string) bool {
if !strings.HasPrefix(signatureHeader, "sha256=") {
return false
}
empfangen := signatureHeader[7:]
mac := hmac.New(sha256.New, []byte(secret))
mac.Write(body)
erwartet := hex.EncodeToString(mac.Sum(nil))
return hmac.Equal([]byte(empfangen), []byte(erwartet))
}
Node.js-Beispiel
const crypto = require("crypto");
function webhookVerifizieren(body, signatureHeader, secret) {
if (!signatureHeader.startsWith("sha256=")) return false;
const empfangen = signatureHeader.slice(7);
const erwartet = crypto.createHmac("sha256", secret).update(body).digest("hex");
return crypto.timingSafeEqual(Buffer.from(empfangen), Buffer.from(erwartet));
}
Verwenden Sie immer zeitkonstante Vergleichsfunktionen, um Timing-Angriffe zu verhindern.
Webhooks verwalten
| Operation | Endpunkt | Bereich |
|---|---|---|
| Auflisten | GET /api/v1/webhooks | webhooks:read |
| Abrufen | GET /api/v1/webhooks/:webhookId | webhooks:read |
| Aktualisieren | PATCH /api/v1/webhooks/:webhookId | webhooks:update |
| Löschen | DELETE /api/v1/webhooks/:webhookId | webhooks:delete |
| Testen | POST /api/v1/webhooks/:webhookId/test | webhooks:create |
| Zustellungsprotokolle | GET /api/v1/webhooks/:webhookId/deliveries | webhooks:read |
Wiederholungslogik
Fehlgeschlagene Zustellungen werden automatisch mit exponentiellem Backoff wiederholt:
| Versuch | Verzögerung | Gesamtzeit verstrichen |
|---|---|---|
| 1 | Sofort | 0 |
| 2 | 60 Sekunden | 1 Minute |
| 3 | 120 Sekunden | 3 Minuten |
| 4 (letzter) | 240 Sekunden | 7 Minuten |
Eine Zustellung gilt als fehlgeschlagen, wenn:
- Ihr Endpunkt einen nicht-2xx HTTP-Code zurückgibt
- Die Verbindung abbricht (30 Sekunden Timeout)
- Die DNS-Auflösung fehlschlägt
- Der TLS-Handshake fehlschlägt
Gesundheitsüberwachung
Die Plattform verfolgt die Webhook-Gesundheit basierend auf dem Zustellungserfolg:
| Feld | Beschreibung |
|---|---|
isHealthy | true wenn kürzliche Zustellungen erfolgreich waren |
consecutiveFailures | Anzahl aufeinanderfolgender Fehler |
lastTriggeredAt | Zeitstempel des letzten Versuchs |
lastStatusCode | HTTP-Code der letzten Zustellung |
Automatische Deaktivierung
Wenn ein Webhook 10 aufeinanderfolgende Fehler ansammelt, wird er automatisch deaktiviert (isActive: false). Zum Reaktivieren:
- Beheben Sie das Problem mit Ihrem Endpunkt
- Reaktivieren Sie über
PATCHmit{"isActive": true} - Senden Sie ein Test-Ereignis zur Überprüfung
Best Practices
- ✅ Nur HTTPS verwenden — Webhook-URLs müssen
https://verwenden - ✅ Signaturen verifizieren bei jeder Anfrage
- ✅ Schnell 200 zurückgeben — Ereignisse asynchron verarbeiten
- ✅ Idempotenz implementieren — Dasselbe Ereignis kann bei Wiederholungen mehrfach zugestellt werden
- ✅ Ereignistyp validieren — Nur erwartete Ereignisse verarbeiten
Nächste Schritte: