Verifying Webhook Signatures

📘

Note:

You don't need to verify webhook signatures in order to use our webhooks, but verifying the signatures adds an additional layer of security to your application, since you can verify the webhook request came from Canopy Connect.

Each webhook request sent by Canopy Connect includes a canopy-signature header. You can verify that the request came from Canopy Connect by following the instructions on this page.

Example of the Canopy Connect signature header:

canopy-signature: t=1645638136,s=18416697e8e8d0c07fde9dc16d410f9263193b631fd889ad81ald298bcd9241f

Step 1: Extract the timestamp and signatures from the header

Split the header, using the , character as the separator, to get a list of elements. Then split each element, using the = character as the separator, to get a prefix and value pair. The value for the prefix t corresponds to the timestamp, and s corresponds to the signature. You can discard all other elements.

Step 2: Prepare the signed_payload string

The signed_payload string is created by concatenating:

  • The timestamp (as a string)
  • The character .
  • The actual JSON payload (i.e., the request body)

Step 3: Determine the expected signature

Compute an HMAC with the SHA256 hash function. Use the webhooks signing secret as the key, and use the signed_payload string as the message.

Step 4: Compare the signatures

Compare the signature in the header to the expected signature. For an equality match, compute the difference between the current timestamp and the received timestamp, then decide if the difference is within your tolerance. To protect against timing attacks, use a constant-time string comparison to compare the expected signature to each of the received signatures.