Skip to main content

Signature verification

Tesouro can sign webhook deliveries with HMAC-SHA512 so you can verify a request came from Tesouro and wasn’t tampered with. Signing is opt-in per subscription - unsigned by default. Once enabled, every delivery to that subscription includes the three headers below. To enable signing for your subscription, contact your Tesouro implementation team.

Headers

Computing the signature

{t} is the unix-seconds value from x-tesouro-signature. {request_body} is the raw request body bytes, byte-for-byte as received - don’t re-serialize or reformat the JSON before hashing. Compare case-insensitively (the digest is uppercase on the wire).

Verification steps

  1. Extract t=<unix-seconds> and v1=<hex> from the x-tesouro-signature header.
  2. Look up the shared secret for the key id in x-tesouro-key-id.
  3. Construct signed_input = "{t}.{raw_body}".
  4. Compute HEX(HMAC-SHA512(secret, signed_input)).
  5. Reject with 401 if the computed digest doesn’t match v1.
Example using openssl:
If signing is enabled for your subscription, always verify the signature before processing the event.

Replay protection

After verifying the signature, also check that the request is fresh:
  1. Reject stale requests. Compare t=<unix-seconds> from x-tesouro-signature to the current time and reject anything older than a small window (Tesouro recommends 5 minutes).
  2. Deduplicate on deliveryId. Maintain a cache of recently-seen deliveryId values from the envelope and reject any request whose deliveryId you’ve already processed.

Secret rotation

Signing secrets can be rotated without downtime:
  • Add the new secret before removing the old one.
  • During the rotation period, accept requests signed by either key - use x-tesouro-key-id to select the matching secret per request.
  • Remove the old secret only after all in-flight webhooks finish.
Contact Tesouro support to rotate your webhook signing secret.

Endpoint validation

In addition to signature verification:
  • Register only HTTPS endpoints; plain HTTP isn’t supported.
  • Where possible, restrict your webhook handler to known Tesouro source IPs.
  • Return 401 for requests that fail validation.

Additional options

Tesouro also supports mutual TLS (mTLS) - contact the implementation team to enable it.