Verifying Webhook Data

Whenever you receive a webhook event from Gradual, it includes a signature you can use to verify that the data came from Gradual and was not altered in transit.


Below is a step-by-step guide on verifying the webhook data using the secret key.


Getting Your Secret Key

1
Log into your tenant dashboard and navigate to 'Integrations'
2
Expand the 'Outbound Webhooks' Configure sidebar, where you will find your secret key

3
If you need to rotate (i.e., change) your secret key, you can do so by clicking the "Roll Secret" button on the same page. 

Remember to keep your secret key secure. Do not share it or expose it in any publicly accessible locations such as GitHub, client-side code, and so forth.


Verifying the Signature

1
Extract the timestamp and signatures from the Gradual-Signature header of the webhook HTTP request.

It should look something like this: t=1492774577,v0=abcd1234


2
Prepare the signed_payload string.

This is formed by concatenating:

- The timestamp (as a string)

- The character '.'

- The actual JSON payload (i.e., the request body)


3
Compute the HMAC digest to get the expected signature:

- Use the HMAC-SHA256 algorithm. In most programming languages, you would use a function like createHmac .

- Use your API secret key as the key.

- Use the signed_payload string as the message.


4
Compare the signature in the header to the expected signature.

If you just rotated the secret recently, we will create signatures with the new and old secrets.

The signature header value looks like this:

t=1492774577,v0=abcd1234,v0=abcd5678 . ‘abcd1234’ is generated with the new secret, and ‘abcd5678’ is generated with the old one.

The old secret will be expired after 48 hours, and only the new secret’s signature will be included.


Example Python method to verify the signature:

import hmac

import hashlib

def verify_signature(signature_header_value, payload, secret):

# Split the header value into components

parts = signature_header_value.split(',')

# Extract timestamp and signatures

timestamp = parts[0].split('=')[1]

signatures = [part.split('=')[1] for part in parts[1:]]

# Generate HMAC for the secret

timed_message = f'{timestamp}.{payload}'

hmac_obj = hmac.new(secret.encode(), timed_message.encode(), hashlib.sha256)

generated_signature = hmac_obj.hexdigest()

# Verify if any signature matches

return any(signature == generated_signature for signature in signatures)


If the signature does not match, do not trust the request's content. Webhook payloads include a lot of information, and we hash that information using your secret key to create the signature. 


This guide covers the basics of signature verification. The exact way to perform these steps may vary depending on the programming language and libraries you're using. If you encounter issues verifying the signature or have questions, please contact us for support.

Still need help? Contact Us Contact Us