HTTP Webhook Strategy - HMAC Configuration

Configure webhooks HMAC to ensure additional authentication layer.

This article applies to HTTP webhook strategy only.

With the HTTP webhook strategy active, all the events are sent to the configured destinationURL through HTTP POST requests. These requests can be (optionally) authenticated using HMAC (Hash-based message authentication code). By using HMAC, you can add authentication layer and verify that the incoming data is correct and authentic.

To enable such an authentication mechanism, provide the secretKey in the HTTP configuration.

HMAC involves cryptographic hash function and a secret cryptographic key. SHA-256 is used as a cryptographic hash function and the provided secretKey acts as a secret cryptographic key.

Authentication process

The steps to authenticate the message are as follows:

  1. The secretKey is used to produce a key.

  2. The event’s payload is converted to JSON format producing a message.

  3. The SHA-256 hash function is used to produce an HMAC derived from the message and the key.

  4. HMAC is encoded using Base64 scheme.

  5. The encoded HMAC value is attached to the request as the emporix-event-signature header of the HTTP request.

These steps ensure that the recipient is able to verify if the request is correctly authenticated.

Example HMAC implementation

Here is an example JavaScript function which verifies incoming HTTP request on the receiver's side:


const functions = require('@google-cloud/functions-framework');
const crypto = require('crypto');
const stringify = require('json-stable-stringify');

const secretKey = 'password123';

functions.http('helloHttp', (req, res) => {

  const body = stringify(req.body); // 1
  const hmac = crypto.createHmac('sha256', secretKey); // 2
  hmac.update(body); // 3

  const computedHmac = hmac.digest('base64'); // 4

  if (computedHmac === req.headers['emporix-event-signature']) { // 5
    console.log('HMAC validation passed.'); // 6
  } else {
    console.log("HMAC validation didn't pass."); // 7
  }

  res.send(`Hello ${req.query.name || req.body.name || 'World'}!`);
});

This simple function conveys the following logic:

  1. It converts the request body into JSON. The stringify function from an external library is used to order all the fields and nested objects alphabetically which allows maintaining the correct order.

  2. It generates the key based on the secretKey. The secretKey is password123.

  3. It generates the HMAC using SHA-256 hash function.

  4. It encodes HMAC to Base64 scheme.

  5. It compares the value from the emporix.event-signature header with the generated HMAC.

    • If the values match, it logs HMAC validation passed. With the above configuration, if the secretKey is set to password123 on the source side, the validation passes.

    • If the values do not match, it logs HMAC validation didn't pass. With the above configuration, if the secretKey is set to some different value than password123 on the source side, the validation doesn't pass.

This example demonstrates how you can implement HMAC in your own setup.

Last updated

Was this helpful?