Getting Started with the Event Webhook Security Features
Twilio SendGrid's Event Webhook will notify a URL via HTTP POST with information about events that occur as your mail is processed. This article covers all you need to know to secure the Event Webhook, allowing you to verify that incoming requests originate from Twilio SendGrid.
For more information about working with the Event Webhook and the data it provides, please see Getting Started with the Event Webhook.
Make sure your API Key Permissions on SendGrid is set to Full Access.
Twilio SendGrid provides two methods for securing the Event Webhook: cryptographic signing and OAuth 2.0. These two security methods are independent of one another and can be used simultaneously.
The Signed Event Webhook
When using the Signed Event Webhook, Twilio SendGrid will generate a private and public key pair. The private key will be used to generate a signature that is posted to your HTTP webhook in the "X-Twilio-Email-Event-Webhook-Signature"
header.
You can verify the signature with the public key provided. More information is provided in the Verification section of this page.
Manage the Signed Event Webhook using the app
Enable the Signed Event Webhook
To enable the Signed Event Webhook and generate a key pair using the SendGrid App:
- Navigate to Settings > Mail Settings in the sidebar navigation.
- Under "Event Settings," you should see “Signed Event Webhook Requests.” Click on the edit icon to load a sidebar modal.
- In the sidebar modal, click "Generate Verification Key." This will generate a private and public key. The public key will then be displayed to you.
- Copy this key and use it for verification.
- To confirm that the Signed Event Webhook is enabled, navigate back to Settings > Mail Settings to verify that the setting is listed as "Enabled."
Disable the Signed Event Webhook using the app
To disable the Signed Event Webhook, which will delete any existing keys:
- Navigate to Settings > Mail Settings in the sidebar navigation.
- Under "Event Settings," you should see "Signed Event Webhook Requests." Click the edit icon to load a sidebar modal.
- When a signature exists, the side modal will show a toggle set to "Enabled" under the "Signed Event Webhook Request Status" label. Click the toggle to disable the feature and delete your existing keys.
- Another modal will load asking you to confirm your decision. Click "Delete and Disable Signing" to confirm.
Manage the Signed Event Webhook using the API
Twilio SendGrid provides two Event Webhook API endpoints that allow you to manage signatures. A brief overview of both endpoints is provided below. You can find more at our Event Webhook API Reference.
Enable/Disable the Signed Webhook
To enable or disable the Signed Event Webhook, you can pass a PATCH
request to https://api.sendgrid.com/v3/user/webhooks/event/settings/signed
. This endpoint expects a JSON request body with the single required boolean field enabled
.
{
"enabled": true
}
Initiate the PATCH request by including the parameters listed (Authentication, Headers, Request Body, and Responses) on the "Enable/Disable Signed Webhook" documentation.
Retrieve the Signed Webhook public key
You can also retrieve your public key by passing a GET
request to https://api.sendgrid.com/v3/user/webhooks/event/settings/signed
. This endpoint accepts no query parameters and will return the string field public_key
containing your current public key.
Verify the signature
Twilio SendGrid generates the private and public key pair using the Elliptic Curve Digital Signature Algorithm (ECDSA).
We recommend using a package or library suitable for your language to verify the signature. Libraries are listed below in Sample verification libraries. The general steps required to verify a signature are outlined below with Golang code samples.
Initiate the GET request by including the parameters listed (Headers and Responses) on the "Retrieve Event Webhook Settings" documentation.
When verifying the signature, be aware that we deliver a payload that must be used in its raw bytes form. Transformations from raw bytes to a JSON string may remove characters that were used as part of the generated signature.
- Get the signature from the
"X-Twilio-Email-Event-Webhook-Signature"
HTTP header.
// Golang Example
s := http.Request.Header.Get("X-Twilio-Email-Event-Webhook-Signature")
- Get the timestamp from the
"X-Twilio-Email-Event-Webhook-Timestamp"
HTTP header.
// Golang Example
ts := http.Request.Header.Get("X-Twilio-Email-Event-Webhook-Timestamp")
- Base64 decode the signature. Then perform an ASN.1 unmarshal of the decoded signature into a string. This string will be in the form of
{r value},{s value}
.
// Golang Example
signatureBytes, _ := base64.StdEncoding.DecodeString(s)
ecdsaSig := struct {
R *big.Int
S *big.Int
}
asn1.Unmarshal(signatureBytes, &ecdsaSig)
- Generate a sha256 hash of the timestamp + payload (use raw bytes).
// Golang Example
tsBytes := []byte(ts)
payload, _ := ioutil.ReadAll(http.Request.Body)
h := sha256.New()
h.Write(tsBytes)
h.Write(payload)
hashedPayload := h.Sum(nil)
- Verify the signature.
// Golang Example
// uses https://golang.org/pkg/crypto/ecdsa/ to perform the verification
ecdsa.Verify(publicKey, hashedPayload, ecdsaSig.R, ecdsaSig.S)
- Again, the simplest way to verify the signature is to use a package or library that will abstract away this process into a helper method or function.
Sample verification libraries
The Twilio SendGrid API libraries contain helpers to assist you when verifying the ECDSA signature. The links below will take you to the Event Webhook helper in each library.
- C# Event Webhook Helper
- Go Event Webhook Helper
- Java Event Webhook Helper
- Node.js Event Webhook Helper
- PHP Event Webhook Helper
- Python Event Webhook Helper
- Ruby Event Webhook Helper
OAuth 2.0
OAuth offers an additional and separate way of providing security controls for the Event Webhook. OAuth is an open authorization protocol used to share resources with applications. Rather than sharing your username and password with an application, granting total access to your account, OAuth enables scoped access to your resources. For more on OAuth and how it works, see the OAuth community site.
The Twilio SendGrid Event Webhook uses the Client Credentials OAuth grant type, which is an authorization workflow meant for machine-to-machine communication. This authorization method creates a token that Twilio SendGrid can pass to your app in an Authorization header, allowing you to verify that the request originated from Twilio SendGrid.
OAuth Client Credentials flow
OAuth can be confusing. To help illuminate the process, we have provided a description of the setup flow here.
- You, the customer, have an app that provides an HTTP webhook. You want the Twilio SendGrid Event Webhook to make POST requests to this URL. To ensure that the requests you receive are actually from Twilio SendGrid, you implement OAuth.
- This means you are responsible for generating a Client ID and Client Secret. You must also provide two URLs, the HTTP POST URL for your app and a URL to an authorization server or OAuth service.
- When you give Twilio SendGrid all of this information, it will pass the Client ID and Client Secret to the Token URL (your authorization server/OAuth service). The authorization server will then use the Client ID and Client Secret to generate an access token. This token is sent back to Twilio SendGrid.
- The access token is meaningless to Twilio SendGrid. It acts only as a key to pass back to your app at the HTTP POST URL. This will be done in an Authorization header.
- Because this access token is shared among only your app, the authorization server, and Twilio SendGrid, you can trust requests delivered with the token are from a trusted source.
- You can verify the access token is legitimate by checking with the authorization server that created it.
Manage OAuth 2.0 using the app
Enable OAuth
To enable OAuth using the SendGrid App:
-
Navigate to Settings > Mail Settings in the sidebar navigation.
-
Under "Event Settings," you should see "Event Webhook." Click the edit icon to load a sidebar modal.
- In the sidebar modal, you should see an "Authorization Method" drop-down menu. Select "OAuth 2.0" to load the OAuth configuration fields.
-
Fill the OAuth configuration fields:
-
Client ID: Required to generate an authorization token.
- Client Secret: Required to generate an authorization token. This secret is needed only once to create an access token. SendGrid will store this secret, allowing you to update your Client ID and Token URL without passing the secret to SendGrid again.
-
Token URL: The URL where Twilio SendGrid should deliver the Client ID and Client Secret in order to create an access token. This URL should route to your own authorization server or an OAuth service such as Auth0 or Okta.
-
With the above steps completed, requests to your HTTP POST URL by Twilio SendGrid will contain the access token in an Authorization header. You can now use this token to verify the requests using your OAuth service or authorization server.
Please note, it is your responsibility to verify the access token used in requests to your HTTP POST URL.
Disable OAuth
To disable OAuth using the SendGrid App:
- Navigate to Settings > Mail Settings in the sidebar navigation.
- Under "Event Settings," you should see "Event Webhook." Click the edit icon to load a sidebar modal.
- In the sidebar modal, you should see an "Authorization Method" drop-down menu. Select "None" to disable authorization on the Event Webhook.
- By selecting "None," requests to your HTTP POST URL by Twilio SendGrid will no longer contain an access token.
Manage OAuth 2.0 using the API
Twilio SendGrid allows you to manage OAuth setup using the API. A brief overview of enabling, disabling, and testing OAuth; and retrieving your OAuth credentials is provided below. You can find more at our Event Webhook API Reference.
Enable/Disable OAuth
To enable or disable OAuth, you can pass a PATCH
request to https://api.sendgrid.com/v3/user/webhooks/event/settings
.
This endpoint expects a JSON request body. The three optional string fields used to manage OAuth are oauth_client_id
, oauth_client_secret
, and oauth_token_url
.
- Client ID: Required to generate an authorization token.
- Client Secret: Required to generate an authorization token. This secret is needed only once to create an access token. SendGrid will store this secret, allowing you to update your Client ID and Token URL without passing the secret to SendGrid again.
- Token URL: The URL where Twilio SendGrid should deliver the Client ID and Client Secret in order to create an access token. This URL should route to your own authorization server or an OAuth service such as Auth0 or Okta.
Passing a request with valid values assigned to these fields will enable OAuth. Passing a request with empty values in these fields will disable OAuth.
{
“oauth_client_id”: “yourclientidstringvalue”,
“oauth_client_secret”: “yourclientsecretstringvalue”,
“oauth_token_url”: “https://your-authorization-service.com”
}
Please note, there are other required fields when making requests to this API endpoint. Please see the API reference for details.
Using the v2 Web API's eventnotify
API call will overwrite any previously configured Event Webhook notification settings, including OAuth 2.0. If your OAuth 2.0 settings are overwitten, please configure them again using either the Mail Settings page or the SendGrid v3 API
Testing the Event Webhook
You can test your Webhook by passing a POST
request to https://api.sendgrid.com/v3/user/webhooks/event/test
. This request will send a fake event to your HTTP POST URL, which you can use to verify proper functionality. This endpoint expects a JSON request body with a required URL field. To test the OAuth setup, you must include the three optional OAuth fields.
{
“url”: “https://your-http-post-url.com”,
“oauth_client_id”: “yourclientidstringvalue”,
“oauth_client_secret”: “yourclientsecretstringvalue”,
“oauth_token_url”: “https://your-authorization-service.com”
}
Retrieve your OAuth credentials.
To retrieve your OAuth credentials, pass a GET
request to https://api.sendgrid.com/v3/user/webhooks/event/settings
. You do not need to pass any query parameters to this endpoint. Note that only the oauth_client_id
and oauth_token_url
will be returned. The oauth_client_secret
will not be provided for security reasons.
Next steps
Now that you know how to secure the Event Webhook, you can begin using your event data to better understand your email. To finish setting up the Webhook, see Getting Started with the Event Webhook or jump right into the Event Webhook Reference.
Additional Resources
- "Simple Webhook Testing Using Sinatra and ngrok" blog post by SendGrid Team
- "Test SendGrid Webhooks with ngrok" blog post by SendGrid Team
Need some help?
We all do sometimes. Get help now from the Twilio SendGrid Support Team.
Running into a coding hurdle? Lean on the wisdom of the crowd by browsing the SendGrid tag on Stack Overflow or visiting Twilio's Stack Overflow Collective.