Check Signatures

Security matters, which is why we include signatures on all webhook events we send to your endpoints. This allows you to confirm the events were sent by a Tilled team member, and not a third party. Continue reading to learn how you can not only check webhook signatures, but also verify them.

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.

Confirming 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 v1.

tilled-signature:
t=1614049713663,
v1=8981f5902896f479fa9079eec71fca01e9a065c5b59a96b221544023ce994b02
The newlines are there for clarity, but a real tilled-signature header is usually on a single line.

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

The 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 signed_payload string.

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.