Saltar al contenido principal
Version: 1.0.0

Webhooks

Los webhooks proporcionan notificaciones HTTP push en tiempo real cuando ocurren eventos de análisis, eliminando la necesidad de polling. Cuando un análisis se completa, falla o desencadena otros eventos, la plataforma Cert-IX envía una solicitud HTTP POST a su URL registrada con el payload del evento.

¿Por qué usar webhooks?​

  • Notificaciones instantáneas — Sin retardo de polling
  • Reducción de llamadas API — Sin cuota consumida para verificaciones de estado
  • Arquitectura basada en eventos — Active automáticamente gates CI/CD, notificaciones, creación de tickets
  • Entrega confiable — Reintentos automáticos con backoff exponencial

Registrar un webhook​

Endpoint​

POST /api/v1/webhooks

Alcance requerido: webhooks:create

Solicitud​

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": "Notificaciones CI/CD",
"url": "https://su-servidor.example.com/webhooks/certix",
"events": ["scan.completed", "scan.failed"]
}'

Parámetros de la solicitud​

CampoTipoRequeridoDescripción
namestringSíNombre legible del webhook (máx. 255 caracteres)
urlstringSíEndpoint HTTPS para recibir eventos (máx. 2048 caracteres)
eventsstring[]NoTipos de eventos a suscribir (predeterminado: scan.completed, scan.failed)

Respuesta (201 Created)​

{
"success": true,
"data": {
"id": "wh-a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Notificaciones CI/CD",
"url": "https://su-servidor.example.com/webhooks/certix",
"secret": "whsec_a8b2f1d92ffb23344a943df2b6a001fb1028d002e3f4a5b6c7d8",
"events": ["scan.completed", "scan.failed"],
"isActive": true,
"isHealthy": true,
"createdAt": "2026-03-06T10:00:00Z"
}
}
Almacene el secreto

El campo secret se devuelve solo al momento de la creación. Almacénelo de forma segura — lo necesitará para verificar las firmas de webhooks.

Eventos webhook​

EventoDisparadorDescripción
scan.completedEl análisis termina exitosamenteLos resultados están listos para ser obtenidos
scan.failedEl análisis encuentra un error fatalDetalles del error incluidos en el payload
scan.startedEl análisis comienza la ejecuciónTransición de queued a running
scan.cancelledEl análisis es canceladoResultados parciales pueden estar disponibles

Formato del payload​

Encabezados​

Content-Type: application/json
X-Webhook-Signature: sha256=a1b2c3d4e5f6...
X-Webhook-Event: scan.completed
X-Webhook-Delivery: del-uuid-aqui
X-Webhook-Timestamp: 2026-03-06T10:02:15Z

Cuerpo​

{
"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": "Auditoría de red semanal",
"target": "example.com",
"status": "completed",
"progress": 100,
"resultCount": 12,
"durationMs": 135000
}
}

Verificación de firma​

Cada entrega de webhook está firmada con su secreto de webhook usando HMAC-SHA256. Verifique siempre las firmas para asegurarse de que la solicitud proviene de Cert-IX y no ha sido alterada.

Algoritmo de verificación​

  1. Extraer el encabezado X-Webhook-Signature
  2. Obtener el cuerpo crudo de la solicitud (antes de cualquier análisis JSON)
  3. Calcular HMAC-SHA256(secreto, cuerpo) y codificar en hexadecimal
  4. Comparar con la firma del encabezado (usar comparación en tiempo constante)

Ejemplo Python​

import hmac
import hashlib

def verificar_webhook(cuerpo_solicitud: bytes, encabezado_firma: str, secreto: str) -> bool:
"""Verificar la firma del webhook de Cert-IX."""
if not encabezado_firma.startswith("sha256="):
return False
recibido = encabezado_firma[7:]
esperado = hmac.new(
secreto.encode("utf-8"),
cuerpo_solicitud,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(recibido, esperado)

Ejemplo Go​

func verificarWebhook(body []byte, signatureHeader, secret string) bool {
if !strings.HasPrefix(signatureHeader, "sha256=") {
return false
}
recibido := signatureHeader[7:]
mac := hmac.New(sha256.New, []byte(secret))
mac.Write(body)
esperado := hex.EncodeToString(mac.Sum(nil))
return hmac.Equal([]byte(recibido), []byte(esperado))
}

Ejemplo Node.js​

const crypto = require("crypto");

function verificarWebhook(body, signatureHeader, secret) {
if (!signatureHeader.startsWith("sha256=")) return false;
const recibido = signatureHeader.slice(7);
const esperado = crypto.createHmac("sha256", secret).update(body).digest("hex");
return crypto.timingSafeEqual(Buffer.from(recibido), Buffer.from(esperado));
}
Seguridad

Use siempre funciones de comparación en tiempo constante para prevenir ataques de temporización.

Gestionar webhooks​

OperaciónEndpointAlcance
ListarGET /api/v1/webhookswebhooks:read
ObtenerGET /api/v1/webhooks/:webhookIdwebhooks:read
ActualizarPATCH /api/v1/webhooks/:webhookIdwebhooks:update
EliminarDELETE /api/v1/webhooks/:webhookIdwebhooks:delete
ProbarPOST /api/v1/webhooks/:webhookId/testwebhooks:create
Registros de entregaGET /api/v1/webhooks/:webhookId/deliverieswebhooks:read

Lógica de reintentos​

Las entregas fallidas se reintentan automáticamente con backoff exponencial:

IntentoRetrasoTiempo total transcurrido
1Inmediato0
260 segundos1 minuto
3120 segundos3 minutos
4 (final)240 segundos7 minutos

Una entrega se considera fallida si:

  • Su endpoint devuelve un código HTTP no 2xx
  • La conexión expira (timeout de 30 segundos)
  • La resolución DNS falla
  • El handshake TLS falla

Monitoreo de salud​

La plataforma rastrea la salud de los webhooks basada en el éxito de las entregas:

CampoDescripción
isHealthytrue si las entregas recientes fueron exitosas
consecutiveFailuresNúmero de fallos consecutivos
lastTriggeredAtMarca de tiempo del último intento
lastStatusCodeCódigo HTTP de la última entrega

Desactivación automática​

Si un webhook acumula 10 fallos consecutivos, se desactiva automáticamente (isActive: false). Para reactivarlo:

  1. Corrija el problema con su endpoint
  2. Reactive vía PATCH con {"isActive": true}
  3. Envíe un evento de prueba para verificar

Mejores prácticas​

  • ✅ Use solo HTTPS — Las URL de webhook deben usar https://
  • ✅ Verifique las firmas en cada solicitud
  • ✅ Devuelva 200 rápidamente — Procese los eventos de forma asíncrona
  • ✅ Implemente idempotencia — El mismo evento puede entregarse más de una vez durante reintentos
  • ✅ Valide el tipo de evento — Solo procese los eventos esperados

Próximos pasos:

¿Te resultó útil esta página?