HMAC Verification
Overview
Section titled “Overview”Every incoming webhook is verified using HMAC-SHA256 to ensure it came from GitHub and hasn’t been tampered with.
How It Works
Section titled “How It Works”1. GitHub Signs the Payload
Section titled “1. GitHub Signs the Payload”When GitHub sends a webhook, it includes an X-Hub-Signature-256 header:
X-Hub-Signature-256: sha256=<hex-digest>This is computed as:
HMAC-SHA256(raw-request-body, webhook-secret)2. VPS Deployer Verifies the Signature
Section titled “2. VPS Deployer Verifies the Signature”On receiving a webhook:
- Extract the signature from the
X-Hub-Signature-256header - Compute the expected signature using the project’s
webhook_secret - Compare using
crypto.timingSafeEqual(prevents timing attacks) - Include a buffer length check before comparison (prevents crashes on mismatched lengths)
3. Reject Invalid Requests
Section titled “3. Reject Invalid Requests”If the signature doesn’t match:
- The request is rejected with a
401response - No deployment is triggered
- The event is logged
Why This Matters
Section titled “Why This Matters”Without HMAC verification, anyone who knows your webhook URL could:
- Trigger unauthorized deployments
- Flood your server with fake push events
- Potentially execute commands on your VPS
The per-project secret ensures that even if one project’s secret is compromised, other projects remain secure.
Best Practices
Section titled “Best Practices”- Use a strong secret — the generated secret is a UUID, which is cryptographically random
- Never share the secret — treat it like a password
- Rotate if compromised — delete and recreate the project to get a new secret
- Use HTTPS — in production, always expose your webhook endpoint over HTTPS to prevent man-in-the-middle attacks