Verification Process

Step 1. Create a Webhook Target

When creating a webhook target, you'll provide settings that include:

  • destination: The webhook URL
  • methodThe HTTP method used to call the URL (defaults to POST).
  • secret: An alphanumeric string with a minimum length of 10. A longer string is recommended for enhanced security.

Once created, the webhook target was in the "active" state.

.....
"settings": {
        "destination": "http://example.com/webhook",
        "method": "POST",
        "secret": "************here"
    },
"status": "active",
"type": "webhook",
"updated_at": "2024-03-06T09:48:06.673414Z"

However, a target must have the "connected" status to receive messages. Therefore, webhook must pass a verification process. This verification is a security measure to ensure that only legitimate customers can register a webhook.

To achieve this, we implement a Challenge Response Check (CRC).


Step 2. Challenge Response Check (CRC)

The webhook verification process consists of a Challenge Response Check (CRC), which occurs during a target's initial registration and periodically throughout its lifespan.

  1. The webhook verifier initiates the CRC by sending a GET request to your webhook. This request includes a query parameter called token, which acts as the Challenge Token.
curl -X GET \
  "https://example.com/webhook?token=<CHALLENGE_TOKEN>" \
  -H "Accept: application/json" 
  1. To pass the CRC, the webhook must return a response_token. This response_token is generated using HMAC with SHA256, where the webhook should use the webhook secret as the HMAC key and the challenge token as the payload.
{
  "response_token": "sha256=sU+MyTOKEN="
}
  1. After receiving the verification payload, event streaming generates an HMAC using the same information and compares the values.
  2. If the webhook payload matches the expected HMAC, the target's status is updated from its previous "active" state to "connected".
{
  "bd_metadata": {
    "schema": "system.connection",
    "version": 0
  },
  "connection_time": "2024-02-01T09:30:08.776743Z",
  "disconnect_time": "2024-02-01T09:27:58.266261Z",
  "new_status": "connected",
  "previous_status": "active",
  "target_id": "<THE_TARGET_ID>"
}

Example: Challenge Response Check Implementation in Go

Below you will find a code snippet in Go that implements the Challenge Response Check for a webhook:

package main

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"fmt"
	"net/http"
)

func main() {

	http.HandleFunc("/", func(rw http.ResponseWriter, req *http.Request) {
		challenge := req.URL.Query().Get("token")

		key := []byte("<YOUR_WEBHOOK_SECRET")
		h := hmac.New(sha256.New, key)
		h.Write([]byte(challenge))

		hash := h.Sum(nil)
		encodedHash := base64.StdEncoding.EncodeToString(hash)
		response := "sha256=" + encodedHash
		_, _ = rw.Write([]byte(fmt.Sprintf(`{ "response_token": "<YOUR_RESPONSE_TOKEN"}`, response)))
	})

	http.ListenAndServe(":8082", http.DefaultServeMux)
}

Replace the following value:

  • YOUR_WEBHOOK_SECRET: Replace this with your webhook target's secret. The secret should be an alphanumeric string with a minimum length of 10. For better security, a longer string is recommended.
  • YOUR_RESPONSE_TOKEN: Replace this with the token you got when initiating the CRC.

👋 Need Help?

Contact us through email or our support page for any issues, bugs, or assistance you may need.