Check the X-Twilio-Signature header against the exact webhook URL you configured plus every parameter in the request, using your account auth token and the vendor's validation library. Serve the endpoint over HTTPS with a certificate from a trusted authority. Do not validate against a fixed list of parameters.
What the vendor signs
Twilio's security documentation says it signs all HTTP requests to your app with an X-Twilio-Signature header. To build the signature it combines and hashes the account auth token, the webhook URL configured in Twilio, and all request parameters, using HMAC-SHA1 with the auth token as the secret key. Your web app should check the header before responding to the request.
That description already points to two common failure causes: the URL and the parameters.
Three details that trip people up
- The URL must match what Twilio used. If a proxy or load balancer rewrites the scheme, host or path, your computed signature will differ. Validate against the public URL as configured, not the internal one your framework sees.
- Parameters change. The documentation warns that webhook parameters vary by channel and event type and that Twilio occasionally adds parameters without notice. Its sample code comment says the check must include all received parameters, not a hardcoded list of the parameters you receive today. A strict list works on Monday and breaks on Tuesday.
- HTTPS with a real certificate. The documentation states that Twilio will not connect to an HTTPS URL with a self-signed certificate, and that the console always validates certificates. Use a certificate from a recognised provider.
Steps
- Store the auth token in a secrets store, not code.
- Configure the webhook with the full public HTTPS URL.
- In the handler, read the header and the complete set of request parameters.
- Call the official validation helper from the vendor's library with the token, the signature, the public URL and the parameters.
- If validation fails, return an error and do no further work.
- Log the failure with a request ID, never the token.
Use the library the vendor provides. The documentation recommends it, and it handles encoding details that are easy to get subtly wrong.
Troubleshooting a mismatch
| Symptom | Likely cause |
|---|---|
| Always fails behind a proxy | Handler sees internal URL, not the public one |
| Fails only for some event types | Parameter list is hardcoded |
| Fails after a redirect | URL with or without trailing slash differs |
| Fails in staging only | Staging uses a different token or URL than the one configured |
Keep the token narrow in other places
The auth token is also the credential for the account. For outbound API calls, use API keys rather than the main token where you can, so one leaked integration key can be revoked alone. The vendor's key documentation describes three types, Main, Standard and Restricted, and says Restricted keys give minimum, fine grained access. More in which messaging API key to use.
Where Safeguard fits
Validation code depends on libraries that need to stay patched. Safeguard's dependency scanning and policy gates can flag a vulnerable version before it merges.
Try it yourself
Click through it at your own pace, or open it full screen. Watch how a failing check blocks the merge until the issue is fixed.
Quick check
Why does validation fail only behind my load balancer?
Because the URL used in the signature is the public one configured in the vendor console. If your handler computes it from an internal address, the values will not match.
Can I pass only the parameters I use?
No. The vendor says the check must include all received parameters, since new ones can be added without notice.
Sources
- Secure webhooks, Twilio documentation
- API keys, Twilio documentation
Last reviewed: 19 October 2026.