INTRODUCTION TO WEBHOOKS WITH DOPPLER
Introduction to Webhooks
Webhook is a way for an application to notify other applications with real-time information automatically when a specific event occurs. A webhook provider will usually require a webhook URL to which information (webhook or aka web callback) is sent. Webhook makes use of the HTTP POST request method to send information. Popular applications like Stripe, Twilio and Github make use of webhooks to send or update data and take other actions. Essentially, a webhook asynchronously sends a notification when a specified event is triggered with which you can run processes based on that notification.
Why use webhooks
Let’s say you make a withdrawal from your bank account, you don’t want to have to go to the ATM (Automated Teller Machine) or the bank to check your account balance every time you make a withdrawal. With webhooks, you can be notified automatically with your updated balance as well as details of a withdrawal every time you make one.
Webhooks are very useful and here are some of the benefits of using webhooks:
- Webhooks are automated and happen asynchronously.
- Webhook notifications are sent immediately when a given event is triggered (in real-time).
- You can connect to a payment gateway using webhooks, to send notifications of the payments after the payment has been completed.
Webhooks vs APIs
Webhooks allows applications to communicate with each other, makes use of HTTP POST requests and also use JSON format or XML format and so one would ask the difference between webhooks and APIs.
Well, while with APIs you have to pull data by making periodic requests to the server to stay up to date, webhooks on the other hand push data to you once a particular event occurs. Let’s revisit our example again. API will be likened to you going to check your account balance and details of the transaction every time you make a withdrawal, while webhooks are like your bank automatically sending you those details every time you make a withdrawal. This is why webhooks are often referred to as “reverse APIs”
What is Doppler
Doppler acts as your source of truth for managing and storing secrets, it basically helps you securely store your tokens/keys for your various environments and access them when you need them.
With Doppler, you don’t have to use the .env
file anymore. All you have to do is store it in Doppler and request it from Doppler in your workspace. Doppler will then retrieve the latest version of your secrets and inject them as environment variables into the Nodejs process.
We are not going to be covering Doppler set up in this guide but you can visit https://docs.doppler.com/docs/enclave-installation since doppler securely stores and manages your secrets for you. Your data is never stored on their servers and they use end-to-end encryption to keep your data safe while it’s in transit. Doppler provides a nice and intuitive dashboard for you to manage your application and secrets. Fair Pricing and even free (forever) with unlimited users, unlimited secrets and secrets referencing. You can have a look at the pricing at doppler.com/pricing.) and follow the guide to set up Doppler CLI.
Why use Doppler
- With doppler, you don’t have to use the .env files anymore or worry about configuration for the file as doppler handles all of these for you and simply injects your variables into Nodejs process.
- You no longer have to worry about pushing secrets mistakenly to your version control system (e.g GitHub or bitbucket) since doppler securely stores and manages your secrets for you. Your data is never stored on their servers and they use end-to-end encryption to keep your data safe while it’s in transit.
- Doppler provides a nice and intuitive dashboard for you to manage your application and secrets.
Webhook in Doppler
In Doppler, you can use webhooks to get notifications every time a secret has been changed or updated. For example; you can use webhooks to restart or redeploy an application when a secret is changed. The webhook receives a single POST request from Doppler whenever a change is made to secrets for that project.
To follow this guide, you will need to have some knowledge of [Nodejs](nodejs.dev/learn), [express.js](expressjs.com/en/starter/installing.html), [npm](docs.npmjs.com/getting-started) and environment variables to follow along.
Please note that to make use of webhooks in Doppler, Doppler requires a Pro subscription and only an admin of the workspace can manage webhooks.
Create a webhook in Doppler
To create a webhook in Doppler, navigate to project
and click on the project config. See the sample in the image below:
Next, click on webhooks from the navigation options and click on Add webhook or click on the + Add button.
Next, we have to specify our webhook url. Remember this is where Doppler can send us information when the secret change (event) occurs. After clicking as shown in the image above, you’re welcomed with a modal to input your webhook url and optionally a secret value which can be used to sign the webhook. We will talk about webhook signing later on in the guide.
Almost there! We can now see our list of added webhooks. Lastly, we can select an environment for which we want to be notified when secrets in that environment have been changed and that’s it, we’ve completely set up a webhook in Doppler!
Doppler’s webhook payload (request body)
When a secret is changed, Doppler sends a notification (web callback) to the webhook url which you have specified when creating the webhook. The payload contains details of the config, project and workspace objects. Here’s a sample payload from webhook.
{
"type": "enclave.project.config.secrets.update",
"config": {
"name": "super_dev",
"created_at": "2021-10-20T10:20:33.266Z",
"environment": "dev",
"project": "413facq6620"
},
"project": {
"id": "413facq6620",
"name": "super project",
"description": "Your super project!",
"created_at": "2021-10-20T10:20:33.266Z"
},
"workplace": {
"id": "dcc96",
"name": "super zone",
"billing_email": "superdev@gmail.com"
}
}
Webhook Signing and Verification
If you provide Doppler with a secret when you create or add a new webhook, Doppler signs the webhook by including a signature in each event’s X-Doppler-Signature
header. The purpose of this signature is for you to verify that the notification was sent from Doppler and not some third party.
Please note that to enable webhook verification/signage, you have to pass in a secret to Doppler when you provide your webhook URL. Doppler uses this secret to create a signature and includes it in the event’s
X-Doppler-Signature
header.
The signature is generated using the HMAC-SHA256 crypto hashing algorithm. The X-Doppler-Signature
header will contain a SHA256 hash of the payload (request body) prepended with “sha256=” (e.g. X-Doppler-Signature: sha256= 70c0567b214714143a63e512fc457f5ae8fd9666e75c6c3bdbba064bee0d2f0406d42797864
). Learn more about Crypto modules at nodejs.org/api/crypto.html.
To verify the signature, you have to create your own SHA256 hash of the webhook payload (request body) sent to you by Doppler using the secret value you provided when creating the webhook. Then compare the X-Doppler-Signature
header value against your own computed value using [Crypto timing-safe equality function](nodejs.org/api/crypto.html#crypto_crypto_ti..). This crypto function returns true if argument a
is equal to argument b
, without leaking timing information that would allow an attacker to guess one of the values. So if the value returned by this function is true, then you know the webhook was sent by Doppler, else it is not and so you wouldn’t run any process.
Here is an example of how you can do this using Node.js.
const bodyParser = require("body-parser");
const crypto = require("crypto");
const express = require("express");
const app = express();
app.use(bodyParser.json({
limit: '200kb',
}));
app.post('/webhooks/doppler', (req, res) => {
const requestHMAC = req.header("X-Doppler-Signature"); // Doppler stores its own computed signature in the X-Doppler-Signature header
const secret = process.env.WEBHOOK_SECRET_VALUE; //this is the secret you provided when creating the webhook
const myComputedHMAC = `sha256=${crypto.createHmac('sha256', secret)
.update(JSON.stringify(req.body))
.digest('hex')}`;
const signatureMatches = crypto.timingSafeEqual(Buffer.from(requestHMAC), Buffer.from(myComputedHMAC));
if (signatureMatches) {
// run process like restart application or whatever you want to run when the secret changes
}
res.sendStatus(signatureMatches ? 200 : 401);
});
Remove Webhook
You can remove or disable a webhook in doppler by navigating to your list of webhooks and clicking on the disable or remove button.
Conclusion
Webhooks are a great feature for the web, more and more people are beginning to embrace and utilise the power of webhooks. Payment industries such as Stripe, Paypal, Payoneer etc. make use of webhook to send notifications after transactions have been completed. This is not only beneficial for payment industries alone as Github and Twilio also make use of webhooks. Doppler is a very convenient tool for you to utilise webhooks when managing your secrets. You want to be able to do something when these secrets are changed or updated and as you’ve seen, Doppler helps you handle this in an easy and secure way. You’ve come to the end of this article, thank you for reading!