Glossary · Core

HMAC

Hash-based Message Authentication Code — proves a message came from someone who knows a shared secret and was not modified.

HMAC (Hash-based Message Authentication Code) is a cryptographic primitive that combines a hash function with a shared secret to produce a signature over some data. The signature proves two things at once: the sender knew the secret, and the data wasn't modified in transit.

In webhooks, HMAC is the most common way providers sign payloads. The sender computes HMAC(secret, body) and includes it in a header. The receiver recomputes the signature on the raw body and compares constant-time with the header value.

Why webhooks use HMAC

Three properties matter:

  • Symmetric. Both sides share the same secret. No key infrastructure (PKI, certificate authorities, key servers) needed.
  • Fast. HMAC-SHA256 is microseconds per request even at high throughput.
  • Standard. Every language ships HMAC primitives in its standard library.

The trade-off is that the secret must be shared in advance and rotated periodically. For machine-to-machine webhook flows, this is usually acceptable.

Verification rules

Three things must be true for HMAC verification to be safe:

  1. Read the raw body before parsing. Parsing JSON normalizes whitespace; the signature won't match.
  2. Compare constant-time. Naive == comparison is vulnerable to timing attacks; use a constant-time comparison function.
  3. Verify a timestamp. Most providers include a timestamp in the signed string to prevent replay attacks; reject anything older than a few minutes.

Common variants in webhooks:

  • HMAC-SHA256 — Stripe, GitHub, Shopify, Slack, Standard Webhooks
  • HMAC-SHA1 — Twilio (legacy)
  • Ed25519 — Discord interactions (asymmetric, not HMAC, but same role)
  • JWT with ES256 — Plaid (asymmetric)

For the verification model in practice: Verify provider webhooks.

Related terms