A webhook is a server endpoint meant to be used by another service. This means it's open to the World Wide Web and could be used by anyone, not only Outseta.
You must configure a Webhook Signature Key to ensure that does not happen.
When doing so, Outseta adds a signature header to all requests to your webhooks, and you may verify that signature to make sure the request does indeed come from Outseta.
The signature is a Hash-based Message Authentication Code (HMAC) created with the sha256 algorithm. To verify the signature, you calculate the same HMAC in your webhook and check to see if it matches the signature from the header.
TLDR
In your webhook:
- Get the raw body from the request as a string.
- Convert the body from a UTF8 string into a byte array, and decode the Webhook Signature Key from hex into a byte array
- Calculate the HMAC of the UTF8 Byte Arrays versions of the body and Webhook Signature Key
- Compare the calculated HMAC Hex with an added
sha256=
with the one sent in thex-hub-signature-256
header
1. Enable webhook signature by adding a key
Before creating any verification logic in your webhook, enable Webhook Signatures in Outseta by doing the following:
1.1 Generate your signature key
The Webhook Signature Key must be a 32-byte hex-encoded string.
If you have OpenSSL installed, you may run the following command in your terminal:
openssl rand -hex 32
1.2 Add your signature key
Add the key you generated in step one to Settings > Notifications > ⚙️:
2. Verify the signature in your webhook
After Webhook Signatures in Outseta is enabled you may add verification logic in your webhook.
- Get the raw body from the request as a string.
- Convert the body from a UTF8 string into a byte array, and decode the Webhook Signature Key from hex into a byte array
- Calculate the HMAC of the UTF8 Byte Arrays versions of the body and Webhook Signature Key
- Compare the calculated HMAC Hex with an added
sha256=
with the one sent in thex-hub-signature-256
header
Using Node steps 2 to 4 can be achieved with the following code:
exports.verifyOutsetaSignature = ( signature = "", bodyAsString = "", keyAsHex = "", ) => { const key = Buffer.from(keyAsHex, "hex"); const payloadToSign = Buffer.from(bodyAsString, "utf-8"); const calculatedSignature = crypto .createHmac("sha256", key) .update(payloadToSign) .digest("hex"); return signature === "sha256=" + calculatedSignature; };
Full Express/Node demo on Code Sandbox
Test that it works as expected
One of the easier actions to trigger is Person Login, making it a good candidate when developing your webhooks.
- Log in to your site
- Verify that there is a call to your webhook within a couple of minutes that passes validation.
- Change the Webhook Signature Key
- Either in your code or in Outsate, but not both.
- Log out and in again to your site
- Verify that there is a call to your webhook within a couple of minutes that does not pass validation.
- Change the Webhook Signature Key
- Change it back to the setup you had in Step 1.