Skip to main content
Materi uses GitHub-style webhook signatures in several places: a request body is signed with HMAC-SHA256, and the signature is carried in the X-Hub-Signature-256 header as:
  • sha256=<hex>
This recipe is aligned with the Shield implementation in 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 from X-Hub-Signature-256
  • secret: the shared secret configured on both sides

Python

This matches the Shield implementation in domain/shield/apps/cicd/webhooks.py.
Common pitfalls:
  • Verify against the raw request body bytes (before JSON parsing).
  • Use constant-time comparison (hmac.compare_digest).

Node.js

This matches the Shield implementation in domain/shield/apps/cicd/webhooks.py.
Notes:
  • Pass the raw bytes (e.g., Buffer), not a parsed JSON object.
  • timingSafeEqual requires 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).