Suggestions

close search

Add Messaging, Voice, and Authentication to your apps with Vonage Communications APIs

Visit the Vonage API Developer Portal

Secure callbacks

You can configure the webhooks you use for Video API to be secured with signed callbacks.

The secure callbacks feature provides a method for your application to verify a webhook callback request is coming from Vonage and its payload has not been tampered with during transit. When receiving a request, the incoming callback webhook will include a JWT token in the authorization header, which is signed with your signature secret.

The following API callbacks can be secured with signed callbacks and configured with their own signature secret:

Configuring secure callbacks

The following instructions can be used to enable Session Monitoring a secure callback. You can also follow these instructions similarly for other callbacks (for archive monitoring, SIP call monitoring, and experience composer monitoring).

  1. Log in to your Vonage Video API Account.

  2. From the left-hand menu, choose the desired Account.

  3. In the left-hand menu, select the Project for which you want to register a secure callback.

  4. Scroll down to Project Settings. Click the Edit icon, turn on the Secured Callback slider button, and click the Save button.

  5. Find Session Monitoring (or appropriate section) and click Configure.

  6. The user interface includes options to configure the callback URL, set the Signature secret, and toggle use of the signature secret for type of the callback (such as Session Monitoring).

  7. A randomly generated signature secret will be provided by the system each time the signature secret field is enabled. This pre-populated signature secret value can be used or overwritten with a user selected value. When receiving a callback, the incoming webhook will be signed with the signature secret configured in the field. Click Submit to configure this secret to be used for secure callbacks. (Note: the signature secret must be character string, with a minimum length of 1 character to a maximum length of 50 characters.)

  8. The system will report that secure callbacks have been configured with the URL and signature secret. Note that updates may take up to 30 minutes to apply the configuration in the platform.

Validating secure callbacks

Validating secure callbacks provides a number of security benefits, including:

There are two parts to validating secure callbacks:

Verifying the request

Callbacks will include a JWT in the Authorization header. Use the API key included in the JWT claims to identify which of your signature secrets has been used to sign the request. The secret used to sign the request corresponds to the signature secret associated with the api_key included in the JWT claims. You can identify your signature secret through the Vonage Video API Account portal.

Verify the payload has not been tampered with in transit

Once you have verified the authenticity of the request, you may optionally verify the request payload has not been tampered with by comparing a SHA-256 hash of the payload to the payload_hash field found in the JWT claims. If they do not match, then the payload has been tampered with during transit. You only need to verify the payload if you are using HTTP rather than HTTPS, as Transport Layer Security (TLS) prevents MITM attacks.

Code sample

The following Express example shows how to verify a webhook signature. It is recommended you use HTTPS protocol as it ensures that the request and response are encrypted on both the client and server ends.

const express = require('express');
const jwt = require('jsonwebtoken');
const sha256 = require('js-sha256');
const app = express();


app.use(express.json());

const VONAGE_API_SIGNATURE_SECRET = process.env.SIGNATURE_SECRET;

app.post('/video/webhook', express.raw({ type: 'application/json' }), (request, response) => {
  try {
    const userAgent = request.headers['user-agent'];
    if (userAgent !== 'Vonage/Callback/v1.0') {
      console.log('Bad token detected');
      return response.status(401).send();
    } else {
      const payload = request.body;
      let token = request.headers.authorization.split(" ")[1];
      // replace VIDEO_CALLBACK_SECRET with the secret value set at the Dashboard
      var decoded = jwt.verify(
        token,
        VONAGE_API_SIGNATURE_SECRET,
        { algorithms: ['HS256'] },
        );
      if (sha256(JSON.stringify(payload)) != decoded['payload_hash']) {
        console.log('tampering detected');
        response.status(401).send();
      }
    }
    console.log('Success');
    return response.status(204).send();
  } catch (err) {
    if (err instanceof JsonWebTokenError  || err instanceof TokenExpiredError){
      console.log('Token Error', err.message);
    } else {
      console.error(err);
    }
    return response.status(401).send();
  }
});

app.listen(4242, () => console.log('Running on port 4242'));

Known Limitations/Considerations

The following section covers limitations and considerations before enabling this feature.

Callback IP address

Once enabled for secure callbacks, the IP Address range used by the Vonage callback service will be of a different set than previous Video API callbacks. Please allow the following range to enable seamless communication with Vonage secure callbacks: 216.147.0.0/18.

Mutual TLS (mTLS)

mTLS is supported in the secure callbacks flow. (Previously, it was not)

Callback retry and backoff policy changes

Once enabled for secure callbacks, there will be a change in behavior for the callback retry and backoff policy.

Note that retries are only attempted for connectivity issues (not for other errors).

What will happen if the callback events of my application goes down?

Important: The new service will no longer disable event forwarding in the case of excessive delivery failures, since the retry and backoff mechanism will be used. Therefore, there will no longer be any expected email indication to notify that callbacks were disabled and need to be re-enabled, because the new service will not suspended/disable callbacks in any way.