Skip to content

Signature Verification

Every webhook received by Transyt is cryptographically verified using the provider’s specific signature scheme. This ensures webhooks are authentic and haven’t been tampered with in transit.

ProviderAlgorithmHeader
StripeHMAC-SHA256 + timestampStripe-Signature
SignalWireHMAC-SHA1 / HMAC-SHA256X-SignalWire-Signature / X-Twilio-Signature
TwilioHMAC-SHA1X-Twilio-Signature
LobHMAC-SHA256 + timestampLob-Signature
SES/SNSRSA certificate verificationSNS message fields
MailgunHMAC-SHA256Body fields (signature.timestamp, signature.token, signature.signature)
ResendSvix HMAC-SHA256svix-id, svix-timestamp, svix-signature
RampHMAC-SHA256X-Ramp-Webhook-Signature
LinearHMAC-SHA256Linear-Signature
Authorize.netHMAC-SHA512X-ANET-Signature
CrispURL key parameterQuery string ?key=
WhatConvertsURL key parameterQuery string ?key=
GenericFlexible (header, Bearer, URL param)Multiple

Providers that include timestamps in their signatures (Stripe, Lob, Resend) are validated against a 5-minute tolerance window (300 seconds). This prevents replay attacks where a captured valid webhook is re-sent later.

When signature verification fails:

  1. The event is stored with status = rejected
  2. The raw headers are preserved for debugging
  3. The last_error field contains the rejection reason
  4. A 401 Unauthorized response is returned to the provider

This approach ensures you can debug verification failures without losing the webhook data.

For development or testing, you can set skip_signature_verification: true on a provider account. This bypasses signature checks entirely.

All signature comparisons use constant-time algorithms (hmac.compare_digest) to prevent timing attacks. This applies to both HMAC signature verification and URL key parameter authentication.