Securing Your Webhooks with Secret Keys
When an external service, like Pulsetic, sends data to your application (often called a "webhook"), it's crucial to ensure that these requests are legitimate and not coming from an impostor. This tutorial explains how to use a secret key to validate incoming requests, making sure only authorized services can communicate with your backend.
The Core Idea: A Secret Handshake for Your Backend
This "secret password" is a unique string of characters (your secret key) that is known only to Pulsetic (the sender) and your backend (the receiver). Every time Pulsetic sends a webhook, it includes this secret key within the request. Your backend then checks for this key; if it matches, the request is processed; otherwise, it's rejected.
There are two common ways Pulsetic can send this secret:
- Custom Header: Pulsetic includes the secret in a special, custom-named part of the request, like
X-Pulsetic-Secret
. - Authorization Header: Pulsetic includes the secret in a standard
Authorization
header, often prefixed withBearer
(e.g.,Authorization: Bearer YOUR_SECRET_KEY
). This is a widely adopted standard for API authentication.
Option 1: Using a Custom Header (e.g., X-Pulsetic-Secret
)
This method involves creating a unique, non-standard header just for your secret. It's like adding a special, custom-made label to your package.
- First, decide on your secret key. Let's use
my-custom-webhook-secret-123
. Store this secret securely in your backend (e.g., as an environment variableWEBHOOK_SECRET_KEY
). Your backend code will look for this exact value. - Go to your Pulsetic monitor's Advanced Settings.
- Navigate to Request Settings.
- Find the section for Request Headers.
- Add a new header with:
- Header Name:
X-Pulsetic-Secret
(TheX-
prefix is a common convention for custom headers). - Header Value:
my-custom-webhook-secret-123
(Your actual secret key). - Save these settings in Pulsetic.
- When your backend receives a request from Pulsetic, it will look for this custom header.
Backend Code Example (Node.js/Express):
// In your webhook endpoint handler const receivedSecret = req.headers['x-pulsetic-secret']; // Header names are usually lowercase in Node.js/Express if (receivedSecret === process.env.WEBHOOK_SECRET_KEY) { // Secret matches! Process the request. console.log('Custom header secret matched. Request is valid.'); } else { // Secret does not match or is missing. Reject the request. res.status(401).send('Unauthorized: Invalid custom secret.'); }
Note:
Your backend compares receivedSecret
with the WEBHOOK_SECRET_KEY
it expects.
Option 2: Using an Authorization Header (Bearer Token)
This is a more standardized way to send a secret, often used for API authentication. It's like presenting a "bearer token" (your secret) as proof of identity.
- Choose your secret key. For this option, let's use
my-bearer-token-secret-xyz789
. Store this secret securely in your backend (e.g., as an environment variableWEBHOOK_SECRET_KEY
). - Go to your Pulsetic monitor's Advanced Settings.
- Navigate to Request Settings.
- Find the section for Request Headers.
- Add a new header with:
- Header Name:
Authorization
(This is a standard HTTP header name). - Header Value:
Bearer my-bearer-token-secret-xyz789
(It must start withBearer
followed by a space, then your actual secret key). - Save these settings in Pulsetic.
- Your backend will receive the
Authorization
header. You'll need to parse it to extract just the token part.
Backend Code Example (Node.js/Express):
// In your webhook endpoint handler const authHeader = req.headers['authorization']; let receivedSecret = null; if (authHeader && authHeader.startsWith('Bearer ')) { receivedSecret = authHeader.substring(7); // Extracts the string after "Bearer " } if (receivedSecret === process.env.WEBHOOK_SECRET_KEY) { // Secret matches! Process the request. console.log('Authorization header secret matched. Request is valid.'); } else { // Secret does not match or is missing. Reject the request. res.status(401).send('Unauthorized: Invalid or missing bearer token.'); }
Your backend extracts the token and compares it with the WEBHOOK_SECRET_KEY
it expects.
Here is a more in-depth guide on configuring all of Pulsetic's Advanced Settings.