Genesys Cloud Webhook Signature Verification Failing with HMAC SHA256

We’ve set up a custom endpoint to ingest adherence events from Genesys Cloud Webhooks. The goal is to ensure the requests are actually coming from Genesys and not a replay attack. I’m using Node.js with the crypto module to verify the signature header.

Here’s the verification logic:

const crypto = require('crypto');

function verifySignature(payload, signature, secret) {
 const hmac = crypto.createHmac('sha256', secret);
 hmac.update(payload);
 const digest = hmac.digest('hex');
 return digest === signature;
}

The issue is the comparison always fails. I’m logging both values and they look completely different. I’ve tried using the raw body string and the JSON stringified version. Neither works.

Environment specs:

  • Node.js 18 LTS
  • Genesys Cloud Webhook version 2
  • Secret key copied directly from the Admin portal
  • Payload is raw JSON body

I checked the docs and it mentions using the raw request body for the hash. My middleware captures req.body but it’s already parsed by express.json(). Could that be the problem? Or am I missing a step in the encoding?

The signature header comes in as X-Genesys-Signature. I’m passing that value directly to the function. No base64 decoding on my end.