Jump to

Webhook signature verification

Every webhook request sent by feedback.tools includes an X-Webhook-Signature header so you can verify the request came from feedback.tools and was not tampered with.

How it works

The signature is computed as HMAC-SHA256 of the raw request body, using your integration's secret as the key:

X-Webhook-Signature: sha256=<hex digest>

The body is serialized as compact JSON (no spaces, keys sorted alphabetically) before signing.

Verifying the signature

Python:

import hashlib
import hmac

def verify(secret: str, body: bytes, signature: str) -> bool:
    expected = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(f'sha256={expected}', signature)

Node.js:

const crypto = require('crypto');

function verify(secret, body, signature) {
    const expected = 'sha256=' + crypto
        .createHmac('sha256', secret)
        .update(body)
        .digest('hex');
    return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}

Always use a constant-time comparison (hmac.compare_digest / timingSafeEqual) to prevent timing attacks.

Verify the signature against the raw request body bytes, before parsing JSON.

Managing the secret

  • The secret is generated automatically when you create a webhook integration.
  • You can view and rotate it via the Rotate secret button in the integration settings.
  • After rotating, update the secret on your receiver side — old signatures will no longer be valid.