The scheme
The header looks like:t— Unix time (seconds) when TrailerCast signed this attempt.v1— hex HMAC-SHA256 of the string${t}.${rawBody}using your endpoint’s secret.
The algorithm
1
Capture the raw body
Compute the HMAC over the exact bytes received. Do not re-serialise the parsed JSON — key order and whitespace would differ and every signature would fail in a way that looks like a wrong secret.
2
Parse the header
Split on commas, then on
=. Reject the request if t is not a number or v1 is missing.3
Check the timestamp
Reject if
t is more than 5 minutes from now, in either direction. A future timestamp is as suspicious as an old one.4
Compute and compare
HMAC-SHA256(secret, t + "." + rawBody) as lowercase hex. Compare to v1 with a constant-time comparison. A plain string compare leaks, byte by byte, how much of a guess was right.Examples
Rotating the secret
Rotate secret on the endpoint issues a newwhsec_… and shows it once. Deliveries already queued are signed with the new secret from their next attempt, so update your verifier before clicking rotate, or accept a short window of 401s that will be retried.
