The way that a notification presents itself depends on the platform in question. For example, notifications sent to Slack will appear as formatted messages sent by the Nightfall Alerts Bot. Other platforms, like email and webhooks, will present the information with raw JSON objects.

Supported Alert Platforms

Slack

Installation

In order to use asynchronous notifications with Slack, you must install the Nightfall Alerts plugin from the Slack Marketplace. To install, navigate to the Nightfall Dashboard, click Settings, then click the Alert Platforms tab. You should see a page like the following:

Click the "Install" button on the Slack tile to initiate the install flow. You should see a page like the following:

If you are logged in to multiple Slack workspaces in your browser, you can choose which Slack workspace you would like to install into by clicking the dropdown in the upper right corner of the screen.

Once you have chosen a workspace, click "Allow", and then Nightfall Alerts should be installed to your workspace. You will be redirected back to the Nightfall Dashboard when the installation is complete.

Use

Once you have authenticated Nightfall to your Slack workspace, you can provide any public channel name (e.g. #general) as part of a request to the Nightfall API. If any findings are detected as part of that request, then the Nightfall Alerts bot will send a message to the channel you configured. Conversely, if there are no findings in the request payload, then Nightfall will not send an alert message.

Email

Email is unauthenticated, so you can get started using Nightfall to send email alerts without any initial setup work. Nightfall will send an email to the provided address only if findings were detected as part of the request. The findings themselves will be attached in a JSON file.

Webhook

Challenge Requests

Before Nightfall will send alerts to a user-provided webhook address, we ensure that the caller owns the server by using challenge requests. Nightfall will issue an HTTP POST request to the provided URL with a JSON body containing a single key, challenge.

{"challenge": "z78woE1uDFu7tPrPvEBV"}

In order to authenticate your webhook server to Nightfall, you must reply with (1) a 200 HTTP Status Code, and (2) a plaintext request body containing only the value of the challenge key. When a server responds successfully to a challenge request, the validity of that URL will be cached for up to 24 hours, after which it will need to be validated again.

Use

When a webhook server receives a request, it should validate that it was actually sent by Nightfall. All requests sent by Nightfall contain an HMAC signature in the request header, where the signing key is a secret unique to your account and is accessible via the Nightfall Dashboard. The sample code here illustrates the process that you can use to verify the authenticity of the signature.

The request body sent by Nightfall is JSON, and uses the schemas in the section documented below.

Nightfall will always send an alert to the client's webhook server if it is provided as part of an API request, even if the scan request yielded no findings.

Alert Schemas

File Scans

Since file scans can produce a large number of results, findings are not transmitted directly in the notification that Nightfall sends. The notification object looks like the following:

{
  "errors": [],
  "findingsPresent": true,
  "findingsURL": "https://files.nightfall.ai/877442c5-1573-4637-a223-595bf620e3e5.json?Expires=1645722381&Signature=C-kQbtonFAPXfooGcm0dYgbsn9jfGu~vGSv5yK5j1z2f7aAhk0WuaL4bISUwx5MZkQmPVFgeyMwemvEoI8aI11lPA-ORsX5LtRdGJBOma4sPVl~9f9qBPKE2VSrdGDmT4EpBLc8ewUtKrLm2xE-0BzW~5PdLSvZ~NQxtB7OMBaYm7h~y2NSUZfpqzdzENyKhyHx5QxH2PJvxeN5IvMXqNUrKyZsxviSYY6kDNAiGExS-u6PmKKS1GhXOaFLdJSRjgtFhUxDLyWl~xTYR-lJol5UTgtcuYU8AaJ3xVTF1-1JYRlioRlaf9shAvme4djFyg8k~zOB8bYgzBeaRqSjeWA__&Key-Pair-Id=K3RYMP51FKX5HX",
  "requestMetadata": "some data",
  "uploadID": "877442c5-1573-4637-a223-595bf620e3e5",
  "validUntil": "2022-02-24T17:06:21.412377682Z"
}

The requestMetadata field contains arbitrary contents provided by the client at request time, and can be used by the client to correlate this response to the original request.

The value of the findingsURL field is a pre-signed URL, which means anyone with the link can download the file. Therefore, this URL itself should be treated as sensitive and must not be leaked. The object stored at this URL is a JSON file containing a single key findings containing a list of all data detected from the request. The schema for the finding object inside the list is shared between the text-based and file-based API endpoints.

{
  "findings": [
    {
      "detector": {
        "id": "74d1315e-c0c3-4ef5-8b1e-6cf98664a854"
      },
      "finding": "4242-4242-4242-4242",
      "confidence": "VERY_LIKELY",
      "location": {
        "byteRange": {
          "start": 146,
          "end": 165
        },
        "codepointRange": {
          "start": 146,
          "end": 165
        },
        "lineRange": {
          "start": 3,
          "end": 3
        },
        "rowRange": null,
        "columnRange": null,
        "commitHash": ""
      },
      "beforeContext": "nd HIPAA Defined PII\nHIPAA HIPAA hooray\n",
      "afterContext": " is my credit card number\n\n",
      "matchedDetectionRuleUUIDs": ["7bd6166a-b9af-4069-847d-487a88788122"],
      "matchedDetectionRules": []
    } 
  ]    
}

Text Scans

The payload that is forwarded on behalf of text scanning requests is identical to the response body that is synchronously returned to the client. Refer to the API docs for more details on this payload.

{
  "findings": [
    [
      {
        "finding": "4242-4242-4242-4242",
        "beforeContext": "hello world cc ",
        "detector": {
          "name": "Credit card number",
          "uuid": "74c1815e-c0c3-4df5-8b1e-6cf98864a454"
        },
        "confidence": "VERY_LIKELY",
        "location": {
          "byteRange": {
            "start": 15,
            "end": 34
          },
          "codepointRange": {
            "start": 15,
            "end": 34
          },
          "rowRange": null,
          "columnRange": null,
          "commitHash": ""
        },
        "matchedDetectionRuleUUIDs": [
          "42efe36c-6479-412a-9049-fd8cdf895ced"
        ],
        "matchedDetectionRules": []
      }
    ]
  ],
  "redactedPayload": [""]
}