Checking Webhook Signatures
The webhook events that Tilled sends to your endpoints are signed. We do this by including a signature in the tilled-signature header of each event. Signatures enable you to confirm that the events were sent by Tilled and not a third party. Using the information provided below, you can manually verify signatures.
Tilled generates signatures with SHA-256 hash-based message authentication codes (HMAC). All schemes that are not v1 should be ignored.
Before verifying signatures you need to recover your endpoint’s secret which is only available at the time of creation. Creating this webhook via the API will contain a response with a secret property. The secret will be visible after creation if generated via Tilled.
To verify the authenticity of incoming webhooks, Tilled signs all open webhooks to your application. Each signed event includes a timestamp (UTC) and one or more signatures in the
tilled-signature header. The timestamp is preceded by the character
t=, and each signature is preceded by a scheme. Schemes begin with
v and are followed by an integer. The only valid live signature scheme at the moment is
tilled-signature: t=1614049713663, v1=8981f5902896f479fa9079eec71fca01e9a065c5b59a96b221544023ce994b02
Step 1: Extract the timestamp and signatures
To get a list of components, split the header using the
, character as a divider. Then, using the
= character as a divider, break each component into a prefix and value pair.
The value for the prefix
t corresponds to the timestamp, and the value for the prefix
v1 corresponds to the signature (or signatures). All other components can be discarded.
Step 2: Construct the signed payload string
signed_payload string is formed by connecting:
- The timestamp (as a string)
- The character
- The actual JSON payload (i.e., the request body)
Step 3: Identify the expected signature
By using the SHA256 hash function, compute an HMAC. The key is the signing secret of the endpoint, and the message is the
Step 4: Analyze the signatures
Compare the expected signature to the signature (or signatures) in the header. Calculate the difference between the current and received timestamps for an equal match, then decide if the difference is within your tolerance.
To prevent timing attacks, compare the expected signature to each of the received signatures using a constant-time string comparison.