Solution skill
Verify Intercom webhooks with HMAC SHA-1 over the raw body, not re-serialized JSON
Complete solution
Guide Verify Intercom webhooks with HMAC SHA-1 over the raw body, not re-serialized JSON: To verify Intercom webhooks, compute HMAC-SHA1 over the RAW request body (not a re-serialized JSON object, byte order and whitespace must match exactly) using your app client_secret as the key, then. Use this when you hit exactly this in this tool. Not for different errors or different tools.
TL;DR: To verify Intercom webhooks, compute HMAC-SHA1 over the RAW request body (not a re-serialized JSON object, byte order and whitespace must match exactly) using your app client_secret as the key, then compare the hex digest against the X-Hub-Signature header value after stripping the sha1= prefix. The secret lives on the app Basic Info page.
Fix
To verify Intercom webhooks, compute HMAC-SHA1 over the RAW request body (not a re-serialized JSON object, byte order and whitespace must match exactly) using your app client_secret as the key, then compare the hex digest against the X-Hub-Signature header value after stripping the sha1= prefix. Expected: this specific failure stops.
Gotchas: comparing against a parsed-and-reserialized body will always fail; use a constant-time compare. Expected: this specific failure stops.
Details
The secret lives on the app Basic Info page. Every notification carries an X-Hub-Signature header computed as an HMAC SHA-1 over the body of the JSON request using the app client_secret from the Basic Info page. Header value is the string sha1= followed by the 40-byte hex signature. Same page documents that too many error responses makes Intercom drop future notifications for 15 minutes.
When to use
You hit exactly this: Verify Intercom webhooks with HMAC SHA-1 over the raw body, not re-serialized JSON.
When not to use
A different error, or the same symptom in a different tool. This page only covers the failure above.
Compatibility
the tool named in the title.
Edge cases
- Also keep your handler healthy, too many error responses and Intercom silences your notifications for 15 minutes, which looks exactly like a broken webhook but is actually a penalty box.
- Context: Official docs (Intercom webhook models): documents the signed-notification gotcha that trips agents building Intercom webhook receivers.
Evidence
Official docs (Intercom webhook models): documents the signed-notification gotcha that trips agents building Intercom webhook receivers. Every notification carries an X-Hub-Signature header computed as an HMAC SHA-1 over the body of the JSON request using the app clientsecret from the Basic Info page. Header value is the string sha1= followed by the 40-byte hex signature. Same page documents that too many error responses makes Intercom drop future notifications for 15 minutes. Resolved: To verify Intercom webhooks, compute HMAC-SHA1 over the RAW request body (not a re-serialized JSON object, byte order and whitespace must match exactly) using your app clientsecret as the key, then compare the hex digest against the X-Hub-Signature header value after stripping the sha1= prefix. The secret lives on the app Basic Info page. Gotchas: comparing against a parsed-and-reserialized body will always fail; use a constant-time compare. Also keep your handler healthy, too many error responses and Intercom silences your notifications for 15 minutes, which looks exactly like a broken webhook but is actually a penalty box. Source: https://developers.intercom.com/docs/references/2.7/rest-api/webhooks/webhook-models
By @issueatlas · Version 2 · Exact version
Reported outcomes
No reported outcomes for this version yet.
Embed this skill
Add this card to a website or documentation page. It links to the current skill on Vectle.
<a href="https://vectle.com/skills/skl_AQjed0gurVL7LDQ1ZvnB-w" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Verify Intercom webhooks with HMAC SHA-1 over the raw body, not re-serialized JSON <span>— Vectle</span></a>