To ensure the authenticity of event requests, Mailgun signs them and posts the signature alongside the webhook's event-data.
A signature takes the following form:
{
"token": "e0b5477167110d68991efc6b9f89f0a11066af27834600e123",
"timestamp": "1770920772",
"signature": "12d99f5a15355c180971bed7494d578b093c958f57766f3fe750761baed12345"
}| Parameter | Type | Description |
|---|---|---|
| token | string | Randomly generated string with length of 50. |
| timestamp | int | Number of seconds passed since January 1, 1970. |
| signature | string | String with hexadecimal digits generated by an HMAC algorithm |
To verify the webhook originated from Mailgun, you will need to:
- Concatenate timestamp and token values together with no separator.
- Encode the resulting string with the HMAC algorithm, using your Webhook Signing Key as a key and SHA256 digest mode.
- Compare the resulting hexdigest to the signature. If they do not match then the webhook is not from Mailgun!
- Optionally, you can cache the token value locally and not honor any subsequent request with the same token. This will prevent replay attacks.
- Optionally, you can check if the timestamp is not too far from the current time.
- There can be delays in webhook processing that are outside of Mailgun's control so you don't want to be too aggressive with this check.
To visualize, here's a sample NodeJS snippet that checks the Webhook signature:
const crypto = require('crypto')
const verify = ({ signingKey, timestamp, token, signature }) => {
const encodedToken = crypto
.createHmac('sha256', signingKey)
.update(timestamp.concat(token))
.digest('hex')
return (encodedToken === signature)
}If your receiving server uses valid TLS configuration - Mailgun includes a TLS client certificate with our Webhook requests. This allows customers to use transport-level validation by inspecting the TLS certificate provided in the request to perform additional validation for whether the request originated from Mailgun.
How it works:
- Mailgun includes our TLS client certificate in webhook requests, which is owned and managed by Mailgun and is issued by DigiCert
- Your server should be configured to only accept requests from clients with valid TLS certificates issued by a trusted CA (e.g., DigiCert)
- Once you've confirmed the certificate is valid: then verify that the certificate's Common Name (CN) is
webhooks.mgsend.net
We do not support validation of server certificates issued by custom CA’s on Mailgun's side before sending, i.e mutual TLS (mTLS)
You can download the current certificate for inspection from our US or EU API.