Search
ctrl+/
Ask AI
ctrl+.
Light
Dark
System
Sign in

Webhooks​

The auth extension supports sending webhooks for a variety of auth events. You can use these webhooks to, for instance, send a fully customized email for email verification, or password reset instead of our built-in email verification and password reset emails. You could also use them to trigger analytics events, start an email drip campaign, create an audit log, or trigger other side effects in your application.

If you are using Webhooks to send emails, be sure to not also configure an SMTP provider otherwise we will send the email via SMTP and also send the webhook which will trigger your custom email sending behavior.

We send webhooks with no durability or reliability guarantees, so you should always provide a mechanism for retrying delivery of any critical events, such as email verification and password reset. We detail how to resend these events in the relevant sections on the various authentication flows.

You can configure webhooks with the UI or via query. The URLs you register as webhooks must be unique across all webhooks configured for each branch. If you want to send multiple events to the same URL, you can do so by adding multiple ext::auth::WebhookEvent values to the events set, like in this example.

Copy
configure current branch insert
  ext::auth::WebhookConfig {
    url := 'https://example.com/auth/webhook',
    events := {
      ext::auth::WebhookEvent.EmailVerificationRequested,
      ext::auth::WebhookEvent.PasswordResetRequested,
    },
    # Optional, only needed if you want to verify the webhook request
    signing_secret_key := '1234567890',
  };

When you receive a webhook, you'll look at the event_type field to determine which event corresponds to this webhook request and handle it accordingly.

You can provide a signing key, which you will need to generate and save in a place that your application will have access to. The extension will then add a x-ext-auth-signature-sha256 header to the request, which you can use to verify the request by comparing the signature to the SHA256 hash of the request body.

Here is an example of how you might verify the signature in a Node.js application:

Copy
/**
 * Assert that if the request contains a signature header, that the signature
 * is valid for the request body. Will return false if there is no signature
 * header.
 *
 * @param {Request} request - The request to verify.
 * @param {string} signingKey - The key to use to verify the signature.
 * @returns {boolean} - True if the signature is present and valid, false if
 *                    the signature is not present at all.
 * @throws {AssertionError} - If the signature is present but invalid.
 */
async function assertSignature(
  request: Request,
  signingKey: string,
): Promise<boolean> {
    const signatureHeader = request.headers.get('x-ext-auth-signature-sha256');
    if (!signatureHeader) {
      return false;
    }

    const requestBody = await request.text();
    const encoder = new TextEncoder();
    const data = encoder.encode(requestBody);
    const key = await crypto.subtle.importKey(
      'raw',
      encoder.encode(signingKey),
      { name: 'HMAC', hash: 'SHA-256' },
      false,
      ['sign']
    );
    const signature = await crypto.subtle.sign('HMAC', key, data);
    const signatureHex = Buffer.from(signature).toString('hex');

    assert.strictEqual(
      signatureHeader,
      signatureHex,
      "Signature header is set, but the signature is invalid"
    );

    return true;
};

If you are having trouble receiving webhooks, you might need to look for any responses from the requests that are being scheduled by the std::net::http (added in 6.0) module. You can list all of the net::http::ScheduledRequest (added in 6.0) objects, and any returned responses with the following query:

Copy
select net::http::ScheduledRequest {
    **,
    response: { ** }
}

Common fields for all events:

  • event_type: (string) This will be a literal string containing the name of the event. You can use this to determine which event occurred.

  • event_id: (string) A unique identifier to help disambiguate events of the same type.

  • timestamp: (string) The ISO 8601 timestamp of when the event was triggered.

When a new ext::auth::Identity object is created, like when a new user signs up, or an existing user adds a new factor, this event is triggered.

Example payload:

Copy
POST http://localhost:8000/auth/webhook
Content-type: application/json
x-ext-auth-signature-sha256: 1234567890

{
  "event_type": "IdentityCreated",
  "event_id": "1234567890",
  "timestamp": "2021-01-01T00:00:00Z",
  "identity_id": "identity123"
}

When an ext::auth::Identity object is authenticated, like when a user logs in, this event is triggered.

Example payload:

Copy
POST http://localhost:8000/auth/webhook
Content-type: application/json
x-ext-auth-signature-sha256: 1234567890

{
  "event_type": "IdentityAuthenticated",
  "event_id": "1234567890",
  "timestamp": "2021-01-01T00:00:00Z",
  "identity_id": "identity123"
}

When a new ext::auth::EmailFactor object is created, like when a user adds a new email factor, this event is triggered.

Example payload:

Copy
POST http://localhost:8000/auth/webhook
Content-type: application/json
x-ext-auth-signature-sha256: 1234567890

{
  "event_type": "EmailFactorCreated",
  "event_id": "1234567890",
  "timestamp": "2021-01-01T00:00:00Z",
  "identity_id": "identity123",
  "email_factor_id": "emailfactor123"
}

When a user verifies their email address, this event is triggered.

Example payload:

Copy
POST http://localhost:8000/auth/webhook
Content-type: application/json
x-ext-auth-signature-sha256: 1234567890

{
  "event_type": "EmailVerified",
  "event_id": "1234567890",
  "timestamp": "2021-01-01T00:00:00Z",
  "identity_id": "identity123",
  "email_factor_id": "emailfactor123"
}

When a user requests to verify their email address, like when they first sign up, or requests to resend the verification email, this event is triggered.

Example payload:

Copy
POST http://localhost:8000/auth/webhook
Content-type: application/json
x-ext-auth-signature-sha256: 1234567890

{
  "event_type": "EmailVerificationRequested",
  "event_id": "1234567890",
  "timestamp": "2021-01-01T00:00:00Z",
  "identity_id": "identity123",
  "verification_token": "verificationtoken123"
}

When a user requests to reset their password, this event is triggered.

Example payload:

Copy
POST http://localhost:8000/auth/webhook
Content-type: application/json
x-ext-auth-signature-sha256: 1234567890

{
  "event_type": "PasswordResetRequested",
  "event_id": "1234567890",
  "timestamp": "2021-01-01T00:00:00Z",
  "identity_id": "identity123",
  "reset_token": "resettoken123"
}