Skip to main content
Grain signs all webhook payloads with an HMAC signature so you can verify they originated from Grain and haven’t been tampered with.

Headers

Each webhook request includes two security headers:

Verification Steps

  1. Extract the timestamp and signature from the request headers.
  2. Check the timestamp is within an acceptable window (recommended: 5 minutes). This protects against replay attacks.
  3. Compute the expected signature using your webhook secret.
  4. Compare signatures using a timing-safe comparison function.

Computing the Signature

The signature is computed over the string {timestamp}.{raw_request_body}:

Python Example

Important Notes

  • Always use the raw request body — do not parse and re-serialize the JSON, as this may change the payload.
  • Use timing-safe comparison — standard string comparison is vulnerable to timing attacks.
  • Validate the timestamp — this protects against replay attacks where an attacker resends a captured request.
  • Store your secret securely — treat it like a password; never commit it to source control.