Skip to main content

Webhook Security

When building an application with SignalWire services, you are very likely to use webhooks to exchange information with SignalWire. A webhook is an HTTP(S) request sent to your web application when a key event has occurred, such as an inbound call, inbound message, or a status change. This allows SignalWire to query your web application in order for instructions on what to do next. For example, you might use a webhook to handle an inbound call by reading the instructions in your webhook to play an IVR, route the customer to the right department, and connect them with an agent. You could also use a webhook as a status callback where each status change of a call or message is sent to your web application which might store some instructions for handling emergent errors.

If your application exposes sensitive data or makes changes to your data, then you may want verify that the HTTP requests to your web application are coming from SignalWire, and not a malicious third party. To support that level of security, SignalWire signs every webhook request with a digital HMAC signature.

You can find your personalized signing key in the API Credentials Space of your Dashboard. Click "Show" to display the key and a copy icon to easily copy the signature into your code. Each project in your Dashboard will have its own signing key for verification. You can reset the signing key by clicking the reset button. Please note that it takes about a minute for the new key to be active. You will also be able to see the new key before finalizing the reset request so that you can copy it to wherever it needs to be updated.

API Credentials page

Verifying the webhook signature

In your webhook logic, you can include the validateRequest method to check the key include on the request against the value you copy from your Credentials page.

import { RestClient } from "@signalwire/compatibility-api";

app.post("/mywebhook", (req, res) => {
const valid = RestClient.validateRequest(
"XXXXXXXX", // signing key copied from your credentials page
req.headers["x-signalwire-signature"],
"https://example.ngrok.io/mywebhook",
req.body
);
});

This method takes as its parameters:

  1. The signing key copied from your Credentials page.
  2. Where to find the request signing key in the request header.
  3. The url the request is calling.
  4. The included request parameters. This should virtually always be the request body.

If you are using Express for your application, you also have the option of using the middleware shortcut webhook() which doesn't require any parameters instead of the validateRequest method.

app.post("/mywebhook", signalwire.webhook(), (req, res) => {
const response = new VoiceResponse();
// application logic
});