# Webhooks

To use the Breach Monitoring Service, it is necessary to setup a Webhook with Enzoic. You will need to specify a URL on your end that will be called with a POST whenever a notification is made. This can be done via API using the [Webhooks API](https://docs.enzoic.com/enzoic-api-developer-documentation/api-reference/breach-monitoring-api/webhooks/managing-webhooks) or by [contacting Enzoic Support](https://support.enzoic.com).  You will also receive a *Webhook Key* and *Webhook Secret* which will be passed to your endpoint via basic HTTP authentication. &#x20;

{% hint style="info" %}
NOTE: Webhook notifications will be sent from IP address: 52.42.159.171. You may need to update your firewall rules accordingly.
{% endhint %}

## **Webhook POST Body**

The content of the POST body that will be sent to your webhook for new Breach Monitoring notifications will be a JSON object with the members specified in the table below. &#x20;

{% hint style="warning" %}
Additional JSON keys may be added to this payload as we make enhancements to the service, so you must implement JSON parsing for the webhook in a way that will not fail if additional data members are present.
{% endhint %}

<table data-full-width="false"><thead><tr><th width="310.3333333333333">Member</th><th width="91">Type</th><th>Description</th></tr></thead><tbody><tr><td>date</td><td>date</td><td>The date/time (in GMT) that the Exposure was found</td></tr><tr><td>exposureID</td><td>string</td><td>The ID of the Exposure. This can subsequently be used with the <a href="../exposures-api/retrieve-details-for-an-exposure">GET Exposure Details API</a> to retrieve additional information about the Exposure.</td></tr><tr><td>username</td><td>string</td><td>The email address which was exposed.</td></tr><tr><td>usernameHash</td><td>string</td><td>The SHA-256 hash of the email address exposed.</td></tr><tr><td>plaintextPassword</td><td>string</td><td>The cleartext version of the password which was found.  If the cleartext password was not recoverable, the passwordHash will contain the hashed version of the password, in which case you can hash a password on your end using the algorithm in <code>passwordType</code> and compare it to the <code>passwordHash</code> value to determine if there is a match.  <br><em>This field will only be present when cleartext credentials API access is enabled.</em></td></tr><tr><td>passwordHash</td><td>string</td><td>The hashed value of the password which was found, if the source data contained a password hash rather than the cleartext password.  <br><em>This field will only be present when cleartext credentials API access is enabled.</em></td></tr><tr><td>passwordSalt</td><td>string</td><td>If the password was hashed and a separate salt value is required for this hash type, this is the salt value which was found.  <br><em>This field will only be present when cleartext credentials API access is enabled.</em></td></tr><tr><td>passwordType</td><td>int</td><td>The hash algorithm for the value in the <code>passwordHash</code> field. See the <a href="https://docs.enzoic.com/enzoic-api-developer-documentation/api-reference/password-hash-algorithms">Password Hash Algorithms</a> page for more details.  <br><em>This field will only be present when cleartext credentials API access is enabled.</em></td></tr><tr><td>customData</td><td>string</td><td>This will contain the <code>customData</code> value you provided along with this username when you subscribed it for monitoring, see <a data-mention href="breach-monitoring-by-user">breach-monitoring-by-user</a>.  Will not be present if the notification is for a monitored domain.</td></tr><tr><td>exposureDetails</td><td>object</td><td>The exposure details object contains detailed information about how and where these credentials were exposed.  See <a data-mention href="../exposures-api/retrieve-details-for-an-exposure">retrieve-details-for-an-exposure</a> for documentation on the contents.</td></tr></tbody></table>

An example POST body:

{% code fullWidth="false" %}

```json
{ 
  "username": "sample@email.tst",
  "usernameHash": "de34a09f96a6677f8a4e0a17545a20e0b60a2f093879c82ed36cff75930d5814",
  "date": "2017-01-17T04:51:05.1915231Z",
  "exposureID": "583d32144d6db21a908faa11",
  "plaintextPassword": "password123!", // only present if cleartext credentials are enabled
  "passwordHash": "b7e283a09511d95d6eac86e39e7942c0", // only present if cleartext credentials are enabled
  "passwordSalt": "", // only present if cleartext credentials are enabled
  "passwordType": 1,
  "customData": "corporate_users",
  "exposureDetails": {
    "title": "test exposure",
    "date": "2015-05-01T00:00:00.000Z",
    "entries": 5123,
    "domainsAffected": 683,
    "category": "Manufacturing",
    "sourceURLs": [
      "https://somecybercriminalforum.com/post123"
    ],
    "source": "Cybercrime Forums",
    "passwordTypes": [
      1
    ],
    "exposedData": [
      "Emails",​
      "Passwords"​
    ],
    "dateAdded": "2016-09-16T15:36:54.000Z"
  }
}
```

{% endcode %}

## **Webhook Authentication**

For security reasons, you should authenticate calls to your Webhook endpoint. To facilitate this, you will be provided with a Webhook Key and a Webhook Secret when you setup your Webhook with Enzoic. These will be passed as a standard basic authentication HTTP with the Webhook Key as the username and the Webhook Secret as the password. As per the standard, the authentication header passed to your endpoint is constructed as follows:

```javascript
authorization: basic Base64({Webhook Key}:{Webhook Secret})
```

## Mutual TLS (mTLS) Authentication (Optional)

If you use an HTTPS endpoint for your webhook's URL, Enzoic will by default confirm that your server certificate is valid prior to posting data by ensuring it is issued by a trusted Certificate Authority and the subject of the certificate matches the webhook domain.  This is to help ensure we are communicating with your server and not an unauthorized 3rd party.

Mutual TLS (mTLS) is an optional authentication you may leverage in your webhook to verify that the call actually originated with Enzoic.  To take advantage of mTLS, you configure your server to verify Enzoic's client certificate.  Enzoic always attempts to send this certificate, so there is no need for any additional configuration on the Enzoic side to enable this functionality. &#x20;

You can read  more about mTLS for webhook security at <https://webhooks.fyi/security/end-to-end-encryption>. &#x20;

### Setting Up mTLS

To setup mTLS, you will need to do the following:

1. Download the Enzoic root certificate from [https://cdn.enzoic.com/certs/Enzoic-RootCA-2025.crt](https://cdn.enzoic.com/certs/Enzoic/Enzoic-RootCA-2025.crt)
2. Configure your web server to require client certificate verification using the certificate from step 1 as the trusted root CA and setting the verification depth to 1.
3. Verify the client certificate is actually from Enzoic by verifying the subject domain name is `webhooks.enzoic.com`

Although the client certificate configuration will be specific to your web server, example configurations for NGINX and Apache are below.

#### NGINX Example Configuration

```nginx
    server {
        listen       443 ssl;
        
        # ... existing server configuration ...

        # mTLS client certificate configuration 
        ssl_verify_client on;
        ssl_client_certificate /path/to/Enzoic-RootCA-2025.crt;
        ssl_verify_depth 1;

        location / {           
            # check that the client cert's distinguished name matches
            # the expected value, otherwise reject with 403
            if ($ssl_client_s_dn !~ "CN=webhooks.enzoic.com") {
                return 403;
            }
            
            # ... existing location configuration ... #
        }
    }
```

#### Apache Example Configuration

```apacheconf
Listen 443
<VirtualHost *:443>
    # ... existing SSL configuration for server authentication ...
    SSLVerifyClient require
    SSLCACertificateFile "/path/to/Enzoic-RootCA-2025.crt"
    SSLVerifyDepth 1
</VirtualHost>
<Directory /var/www/>
    Require expr "%{SSL_CLIENT_S_DN_CN} == 'webhooks.enzoic.com'"
    # ... existing directory configuration ...
</Directory>
```

## Payload Encryption (Optional)

Enzoic can optionally encrypt the webhook body with a pre-shared key, using AES encryption.  In this case the body of the call will contain a Base64 encoded encrypted version of the JSON payload.  It will be necessary to decrypt the received Base64 payload using the pre-shared key.  This provides another safeguard to protect the sensitive data contained in the webhook call against unauthorized interception.

[Contact Enzoic support](https://support.enzoic.com) to discuss enabling this feature for your webhooks.

## **Testing Your Implementation**

Once you have your webhook up and publicly accessible, you can verify all is working using the Webhook Test REST Call using the *type=breachAlert* query string parameter. This will cause a Breach Monitoring Notification POST to be made to your URL containing test data.
