Authsignal has two type of webhooks:

  • Authenticator webhooks - enable you to send SMS, email and push notifications via your own provider.
  • Event webhooks - enable you to receive notifications via your POST endpoint for various events that occur near real-time.

Supported events

Authenticator webhooks

  • email.created
  • push.created
  • sms.created

Event webhooks

  • authenticator.created
  • authenticator.deleted
All webhooks use the same authentication model described below

Configuring webhook urls

To configure webhook URLs for authenticators, navigate to the authenticator’s settings in Authsignal’s admin portal and add the URL of your webhook endpoint. Webhooks are available for the authenticators SMS OTP, Email OTP, Email Magic Link and Push.

To configure a webhook URL for events, navigate to the tenant settings in Authsignal’s admin portal and add the URL of your webhook endpoint.

Verify a signed webhook

Signed webhooks ensure the data’s authenticity and integrity between systems by creating a digital signature with a secret key. The signature is sent alongside the data on the webhook, and the recipient verifies it with the same secret key to prevent malicious attacks.

Failing to verify the request leaves your app vulnerable to various security threats.

The secret key used for HMAC-SHA256 signature generation is your Authsignal secret key, which can be found in Settings -> API Keys -> Secret key in Authsignal’s admin portal.

Webhook setup

  1. Create a POST endpoint on your server that listens for incoming webhook requests.

  2. Add this endpoint’s URL to your authenticator’s webhook configuration settings in Authsignal’s admin portal.

Verification steps

  1. In your webhook function, retrieve the x-signature, content-type and x-timestamp headers from the incoming request.

  2. Construct the message to be signed by concatenating the following with a new line character as the separator (you can use the example code’s messageToSign variable as a reference):

  • HTTP method
  • Your webhook URL
  • The content-type and x-timestamp request headers. These must be converted to title case as shown.
  • The raw request body.
  1. Compute the HMAC-SHA256 signature of the message using your secret key in Authsignal’s admin portal.

  2. Compare the x-timestamp (lowercase intended) value in the header with the current time and check that it is within a reasonable range e.g. less than 10 minutes.

  3. Compare the computed signature with the incoming signature. If they match, the request is authenticated and can be processed; otherwise, the request is not authentic and should be rejected.

Node.js
const secretKey = process.env["AUTHSIGNAL_SECRET_KEY"];

// Retrieve the x-signature header from the incoming request
const signature = req.headers["x-signature"];

const requestHeaders = {
  "Content-Type": req.headers["content-type"],
  "X-Timestamp": req.headers["x-timestamp"],
};

const webhookUrl = "your webhook url"; //e.g https://webhook.site/verify

const messageToSign = `${req.method}\n${webhookUrl}\n${JSON.stringify(
  requestHeaders
)}\n${JSON.stringify(req.body)}`;

// Compute the HMAC-SHA256 signature of the message
const computedSignature = createHmac("sha256", secretKey).update(messageToSign).digest("base64");

// Compare the computed signature with the incoming signature
if (computedSignature === signature) {
  // Request is authentic, process it accordingly
} else {
  // Request is not authentic, reject it
}

Expected responses and retry behavior

Webhooks expect a 200 OK response for successful requests. The behaviour of non-200 responses differs between authenticator webhooks and event webhooks:

Authenticator webhooks

Authenticator webhooks are synchronous and the upstream request will fail for non-200 responses.

For example, if you have configured a webhook to handle the sending of email OTPs, when a challenge is triggered and the webhook returns a non-200 response, the API will return an error response. An appropriate message should be displayed to the user when using our SDKs or APIs directly so that the user may trigger a retry via the UI. This is automatically handled in the pre-built UI.

Event webhooks

Event webhooks are asynchronous. For non-200 responses, the webhook will be retried up to 3 times after at least 30 seconds.

Next steps