Verifying webhook signatures

Check that a webhook came from Teak before you act on it.

When your subscription has a secret, Teak signs every webhook. Verify the signature before you act on an event, so no one else can send your endpoint fake events.

The recipe below walks through the code in Node.js and Python. This page covers the header, test values, and keeping your secret safe.

The signature header

Each request includes:

X-Protecht-Signature: sha256: 9gVpchQZGFoyjw+fuIl6ZgwR5vkOGuhc63yzDdD6cko=

The value is the algorithm (sha256), a colon and a space, then a base64-encoded HMAC-SHA256 of the raw request body, keyed with your subscription's secret.

Unsigned webhooks can't be verified

Without a secret, the header contains a timestamp instead (t: 1727539200). Add a secret to your subscription to receive signed webhooks.

Requests also include X-TicketGuardian-Signature with the same value, for older integrations. Use X-Protecht-Signature.

Test your verification

Check your code against this example before testing with real events:

InputValue
Secretso-secret
Raw body{"foo": "bar"} (with a space after the colon)
Expected headersha256: 9gVpchQZGFoyjw+fuIl6ZgwR5vkOGuhc63yzDdD6cko=

Your function should return true for this input, and false if you change the secret or a single byte of the body.

Keep your secret safe

  • Store the secret in your server's secret manager or environment, never in source control or client-side code.
  • Signatures don't include a timestamp, so they don't protect against a request being replayed. Handle repeats as described in Receiving webhooks, and serve your endpoint over HTTPS only.
  • To rotate the secret, accept both the old and new secrets on your server while you update the subscription, so no webhook is rejected during the switch:

Next steps

With signatures checked, handle the events you subscribe to:


Did this page help you?