X-Hub-Signature-256 header as:
sha256=<hex>
domain/shield/apps/cicd/webhooks.py.
Inputs
You need three pieces of data:payload_bytes: the raw HTTP request body bytes (before JSON parsing)signature_header: the header value fromX-Hub-Signature-256secret: the shared secret configured on both sides
Python
This matches the Shield implementation indomain/shield/apps/cicd/webhooks.py.
- Verify against the raw request body bytes (before JSON parsing).
- Use constant-time comparison (
hmac.compare_digest).
Node.js
This matches the Shield implementation indomain/shield/apps/cicd/webhooks.py.
- Pass the raw bytes (e.g.,
Buffer), not a parsed JSON object. timingSafeEqualrequires buffers of equal length; using the computed/expected hex strings avoids length mismatches unless the header is malformed.
Receiver checklist
- Reject missing/invalid signatures with
401. - Verify against raw bytes.
- Use constant-time comparison.
- Log only high-level info (avoid logging secrets or full payloads in production).