Fri Jan 09 2026
...
Webhook Security Update
What's New
Previously, there was more friction when setting up Webhooks compared to other platforms. We viewed this positively due to the additional security measures required; however, we have recently chosen a method that is equally secure but offers optional security.
Previous Behavior
In the past, the system would send your API key in payloads and expect you to validate it. If you didn’t return a 401 for an invalid API key, the system wouldn’t allow setup.
New Behavior
Now, the system will not send an API key for new webhook configurations. Instead, a signed HMAC signature is included for both new and existing integrations. You may choose to validate this signature based on your required level of security.
Existing configurations will continue to send the API key - you can now request to disable this feature via a support ticket.
HMAC Signature Verification
FastComments now sends the following headers with each webhook request:
| Header | Description |
|---|---|
X-FastComments-Timestamp |
Unix timestamp (seconds) when the request was signed |
X-FastComments-Signature |
HMAC-SHA256 signature in format sha256=<hex> |
token |
Your API Secret (included for backwards compatibility) |
How the Signature is Computed
- Concatenate:
timestamp + "." + JSON_payload_body - Compute HMAC-SHA256 using your API Secret as the key
- Hex-encode the result
Example Verification (Python)
import hmac
import hashlib
import time
import json
def verify_webhook_signature(headers, body, api_secret):
timestamp = headers.get('X-FastComments-Timestamp')
signature = headers.get('X-FastComments-Signature')
if not timestamp or not signature:
return False
# Verify timestamp is recent
now = int(time.time())
if abs(now - int(timestamp)) > 300:
return False
# Verify signature
payload = json.dumps(body, separators=(',', ':'))
message = f"{timestamp}.{payload}"
expected = hmac.new(
api_secret.encode(),
message.encode(),
hashlib.sha256
).hexdigest()
return signature == f"sha256={expected}"
HTTP Method Selection
Additionally, with this update, you can now configure the HTTP method for each webhook event type:
- Create Event: POST or PUT (default: PUT)
- Update Event: POST or PUT (default: PUT)
- Delete Event: DELETE, POST, or PUT (default: DELETE)
Security Benefits
The new system offers several benefits:
- Protection against man-in-the-middle attacks
- Replay attack prevention through timestamp verification
- Detection of payload tampering
Backwards Compatibility
The token header containing your API Secret is still included with every request. Existing integrations will continue to function without changes, and as mentioned earlier, you can request to turn off the old behavior via support.
Documentation
For complete documentation, see our Webhooks Guide.
In Conclusion
As with all major releases, we are pleased that we could take the time to optimize, test, and properly implement these changes. Let us know below if you encounter any issues.
Cheers!
