Security & Signature Verification

Signature verification ensures that webhooks arriving at your webhook.rodeo URL are authentic and haven't been tampered with. This protects you from spoofed requests and man-in-the-middle attacks.

Why verify signatures?

Without signature verification, anyone who knows your webhook URL could send fake requests:

# Attacker sends a fake webhook
curl -X POST https://webhook.rodeo/w/you/payments \
  -d '{"amount": 1000000, "status": "paid"}'

If you blindly trust webhooks, you might process this fake payment. Signature verification solves this by cryptographically proving the webhook came from the legitimate service.

How it works

Signature verification uses HMAC-SHA256 (Hash-based Message Authentication Code):

  1. You share a secret with the webhook sender
  2. The sender creates an HMAC hash: HMAC-SHA256(secret, payload)
  3. The sender includes this hash in a header
  4. webhook.rodeo automatically detects the correct signature header and computes the same hash and compares
  5. If they match, the signature is valid ✅
  6. If they don't match, the request is rejected ❌

The beauty of HMAC is that only someone with the secret can create a valid signature, and any modification to the payload will cause the signature to fail.

Adding a secret

To enable signature verification:

  1. Create or edit your webhook
  2. Check "Enable signature verification"
  3. Enter a secret provided by the service sending the webhook
  4. Click "Save"

Verifying signatures

When a webhook sender includes a signature, webhook.rodeo automatically verifies it before processing the event.

Signature header format

The signature is sent in the appropriate signature header as a hex-encoded string:

X-Signature: a1b2c3d4e5f6...

Verification algorithm

webhook.rodeo uses this algorithm (in pseudocode):

function verifySignature(body, signature, secret) {
  const computedSignature = HMAC_SHA256(secret, body)
  return timingSafeEqual(signature, computedSignature)
}

Note the use of timingSafeEqual—this prevents timing attacks by comparing strings in constant time.

Was this page helpful?