Authenticating webhooks

If you provide a secret token, this will be used to create a digest of the JSON payload sent with a webhook request. The digest will be included in the request under the Ashby-Signature http header.

It will look like this:
Ashby-Signature: sha256=f3124911d2956f10aa3a49c43a88bdf13bba846e94f0ae2bd7c034f90239bd04

The part before the = indicates the algorithm that was used to compute the hash digest.

Computing and comparing digests

To compute the digest of your payload, you want to use the raw payload (i.e. whole request body, json string) before it has been parsed by something like JSON.parse. Here are some rough examples of how to compute it (note that these code examples are only for illustration).

import hmac
import hashlib

secret = b'8b943c474f5d1e1712f13e1a870b485c9b6b2b57' 

# get this from the request header:
signature = "sha256=f3124911d2956f10aa3a49c43a88bdf13bba846e94f0ae2bd7c034f90239bd04"
payload = b'{...}'

def check_signature(signature_from_header, raw_payload):  
    h =, raw_payload, hashlib.sha256)
    digest = h.hexdigest()
    # note that in reality you may want to use a secure digest compare function here:
    return 'sha256={}'.format(digest) == signature_from_header

And in Node:

const crypto = require("crypto");

const secret = "8b943c474f5d1e1712f13e1a870b485c9b6b2b57";

function checkSignature(signatureFromHeader, rawPayload) {
  const hmac = crypto.createHmac("sha256", secret);
  const digest = hmac.digest("hex");
  return "sha256=" + digest === signatureFromHeader;