From 8919a2b2e9997491d44f7b40e68bbdf6667c35a4 Mon Sep 17 00:00:00 2001 From: pravin Date: Wed, 17 Dec 2025 16:39:53 +0530 Subject: [PATCH 1/3] Update Webhook.md Updated the document for webhook secret key --- docs/docs/help/Settings/Webhook.md | 128 +++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) diff --git a/docs/docs/help/Settings/Webhook.md b/docs/docs/help/Settings/Webhook.md index 219cbffc6..0a0c1d15f 100644 --- a/docs/docs/help/Settings/Webhook.md +++ b/docs/docs/help/Settings/Webhook.md @@ -40,6 +40,134 @@ Suppose you're using OpenSign to collect eSignatures: --- +## ๐Ÿงญ How to Create a Webhook Security Key + +A **Webhook Security Key** (also called a webhook secret) is a shared secret used to verify that webhook requests are genuinely sent by OpenSign and have not been tampered with. + +### Steps to Create a Webhook Security Key + +1. Log in to your **OpenSign** account. +2. Navigate to **Settings โ†’ Webhooks**. +3. Add or edit a webhook endpoint. +4. Generate a **Security Key** (or manually enter a strong secret). + - Use a long, random string (at least 32 characters). + - Example: `a50a904a2a329d761781dac27c984416a07396736ac5588b62c6fe226538fbca` +5. Save the webhook configuration. + +โš ๏ธ **Important:** Store this key securely. Do not expose it in client-side code or public repositories. + +--- + +## ๐Ÿ” How the Webhook Security Key Works + +OpenSign signs every webhook request using your security key. + +### High-level Flow + +1. An event occurs (e.g. create document, document viewed, signed, completed, and declined). +2. OpenSign sends a webhook request to your configured endpoint. +3. OpenSign generates a signature using: + - The **raw request payload** + - Your **webhook security key** + - The **HMAC-SHA256** algorithm +4. The generated signature is sent in the request header: + +``` +x-webhook-signature +``` + +5. Your server recomputes the signature using the same payload and secret. +6. If both signatures match, the request is verified as authentic. + +--- + +## ๐Ÿงช Signature Verification Example (Node.js) + +Below is a sample implementation to verify the webhook signature on your server. + +```js +const crypto = require("crypto"); + +function verifySignature(req, secret) { + const receivedSignature = req.headers["x-webhook-signature"]; + const payload = req.body; + + const expectedSignature = crypto + .createHmac("sha256", secret) + .update(JSON.stringify(payload)) + .digest("hex"); + + return receivedSignature === expectedSignature; +} +``` + +### Usage Example + +```js +const isValid = verifySignature(req, WEBHOOK_SECRET); + +if (!isValid) { + return res.status(401).send("Invalid webhook signature"); +} + +// Process webhook event +``` + +--- + +## ๐Ÿ“ฆ Sample Webhook Payload + +```json +{ + "event": "viewed", + "objectId": "d4LP0kKezS", + "type": "request-sign", + "file": "https://...pdf", + "name": "Nu-international-application-form", + "note": "Please review and sign this document", + "signers": [ + { + "name": "Mathew Wade", + "email": "mathew.wade@opensignlabs.com" + }, + { + "name": "Steve Broad", + "email": "steve.Broad@opensignlabs.com", + "phone": "2678288322" + } + ], + "viewedBy": "mathew.wade@opensignlabs.com", + "viewedAt": "Wed, 17 Dec 2025 13:46:05 GMT+5:30", + "createdAt": "Wed, 17 Dec 2025 13:36:40 GMT+5:30" +} +``` + +The corresponding signature is sent in the request header: + +``` +x-webhook-signature: bcf57b06dde0c030d9423639824bad17ab7dd09ea3bf0a743773b95254ecf78e +``` +--- + +## โœ… Best Practices + +- Always verify the webhook signature before processing the payload. +- Use the **raw request body** for signature calculation (avoid modifying it). +- Rotate your webhook security key periodically. +- Return a **2xx** HTTP status only after successful verification. + +--- + +## ๐Ÿงฉ Common Issues + +- **Signature mismatch**: Ensure the payload is stringified exactly as received. +- **Missing header**: Confirm `x-webhook-signature` is present in the request. +- **Wrong secret**: Verify the same security key is used on both sides. + +--- + +This mechanism ensures webhook requests are secure, tamper-proof, and trustworthy. + ## ๐Ÿงช Sandbox Webhook - You can also add webhook for the **Sandbox** environment on the same page. From ee8525dac3b6b9e0d40e1c88ad84d96dd88c3eb6 Mon Sep 17 00:00:00 2001 From: pravin Date: Wed, 17 Dec 2025 17:54:05 +0530 Subject: [PATCH 2/3] Update Webhook.md update the image on the webhook page. --- docs/docs/help/Settings/Webhook.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/docs/help/Settings/Webhook.md b/docs/docs/help/Settings/Webhook.md index 0a0c1d15f..c4c87b1d9 100644 --- a/docs/docs/help/Settings/Webhook.md +++ b/docs/docs/help/Settings/Webhook.md @@ -28,7 +28,7 @@ Suppose you're using OpenSign to collect eSignatures: **Step 1:** Log in to your OpenSign account using your credentials. **Step 2:** Navigate to **Settings โ†’ Webhook**. -![Navigate to Add Webhook](https://github.com/user-attachments/assets/6b069b6c-d2b7-408b-b7c9-7fbeb55d6c98) +Navigate to Add Webhook **Step 3:** Click **Add Webhook**. @@ -36,8 +36,6 @@ Suppose you're using OpenSign to collect eSignatures: > **Note:** To enable **Live Webhook** support, you must upgrade to a **paid plan** โ€” either the **Professional** or **Teams** plan. -![Add Webhook](https://github.com/user-attachments/assets/ff68b255-a6e6-4a7d-9cef-6dd9e3b6d4e4) - --- ## ๐Ÿงญ How to Create a Webhook Security Key @@ -49,10 +47,11 @@ A **Webhook Security Key** (also called a webhook secret) is a shared secret use 1. Log in to your **OpenSign** account. 2. Navigate to **Settings โ†’ Webhooks**. 3. Add or edit a webhook endpoint. -4. Generate a **Security Key** (or manually enter a strong secret). - - Use a long, random string (at least 32 characters). +4. Generate a **Security Key** click Enable authentication. - Example: `a50a904a2a329d761781dac27c984416a07396736ac5588b62c6fe226538fbca` 5. Save the webhook configuration. + +webhook security key โš ๏ธ **Important:** Store this key securely. Do not expose it in client-side code or public repositories. From cb9f75bf2f0ee97b58b0c417b7ba8a182a9447f7 Mon Sep 17 00:00:00 2001 From: pravin Date: Fri, 19 Dec 2025 21:43:47 +0530 Subject: [PATCH 3/3] Update Webhook.md update the help document for webhook secret key --- docs/docs/help/Settings/Webhook.md | 62 +++++++++++------------------- 1 file changed, 23 insertions(+), 39 deletions(-) diff --git a/docs/docs/help/Settings/Webhook.md b/docs/docs/help/Settings/Webhook.md index c4c87b1d9..f34d1f2f1 100644 --- a/docs/docs/help/Settings/Webhook.md +++ b/docs/docs/help/Settings/Webhook.md @@ -47,11 +47,12 @@ A **Webhook Security Key** (also called a webhook secret) is a shared secret use 1. Log in to your **OpenSign** account. 2. Navigate to **Settings โ†’ Webhooks**. 3. Add or edit a webhook endpoint. -4. Generate a **Security Key** click Enable authentication. +4. Generate a Security Key by clicking Enable Authentication, then click the Generate button. +The webhook security key has been generated. - Example: `a50a904a2a329d761781dac27c984416a07396736ac5588b62c6fe226538fbca` -5. Save the webhook configuration. +6. Save the webhook configuration. -webhook security key +webhook security key โš ๏ธ **Important:** Store this key securely. Do not expose it in client-side code or public repositories. @@ -80,11 +81,14 @@ x-webhook-signature --- -## ๐Ÿงช Signature Verification Example (Node.js) +// Process webhook event +``` -Below is a sample implementation to verify the webhook signature on your server. +--- -```js +## ๐Ÿ“ฆ Sample Webhook Payload + +```json const crypto = require("crypto"); function verifySignature(req, secret) { @@ -98,47 +102,27 @@ function verifySignature(req, secret) { return receivedSignature === expectedSignature; } -``` -### Usage Example - -```js -const isValid = verifySignature(req, WEBHOOK_SECRET); - -if (!isValid) { - return res.status(401).send("Invalid webhook signature"); -} - -// Process webhook event -``` - ---- - -## ๐Ÿ“ฆ Sample Webhook Payload - -```json -{ - "event": "viewed", - "objectId": "d4LP0kKezS", +console.log("Try programiz.pro", verifySignature({body: { + "event": "created", "type": "request-sign", - "file": "https://...pdf", - "name": "Nu-international-application-form", + "objectId": "SBEbnHwfrN", + "file": "https://legadratw3d.ams3.digitaloceanspaces.com/c3f0bc11b84a87e6265de6bf28e5015e_uoeksXXU6FI5Op2B.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=DO00QAPRB3CQRWHWQ8ZB%2F20251219%2Fus-west%2Fs3%2Faws4_request&X-Amz-Date=20251219T152806Z&X-Amz-Expires=900&X-Amz-Signature=9635dfb8ee8fde933f881905a97f869578ef7e99b337d4b21a0805b8317fd70d&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject", + "name": "Sample Test Doc Line Compressed", "note": "Please review and sign this document", + "description": "", "signers": [ { - "name": "Mathew Wade", - "email": "mathew.wade@opensignlabs.com" + "name": "Peter Mark", + "email": "peter.mark@opensignlabs.com" }, { - "name": "Steve Broad", - "email": "steve.Broad@opensignlabs.com", - "phone": "2678288322" + "name": "kelvin bosch", + "email": "kelvin.bosch@opensignlabs.com" } ], - "viewedBy": "mathew.wade@opensignlabs.com", - "viewedAt": "Wed, 17 Dec 2025 13:46:05 GMT+5:30", - "createdAt": "Wed, 17 Dec 2025 13:36:40 GMT+5:30" -} + "createdAt": "Sat, 20 Dec 2025 00:58:20 GMT+9:30" +}, headers:{"x-webhook-signature":"52958fd3900f19ba6485319eb2622ef0ec4cf5ddfe36509cbe95eb706ed6b8c2" }}, "0906e8cbc88da0d5a6fd78162eb8e5e57ba7bd99bdc472145dc089d7f82b0a4a")); ``` The corresponding signature is sent in the request header: @@ -146,7 +130,7 @@ The corresponding signature is sent in the request header: ``` x-webhook-signature: bcf57b06dde0c030d9423639824bad17ab7dd09ea3bf0a743773b95254ecf78e ``` ---- +If the script returns true, it means the webhook is valid and has not been tampered with. ## โœ… Best Practices