Webhook
I webhook forniscono notifiche HTTP push in tempo reale quando si verificano eventi di scansione, eliminando la necessità di polling. Quando una scansione si completa, fallisce o genera altri eventi, la piattaforma Cert-IX invia una richiesta HTTP POST al vostro URL registrato con il payload dell'evento.
Perché usare i webhook?​
- Notifiche istantanee — Nessun ritardo di polling
- Riduzione delle chiamate API — Nessuna quota consumata per le verifiche di stato
- Architettura basata su eventi — Attivate automaticamente gate CI/CD, notifiche, creazione ticket
- Consegna affidabile — Tentativi automatici con backoff esponenziale
Registrare un webhook​
Endpoint​
POST /api/v1/webhooks
Scope richiesto: webhooks:create
Richiesta​
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": "Notifiche CI/CD",
"url": "https://vostro-server.example.com/webhooks/certix",
"events": ["scan.completed", "scan.failed"]
}'
Parametri della richiesta​
| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
name | string | Sì | Nome leggibile del webhook (max. 255 caratteri) |
url | string | Sì | Endpoint HTTPS per ricevere eventi (max. 2048 caratteri) |
events | string[] | No | Tipi di eventi da sottoscrivere (predefinito: scan.completed, scan.failed) |
Risposta (201 Created)​
{
"success": true,
"data": {
"id": "wh-a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Notifiche CI/CD",
"url": "https://vostro-server.example.com/webhooks/certix",
"secret": "whsec_a8b2f1d92ffb23344a943df2b6a001fb1028d002e3f4a5b6c7d8",
"events": ["scan.completed", "scan.failed"],
"isActive": true,
"isHealthy": true,
"createdAt": "2026-03-06T10:00:00Z"
}
}
Il campo secret viene restituito solo al momento della creazione. Conservatelo in modo sicuro — vi servirà per verificare le firme dei webhook.
Eventi webhook​
| Evento | Trigger | Descrizione |
|---|---|---|
scan.completed | La scansione termina con successo | I risultati sono pronti per essere ottenuti |
scan.failed | La scansione incontra un errore fatale | Dettagli dell'errore inclusi nel payload |
scan.started | La scansione inizia l'esecuzione | Transizione da queued a running |
scan.cancelled | La scansione viene annullata | Risultati parziali possono essere disponibili |
Formato del payload​
Header​
Content-Type: application/json
X-Webhook-Signature: sha256=a1b2c3d4e5f6...
X-Webhook-Event: scan.completed
X-Webhook-Delivery: del-uuid-qui
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": "Audit di rete settimanale",
"target": "example.com",
"status": "completed",
"progress": 100,
"resultCount": 12,
"durationMs": 135000
}
}
Verifica della firma​
Ogni consegna webhook è firmata con il vostro segreto webhook usando HMAC-SHA256. Verificate sempre le firme per assicurarvi che la richiesta provenga da Cert-IX e non sia stata alterata.
Algoritmo di verifica​
- Estrarre l'header
X-Webhook-Signature - Ottenere il corpo grezzo della richiesta (prima di qualsiasi parsing JSON)
- Calcolare
HMAC-SHA256(segreto, corpo)e codificare in esadecimale - Confrontare con la firma dell'header (usare confronto a tempo costante)
Esempio Python​
import hmac
import hashlib
def verificare_webhook(corpo_richiesta: bytes, header_firma: str, segreto: str) -> bool:
"""Verificare la firma del webhook Cert-IX."""
if not header_firma.startswith("sha256="):
return False
ricevuto = header_firma[7:]
atteso = hmac.new(
segreto.encode("utf-8"),
corpo_richiesta,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(ricevuto, atteso)
Esempio Go​
func verificareWebhook(body []byte, signatureHeader, secret string) bool {
if !strings.HasPrefix(signatureHeader, "sha256=") {
return false
}
ricevuto := signatureHeader[7:]
mac := hmac.New(sha256.New, []byte(secret))
mac.Write(body)
atteso := hex.EncodeToString(mac.Sum(nil))
return hmac.Equal([]byte(ricevuto), []byte(atteso))
}
Esempio Node.js​
const crypto = require("crypto");
function verificareWebhook(body, signatureHeader, secret) {
if (!signatureHeader.startsWith("sha256=")) return false;
const ricevuto = signatureHeader.slice(7);
const atteso = crypto.createHmac("sha256", secret).update(body).digest("hex");
return crypto.timingSafeEqual(Buffer.from(ricevuto), Buffer.from(atteso));
}
Usate sempre funzioni di confronto a tempo costante per prevenire attacchi di timing.
Gestire i webhook​
| Operazione | Endpoint | Scope |
|---|---|---|
| Elencare | GET /api/v1/webhooks | webhooks:read |
| Ottenere | GET /api/v1/webhooks/:webhookId | webhooks:read |
| Aggiornare | PATCH /api/v1/webhooks/:webhookId | webhooks:update |
| Eliminare | DELETE /api/v1/webhooks/:webhookId | webhooks:delete |
| Testare | POST /api/v1/webhooks/:webhookId/test | webhooks:create |
| Log di consegna | GET /api/v1/webhooks/:webhookId/deliveries | webhooks:read |
Logica dei tentativi​
Le consegne fallite vengono ritentate automaticamente con backoff esponenziale:
| Tentativo | Ritardo | Tempo totale trascorso |
|---|---|---|
| 1 | Immediato | 0 |
| 2 | 60 secondi | 1 minuto |
| 3 | 120 secondi | 3 minuti |
| 4 (finale) | 240 secondi | 7 minuti |
Una consegna è considerata fallita se:
- Il vostro endpoint restituisce un codice HTTP non-2xx
- La connessione scade (timeout di 30 secondi)
- La risoluzione DNS fallisce
- L'handshake TLS fallisce
Monitoraggio della salute​
La piattaforma traccia la salute dei webhook basandosi sul successo delle consegne:
| Campo | Descrizione |
|---|---|
isHealthy | true se le consegne recenti sono state di successo |
consecutiveFailures | Numero di fallimenti consecutivi |
lastTriggeredAt | Timestamp dell'ultimo tentativo |
lastStatusCode | Codice HTTP dell'ultima consegna |
Disattivazione automatica​
Se un webhook accumula 10 fallimenti consecutivi, viene disattivato automaticamente (isActive: false). Per riattivarlo:
- Correggete il problema con il vostro endpoint
- Riattivate tramite
PATCHcon{"isActive": true} - Inviate un evento di test per verificare
Best practice​
- ✅ Usate solo HTTPS — Gli URL dei webhook devono usare
https:// - ✅ Verificate le firme ad ogni richiesta
- ✅ Restituite 200 rapidamente — Elaborate gli eventi in modo asincrono
- ✅ Implementate l'idempotenza — Lo stesso evento può essere consegnato più di una volta durante i tentativi
- ✅ Validate il tipo di evento — Elaborate solo gli eventi attesi
Prossimi passi: