Blazelock

Signature Validation

Validate Blazelock webhook requests with the timestamp and signature headers.

Before your application trusts a webhook request, it should verify that the request really came from Blazelock and that the payload was not modified on the way to your endpoint. This helps confirm authenticity, protect against tampered payloads, and reduce the risk of replay attacks.

Headers

Each webhook request includes these headers:

HeaderDescription
X-Blazelock-Webhook-TimestampUnix timestamp in seconds indicating when the webhook request was sent. This value changes on each delivery attempt, including retries.
X-Blazelock-Webhook-SignatureHex-encoded HMAC-SHA256 signature calculated from {timestamp}.{raw_body} using your webhook secret.

Your webhook secret is available in the Blazelock dashboard in the API integration settings.

Validation Steps

  1. Check the Timestamp: Verify that the timestamp from the X-Blazelock-Webhook-Timestamp header is within an acceptable time window, such as 5 minutes, to help prevent replay attacks.
  2. Build the Signed Payload: The signed payload is the exact concatenation of three parts: the X-Blazelock-Webhook-Timestamp header value, a period (.), and the raw request body exactly as it was received.

Example:

1737830031.{"event":"file_scan.completed","integration_id":"...","occurred_at":"...","data":{...}}
  1. Compute the Expected Signature: Generate an HMAC-SHA256 signature for the payload from step 2 using your webhook secret from the Blazelock dashboard.
  2. Compare the Signatures: Compare the signature you computed with the value from the X-Blazelock-Webhook-Signature header using a constant-time comparison.
  3. Process the Event: Only process the webhook event after the signature check succeeds.

Code Examples

The following examples focus only on signature verification. They assume you already have the raw request body, the two headers, and your webhook secret.

import crypto from 'node:crypto'

export function validateBlazelockWebhook(rawBody, timestampHeader, signatureHeader, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(`${timestampHeader}.${rawBody}`)
    .digest('hex')

  const providedSignature = Buffer.from(signatureHeader)
  const expectedSignatureBuffer = Buffer.from(expectedSignature)

  if (providedSignature.length !== expectedSignatureBuffer.length) {
    return false
  }

  return crypto.timingSafeEqual(providedSignature, expectedSignatureBuffer)
}

On this page