Verifying webhooks
Each webhook call includes three headers with additional information used for verification:
svix-id: The unique message identifier for the webhook message. This identifier is unique across all messages but will remain the same when the same webhook is being resent (e.g., due to a previous failure).
svix-timestamp: The timestamp in seconds since the epoch.
svix-signature: The Base64-encoded list of signatures, space-delimited.
Constructing the Signed Content
The content to sign is created by concatenating the ID, timestamp, and payload, separated by a period (.
). In code, it would look something like this:
Where body
is the raw body of the request. The signature is highly sensitive to any changes, so even a minor modification in the body will result in a completely different signature. Therefore, you should not alter the body in any way before verifying it.
Determining the Expected Signature
Txn uses HMAC with SHA-256 to sign its webhooks.
To calculate the expected signature, you should HMAC the signedContent
(constructed as described above) using the Base64-decoded portion of your signing secret (the part after the whsec_
prefix) as the key. For example, if your secret is whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw
, you should use MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw
as the key.
Here's an example of hot to calcialte the signature in Ruby on Rails:
Here’s an example of how to calculate the signature in Node.js:
The generated signature should match one of the signatures sent in the svix-signature
header.
The svix-signature
header contains a list of space-delimited signatures with their corresponding version identifiers. The list usually contains one signature, but there can be multiple. For example:
Before verifying the signature, make sure to remove the version prefix and delimiter (e.g., v1,
).
Security Note: Use a constant-time string comparison method to compare signatures and prevent timing attacks.
Verify Timestamp
As mentioned above, Txn includes the timestamp of the attempt in the svix-timestamp
header. Compare this timestamp against your system's timestamp to ensure it falls within your acceptable tolerance range, helping to prevent timestamp attacks.
Last updated