Transactional Email signs webhook requests so you can (optionally) verify that requests are generated by Transactional Email and not a third-party pretending to be Transactional Email. If your application exposes sensitive data, be sure the requests are coming from Transactional Email. This is not required, but offers an additional layer of verification.
Verifying Request Signatures
Transactional Email includes an additional HTTP header with webhook POST requests, X-Mandrill-Signature
, which will contain the signature for the request. To verify a webhook request, generate a signature using the same key that Transactional Email uses and compare that to the value of the X-Mandrill-Signature
header.
Get your Webhook Authentication Key
When you create a webhook, a key is automatically generated. If you are using the webhooks/add method, the key will be returned in the response. You can also view and reset the key from the Webhooks page in your account, in the Key column. To retrieve a webhook key via the Transactional API, use webhooks/info or webhooks/list.
Generate a Signature
In your code that receives or processes webhook requests:
- Create a string with the webhook's URL, exactly as you entered it in Transactional Email (including any query strings, if applicable). Transactional Email always signs webhook requests with the exact URL you provided when you configured the webhook. A difference as small as including or removing a trailing slash will prevent the signature from validating.
- Sort the request's POST variables alphabetically by key.
- Append each POST variable's key and value to the URL string, with no delimiter.
- Hash the resulting string with HMAC-SHA1, using your webhook's authentication key to generate a binary signature.
- Base64 encode the binary signature
- Compare the binary signature that you generated to the signature provided in the
X-Mandrill-Signature
HTTP header.
Note: Some HMAC implementations can generate either a binary or hexadecimal signature. Transactional Email generates a binary signature and then Base64-encodes it; using a hexadecimal signature will not work.
Example PHP implementation
/**
* Generates a base64-encoded signature for a Mandrill webhook request.
* @param string $webhook_key the webhook's authentication key
* @param string $url the webhook url
* @param array $params the request's POST parameters
*/
function generateSignature($webhook_key, $url, $params) {
$signed_data = $url;
ksort($params);
foreach ($params as $key => $value) {
$signed_data .= $key;
$signed_data .= $value;
}
return base64_encode(hash_hmac('sha1', $signed_data, $webhook_key, true));
}
Considerations
You can reset a webhook's authentication key at any time. Transactional Email will immediately begin using the new key to sign requests. To ensure that you do not lose any webhook batches between the time you reset your key and when you update your application to start using that new key, your webhook processor should reject batches with failed signatures with a non-200 status code. Transactional Email will queue the batch and retry later, which will give you time to update your application with the new key.