hooksig / GitHub
HMAC-SHA256 · hex · no timestamp
GitHub
Simplest of the three, and the template most other older webhooks copied.
Try it — live, in your browser
Request — edit anything
Verify this in code
import { verify } from "hooksig";
const result = await verify("github", {
payload: rawBody, // the RAW body, not parsed JSON
headers: request.headers,
secret: env.WEBHOOK_SECRET,
});
if (!result.verified) {
return new Response(result.reason, { status: 400 });
}no match — signature invalid
Signed string
HMAC-SHA256( secret, signed string ) = expected
Expected vs provided
expected
provided
How it's built
The scheme
- Header
X-Hub-Signature-256 - AlgorithmHMAC-SHA256
- Encodinghex
- Timestampnone — add your own if you need it
- SignsHMAC-SHA256 over the raw body, hex-encoded, prefixed `sha256=`. No timestamp.
Gotchas
- The header value is `sha256=` followed by the digest. Do not forget the prefix.
- There is no timestamp, so there is no built-in replay protection. Add your own if you need it.
- GitHub also sends the older `X-Hub-Signature` (SHA-1). Ignore it, verify the 256 one.