meeva
Docs

Webhook Security

Verify that webhook requests are genuinely from Meeva using HMAC SHA-256 signatures.

Signature Header

Every webhook request from Meeva includes a signature header for verification:

Meeva-Signature: sha256=abc123...

This is an HMAC SHA-256 signature of the raw request body, using your webhook secret as the signing key.

Verification Steps

1

Extract the Signature

Get the Meeva-Signature header from the incoming request

2

Get Your Webhook Secret

Your secret starts with whsec_ — find it in your dashboard under Settings → Webhooks

3

Compute the HMAC

Calculate HMAC SHA-256 of the raw request body using your secret

4

Compare Signatures

If your computed signature matches the header, the request is authentic

⚠️ Important: Use Raw Body
Always compute the signature using the raw, unparsed request body. If you parse JSON first, the signature will not match. Many frameworks require special configuration to access the raw body.

Code Examples

const crypto = require('crypto');
const express = require('express');

const app = express();

// Middleware to capture raw body
app.use(express.json({
  verify: (req, res, buf) => {
    req.rawBody = buf;
  }
}));

// Verification function
function verifyWebhookSignature(rawBody, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');
  
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from('sha256=' + expected)
  );
}

// Webhook endpoint
app.post('/webhooks/meeva', (req, res) => {
  const signature = req.headers['meeva-signature'];
  const secret = process.env.MEEVA_WEBHOOK_SECRET;
  
  if (!verifyWebhookSignature(req.rawBody, signature, secret)) {
    console.error('Invalid webhook signature');
    return res.status(401).send('Invalid signature');
  }
  
  // Signature valid - process the event
  const event = req.body;
  console.log('Verified event:', event.type);
  
  res.status(200).send('OK');
});

Security Best Practices

Use timing-safe comparison

Prevents timing attacks on signature verification

Store secrets securely

Use environment variables, never hardcode

Reject invalid signatures

Never process webhooks with bad signatures

Log verification failures

Monitor for potential attacks