diff --git a/packages/documentation/src/content/docs/integration/requirements/webhook-events.mdx b/packages/documentation/src/content/docs/integration/requirements/webhook-events.mdx
index 6140fc887e..4d0930df91 100644
--- a/packages/documentation/src/content/docs/integration/requirements/webhook-events.mdx
+++ b/packages/documentation/src/content/docs/integration/requirements/webhook-events.mdx
@@ -139,6 +139,69 @@ We provide an Bruno collection that can be used to test your webhook service integration.
+## Verify webhook signatures
+
+To protect your endpoint from unauthorized or spoofed requests, Rafiki supports an optional, but highly recommended, webhook signature verification process. By enabling signature verification, you can ensure that webhook requests are genuinely from Rafiki.
+
+Each webhook request includes a `Rafiki-Signature` header with a timestamp, version, and signature digest. If you instance is configured with both the `SIGNATURE_SECRET` (to generate the signature) and the `SIGNATURE_VERSION` (to set the version, defaults to v1) environment variables, you can verify the authenticity of each webhook request using the steps below.
+
+### Extract the timestamp and signature from the header
+
+The `Rafiki-Signature` header in each webhook request has the following format:
+
+
+
+```
+Rafiki-Signature: t=, v=
+```
+
+
+
+- `t=`: The UNIX timestamp (in seconds) when the signature was generated.
+- `v=`: The versioned HMAC SHA-256 signature digest. The default version is `v1`.
+
+### Prepare the signed payload string
+
+To recreate the signed payload string, concatenate the following.
+- The timestamp extracted from the header
+- A period (.) character
+- The actual JSON payload from the request body, containing the `id`, `type`, and `data` attributes
+
+This string format is essential for accurate signature validation.
+
+### Generate the expected signature
+
+Use HMAC SHA-256 with the `SIGNATURE_SECRET` environment variable as the key and the signed payload string as the message.
+
+### Compare the signatures
+
+Finally, compare the signature in the header to the expected signature you generated. For security, use a constant-time comparison function to prevent timing attacks.
+
+### Example
+Below is an example in JavaScript to verify Rafiki's webhook signature:
+
+
+
+```js
+function verifyWebhookSignature(request: Request): boolean {
+ const signatureParts = request.headers['Rafiki-Signature'].split(', ')
+ const timestamp = signatureParts[0].split('=')[1]
+ const signatureVersionAndDigest = signatureParts[1].split('=')
+ const signatureVersion = signatureVersionAndDigest[0].replace('v', '')
+ const signatureDigest = signatureVersionAndDigest[1]
+ if (signatureVersion !== config['SIGNATURE_VERSION']) {
+ return false
+ }
+ const payload = `${timestamp}.${canonicalize(request.body)}`
+ const hmac = createHmac('sha256', config['SIGNATURE_SECRET'])
+ hmac.update(payload)
+ const digest = hmac.digest('hex')
+ return digest === signatureDigest
+}
+```
+
+
+
## Event handling
### Asynchronous handling