Passa al contenuto principale
Versione: 1.0.0

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​

CampoTipoObbligatorioDescrizione
namestringSìNome leggibile del webhook (max. 255 caratteri)
urlstringSìEndpoint HTTPS per ricevere eventi (max. 2048 caratteri)
eventsstring[]NoTipi 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"
}
}
Conservate il segreto

Il campo secret viene restituito solo al momento della creazione. Conservatelo in modo sicuro — vi servirà per verificare le firme dei webhook.

Eventi webhook​

EventoTriggerDescrizione
scan.completedLa scansione termina con successoI risultati sono pronti per essere ottenuti
scan.failedLa scansione incontra un errore fataleDettagli dell'errore inclusi nel payload
scan.startedLa scansione inizia l'esecuzioneTransizione da queued a running
scan.cancelledLa scansione viene annullataRisultati parziali possono essere disponibili

Formato del payload​

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​

  1. Estrarre l'header X-Webhook-Signature
  2. Ottenere il corpo grezzo della richiesta (prima di qualsiasi parsing JSON)
  3. Calcolare HMAC-SHA256(segreto, corpo) e codificare in esadecimale
  4. 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));
}
Sicurezza

Usate sempre funzioni di confronto a tempo costante per prevenire attacchi di timing.

Gestire i webhook​

OperazioneEndpointScope
ElencareGET /api/v1/webhookswebhooks:read
OttenereGET /api/v1/webhooks/:webhookIdwebhooks:read
AggiornarePATCH /api/v1/webhooks/:webhookIdwebhooks:update
EliminareDELETE /api/v1/webhooks/:webhookIdwebhooks:delete
TestarePOST /api/v1/webhooks/:webhookId/testwebhooks:create
Log di consegnaGET /api/v1/webhooks/:webhookId/deliverieswebhooks:read

Logica dei tentativi​

Le consegne fallite vengono ritentate automaticamente con backoff esponenziale:

TentativoRitardoTempo totale trascorso
1Immediato0
260 secondi1 minuto
3120 secondi3 minuti
4 (finale)240 secondi7 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:

CampoDescrizione
isHealthytrue se le consegne recenti sono state di successo
consecutiveFailuresNumero di fallimenti consecutivi
lastTriggeredAtTimestamp dell'ultimo tentativo
lastStatusCodeCodice HTTP dell'ultima consegna

Disattivazione automatica​

Se un webhook accumula 10 fallimenti consecutivi, viene disattivato automaticamente (isActive: false). Per riattivarlo:

  1. Correggete il problema con il vostro endpoint
  2. Riattivate tramite PATCH con {"isActive": true}
  3. 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: