CloudSealed

Eventos firmados con HMAC

Webhooks

Empuja findings críticos a tu respuesta a incidentes, tu ticketing, tu Slack — en el momento en que se detectan. Sin polling.

Tipos de evento

  • finding.createdSe detectó un nuevo finding.
  • finding.severity_changedSe reclasificó la severidad de un finding — usualmente tras correlacionar nueva evidencia.
  • finding.resolvedUn finding fue marcado como corregido o aceptado como riesgo conocido.
  • audit.startedUna pasada forense 4D arrancó.
  • audit.completedUna pasada 4D terminó, con payload que resume findings nuevos y resueltos.
  • resource.addedUn nuevo recurso de nube entró al inventario.
  • policy.violatedSe disparó una política a medida que definiste.
POST /your-endpoint HTTP/1.1
Host: api.your-app.com
Content-Type: application/json
X-CloudSealed-Event: finding.created
X-CloudSealed-Event-Id: evt_01HZ8K3F2Q4XV6
X-CloudSealed-Timestamp: 1717693200
X-CloudSealed-Signature: sha256=8b9c4a...

{
  "event_id": "evt_01HZ8K3F2Q4XV6",
  "type": "finding.created",
  "created_at": "2026-06-06T14:22:11Z",
  "data": {
    "finding": {
      "id": "fnd_8f3a2c1b",
      "severity": "critical",
      "dimension": "security",
      "resource_id": "res_aws_s3_42",
      "title": "Public S3 bucket exposing customer PII"
    }
  }
}

Semántica de entrega

  • POST con body JSON, content-type application/json.
  • Reintentos: hasta 8 intentos en 24 horas con backoff exponencial.
  • Timeout: 10 segundos. Devuelve 2xx rápido y encola el trabajo de forma asíncrona.
  • Idempotencia: toda entrega trae un header event_id estable. Hazle dedupe.

Verificación de firma

Todo payload se firma con HMAC-SHA256 sobre el cuerpo crudo de la solicitud usando el secret de tu endpoint. La firma viaja en el header X-CloudSealed-Signature junto a un X-CloudSealed-Timestamp. Rechaza cualquier solicitud cuya firma no coincida — nunca confíes en el payload sin esto. Rechaza timestamps con más de cinco minutos para impedir replay.

import { createHmac, timingSafeEqual } from "node:crypto";

export function verifyCloudSealed(req, secret) {
  const signature = req.headers["x-cloudsealed-signature"];
  const timestamp = req.headers["x-cloudsealed-timestamp"];

  // Reject replays older than 5 minutes
  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;

  const expected =
    "sha256=" +
    createHmac("sha256", secret)
      .update(timestamp + "." + req.rawBody)
      .digest("hex");

  const a = Buffer.from(signature);
  const b = Buffer.from(expected);
  return a.length === b.length && timingSafeEqual(a, b);
}