Authenticate webhook requests

Based on the events, webhook requests are triggered. Webhook requests are the actual HTTP requests sent by Liminal to your webhook URL. These requests contain the updates on the transactions. Webhook requests consist of an HTTP method, a webhook URL, headers, and a payload containing the data or information related to the event.

After you have set up your webhook URL in Vaults, a unique Signing Key is generated as shown in the screenshot below. You can use this key to verify it against the key you receive in the header of the webhooks requests sent by Liminal. If both are the same, then the webhook requests are authentic.

After this, you must implement the following code snippet into your application. It is used to verify the authenticity of webhook requests by comparing signatures and taking appropriate actions based on the validation result. The code is written in Node.js. However, you can also translate this code into your preferred programming language.

import * as crypto from "crypto"

const getSignature = (data: any, signingKey:string) => {
    try {
        let signature = crypto.createHmac('sha256', signingKey).update(JSON.stringify(data)).digest('hex');
        return signature;
    } catch (error) {
        Logger.error(`Failed to get signature ${error}`);
    }
}
  
router.post('YOUR-WEBHOOK-ENDPOINT', async (req: Request, res: Response) => {
	
  // Read Header Value => Here you will recevie signature from Liminal Web App
  let liminalSignatureHeaderValue:string=req.headers["x-liminal-signature"];
  
  //Set Signature(Signing Key) value which you will get from Web UI(Setting=>WebHook Section)
  let clientSignatureValue:string="YOUR-SIGNATURE-KEY";

  // Read Request Body.
  let transferStatusObj:any=req.body;

  // Get Signature
  let generatedSignature:string=getSignature(transferStatusObj,clientSignatureValue);

  if(liminalSignatureHeaderValue===generatedSignature){

    console.log(`Valid Signature`);

     // Your Code [Data Insert]
  }
  else
  {
    console.log(`InValid Signature`); 
  }
  
}

Code explanation

The components of the above code and their functions are explained as follows:

The code from the line number 1 to 10 defines a function getSignature that generates a cryptographic signature for a given data using a specific signing key. It uses the 'sha256' hashing algorithm to create a HMAC (Hash-based Message Authentication Code) and returns the digest as a hexadecimal string. If any error occurs during this process, it's caught and logged to the console.

The code starting from line number 12 to the end shows the creation of an endpoint responsible for handling webhook data. Specifically, at line 15, we focus on the retrieval of the Liminal signature from the request header, whereas line 16 focuses on the requirement for the client to provide the signature generated through the Vaults UI.

On line number 21, the code demonstrates the process of extracting webhook data from the request body. Line 24 signifies the critical step of validating the signature by using both the request body and the client's signature key.

Finally, lines 26 to 35 address the validation process. When the Liminal signature matches the signature generated by you in Vaults, it is considered a valid signature. If they don’t match, then it is considered an invalid signature.