DEVELOPER GUIDE
Security
7 min
hmac verification for events and product reports klavi defaults to using the secretkey and sha 256 hmac algorithm to sign the payload the following parameter will be included in the request header that klavi post to you x klavi signature 11fad26ccd04a59085a738b8e20be5f4e01887a3c5cdc88cd37bf431e843083e x klavi timestamp 1740716924 we recommend that you verify the signature of the webhook tips for best practice create a sha 256 hmac of the request body using your secretkey as the key compare it to the signature included on the x klavi signature header if the two are equal then the request is valid, otherwise, it is spoofed the x klavi signature and x klavi timestamp header gets added to every event and product reports here is an example of signature verification in node js const crypto = require('crypto'); const partnersecret = '{{secret key}}'; router use('/webhook handler', (request, res) => { const body = request body; const signature = crypto createhmac('sha256', partnersecret) update(json stringify(body)) digest('hex'); if (request get('x klavi signature') !== signature) { throw new error('spoofing detected, rejecting webhook'); } }); allowed ip addresses to ensure webhook notifications reach your webhook listener server, you must add the following klavi ip addresses to your firewall’s allowlist environment ip address sandbox 18 231 92 86 testing 18 231 92 86 production 18 230 43 17 no matter how you receive shared data, the export ip addresses for klavi's various environments are as shown above if partners have stricter security requirements, you can only allow access to the above ip addresses data encryption klavi supports two methods plaintext and aes 256 algorithm for sensitive information partners can choose according to your actual situation in the console the decryption key for aes is the secretkey generated by klavi for you aes 256 encryption example from crypto cipher import aes from crypto util padding import pad, unpad from crypto random import get random bytes import base64 def aes encrypt(plain text, key) iv = get random bytes(16) cipher = aes new(key, aes mode cbc, iv) encrypted data = cipher encrypt(pad(plain text encode('utf 8'), aes block size)) encrypted message = base64 b64encode(iv + encrypted data) decode('utf 8') return encrypted message aes 256 decryption example from crypto cipher import aes from crypto util padding import pad, unpad from crypto random import get random bytes import base64 def aes encrypt(plain text, key) iv = get random bytes(16) cipher = aes new(key, aes mode cbc, iv) encrypted data = cipher encrypt(pad(plain text encode('utf 8'), aes block size)) encrypted message = base64 b64encode(iv + encrypted data) decode('utf 8') return encrypted message we can also customize and develop data encryption methods according to your requirements