Verification Process

Webhook verification process to receive events from Event Streaming.

Step 1. Create a Webhook Target

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

  • The webhook URL (destination).
  • A method for calling the URL (which defaults to POST) and a secret.

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 the initial registration of a target 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.
    1. Replace <YOUR_WEBHOOK_SECRET> with the secret of your webhook target.
curl -X GET \
  "https://example.com/webhook?token=<YOUR_WEBHOOK_SECRET>" \
  -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>"
}

[Optional] 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)
}

Remember to replace the following value:

  • YOUR_WEBHOOK_SECRET with your webhook target's secret.
  • YOUR_RESPONSE_TOKEN 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.