Skip to content

Alert

A simple alert

A new alert requires at least these fields to be defined:

  • type: The type of the alert.
  • source: The source of the alert.
  • sourceRef: A unique reference for the alert.
  • title: A descriptive title for the alert.
  • description: Additional information describing the alert.

Here's an example that demonstrates how to create the most simplistic alert possible using the alert.create method:

from thehive4py import TheHiveApi

hive = TheHiveApi(url="http://localhost:9000", apikey="h1v3b33")

simple_alert = hive.alert.create(
    alert={
        "type": "simple",
        "source": "tutorial",
        "sourceRef": "should-be-unique",
        "title": "a simple alert",
        "description": "a bit too simple",
    }
)

An advanced alert

In the previous example we really kept things simple and only specified the required alert fields inline in the create method call. With a more advanced example this can become complicated and hard to read. Fortunately we can use thehive4py's type hints to the rescue and specify more complex input alerts outside of the method call.

Here's how:

from thehive4py import TheHiveApi
from thehive4py.types.alert import InputAlert

hive = TheHiveApi(url="http://localhost:9000", apikey="h1v3b33")

input_alert: InputAlert = {
    "type": "advanced",
    "source": "tutorial",
    "sourceRef": "should-be-unique",
    "title": "an advanced alert",
    "description": "a bit more advanced",
    "tags": ["advanced", "example"],
    "severity": 1,
    "caseTemplate": "my-template",
}

output_alert = hive.alert.create(alert=input_alert)

In the above snippet input_alert is created before the create call and later passed to the alert argument. Finally after the creation of the alert we saved the response in the output_alert to be able to use it later.

Note

While the above alert is a bit more advanced it's still far from the most complex example possible. In case you want to see the what the Alert API offers please check out the official alert docs.

Alert observables

TheHive API provides multiple ways to add observables to alerts, let them be textual or file based observables.

Add observables during alert creation

We can add observables already during alert creation. This is a great way to combine alert and observable creation in a simple and atomic way:

Let's create an alert with an ip and a domain observable:

import uuid

from thehive4py import TheHiveApi
from thehive4py.types.alert import InputAlert

hive = TheHiveApi(url="thehive.example", apikey="h1v3b33")

input_alert: InputAlert = {
    "type": "alert-with-observables",
    "source": "example",
    "sourceRef": uuid.uuid4().hex,
    "title": "alert with observables",
    "description": "alert with observables",
    "observables": [
        {"dataType": "ip", "data": "1.2.3.4"},
        {"dataType": "domain", "data": "example.com"},
    ],
}

hive.alert.create(alert=input_alert)

Add observables to an existing alert

While it's probably the most convenient way to combine alert and observable creation in a single call, sometimes we don't have all the observables at hand during alert creation time.

Fortunately TheHive API supports alert observable creation on already existing alerts. Let's repeat the previous example, but this time add the two observables to an existing alert using the alert.create_observable method:

import uuid

from thehive4py import TheHiveApi
from thehive4py.types.alert import InputAlert
from thehive4py.types.observable import InputObservable

hive = TheHiveApi(url="thehive.example", apikey="h1v3b33")

input_alert: InputAlert = {
    "type": "alert-without-observables",
    "source": "example",
    "sourceRef": uuid.uuid4().hex,
    "title": "alert without observables",
    "description": "alert without observables",
}

output_alert = hive.alert.create(alert=input_alert)


input_observables: list[InputObservable] = [
    {"dataType": "ip", "data": "1.2.3.4"},
    {"dataType": "domain", "data": "example.com"},
]


for input_observable in input_observables:
    hive.alert.create_observable(
        alert_id=output_alert["_id"], observable=input_observable
    )

Add file based observables

In the previous examples we've seen how to handle simple observables without attachments. Next we will create a temporary directory with a dummy file and some dummy content that will represent our file based observable and add it to an alert:

import os.path
import tempfile
import uuid

from thehive4py import TheHiveApi
from thehive4py.types.alert import InputAlert

hive = TheHiveApi(url="http://localhost:9000", apikey="h1v3b33")

with tempfile.TemporaryDirectory() as tmpdir:

    observable_filepath = os.path.join(tmpdir, "my-observable.txt")
    with open(observable_filepath) as observable_file:
        observable_file.write("some observable content")

    attachment_key = uuid.uuid4().hex
    attachment_map = {attachment_key: observable_filepath}
    input_alert: InputAlert = {
        "type": "alert-with-file-observable",
        "source": "example",
        "sourceRef": uuid.uuid4().hex,
        "title": "alert with file observables",
        "description": "alert with file observables",
        "observables": [
            {"dataType": "file", "attachment": attachment_key},
        ],
    }

    hive.alert.create(alert=input_alert, attachment_map=attachment_map)

As we can see from the above example a file based observable must specify the attachment property with a key that links it to the attachment specified in the attachment_map dictionary.

This way TheHive will know which attachment to pair with which observable behind the scenes.

In our example attachment_key is used to specify the relationship between the observable and the actual file. In this case its value is a uuid, however it can be any arbitrary value, though it's important that it should uniquely identify the attachment and the observable we would like to pair in TheHive.

Update single and bulk

Sometimes an existing alert needs to be updated. thehive4py offers multiple ways to accomplish this task either with a single alert or multiple ones.

Update single

A single alert can be updated using alert.update method. The method requires the alert_id of the alert to be updated and the fields to update.

import uuid

from thehive4py import TheHiveApi

hive = TheHiveApi(url="http://localhost:9000", apikey="h1v3b33")

original_alert = hive.alert.create(
    alert={
        "type": "update-single",
        "source": "tutorial",
        "sourceRef": uuid.uuid4().hex,
        "title": "original alert",
        "description": "a single alert to update",
    }
)


hive.alert.update(
    alert_id=original_alert["_id"],
    fields={
        "title": "updated alert",
        "tags": ["update-single"],
    },
)

updated_alert = hive.alert.get(alert_id=original_alert["_id"])

In the above example we've updated the title and the tags fields.

Be mindful though, thehive4py is a lightweight wrapper around TheHive API and offers no object relationship mapping functionalities, meaning that the original original_alert won't reflect the changes of the update.

To work with the updated alert we fetched the latest version using the alert.get method and stored it in the updated_alert variable.

Now the content of updated_alert should reflect the changes we made with our update request.

Tip

To see the full list of supported update fields please consult the official docs.

Update bulk

To update the same fields with the same values on multiple alerts at the same time, one can use alert.bulk_update method. The method accepts the same fields dictionary with an additional ids field on it, which should contain the list of ids of the alerts to be bulk updated.

import uuid

from thehive4py import TheHiveApi

hive = TheHiveApi(url="http://localhost:9000", apikey="h1v3b33")

original_alert_ids = []
for i in range(2):
    original_alert = hive.alert.create(
        alert={
            "type": "update-bulk",
            "source": "tutorial",
            "sourceRef": uuid.uuid4().hex,
            "title": f"original alert #{i}",
            "description": "an alert to update in bulk",
        }
    )

    original_alert_ids.append(original_alert["_id"])


hive.alert.bulk_update(
    fields={
        "ids": original_alert_ids,
        "title": "bulk updated alert",
        "tags": ["update-bulk"],
    },
)

In the example we prepare two alerts for the bulk update, and collect their ids in the original_alert_ids list. Then we update the fields title and tags on both alerts using the bulk update method.

Get and find

There are multiple ways to retrieve already existing alerts:

Get a single alert

To get a single alert one can use the alert.get method with the alert's id as follows:

import uuid

from thehive4py import TheHiveApi

hive = TheHiveApi(url="http://localhost:9000", apikey="h1v3b33")

alert_to_get = hive.alert.create(
    alert={
        "type": "get-single",
        "source": "tutorial",
        "sourceRef": uuid.uuid4().hex,
        "title": "alert to get",
        "description": "a single alert to fetch",
    }
)


fetched_alert = hive.alert.get(alert_id=alert_to_get["_id"])

Find multiple alerts

To fetch multiple alerts based on arbitrary conditions one can use the alert.find method which is an abstraction on top of TheHive's Query API.

In the next example we will create two alerts with different tags. The first alert will get the antivirus tag while the second one will get the phishing tag.

Then we will construct a query filter that will look for alerts with these tags on them:

import uuid

from thehive4py import TheHiveApi
from thehive4py.query.filters import Eq

hive = TheHiveApi(url="http://localhost:9000", apikey="h1v3b33")

antivirus_alert = hive.alert.create(
    alert={
        "type": "find-multiple",
        "source": "tutorial",
        "sourceRef": uuid.uuid4().hex,
        "title": "alert to find",
        "description": "an alert to find with others",
        "tags": ["antivirus"],
    }
)

phishing_alert = hive.alert.create(
    alert={
        "type": "find-multiple",
        "source": "tutorial",
        "sourceRef": uuid.uuid4().hex,
        "title": "alert to find",
        "description": "an alert to find with others",
        "tags": ["phishing"],
    }
)


raw_filters = {
    "_or": [
        {"_eq": {"_field": "tags", "_value": "antivirus"}},
        {"_eq": {"_field": "tags", "_value": "antivirus"}},
    ]
}
all_alerts_with_raw_filters = hive.alert.find(filters=raw_filters)

class_filters = Eq(field="tags", value="antivirus") | Eq(field="tags", value="phishing")
all_alerts_with_class_filters = hive.alert.find(filters=class_filters)

The above example demonstrates two ways to construct query filters.

One is to provide a raw dict based filter which is the plain format of TheHive's Query API. This is demonstrated in the raw_filters variable.

However this can be cumbersome to remember, that's why thehive4py provides filter builders to conveniently build filter expressions on the client side. This alternative approach is demonstrated in the class_filters variable.

These filter expressions can be chained together with different operators, just like we did with the | (or) operator in the example.

Currently, the filter classes support the following operators:

  • &: Used for the Query API's _and construct.
  • |: Used for the Query API's _or construct.
  • ~: Used for the Query API's _not construct.

The full list of the filter builders can be found in the query.filters module.

Promote and merge into a case

In TheHive alerts usually represent signals of compromise while cases provide a higher level entity to group these signals into one object. Therefore we can promote an alert into a case or merge new alerts into an existing case for a more organised investigation.

Promote to case

To create a case from an alert we can use alert.promote_to_case method.

import uuid

from thehive4py import TheHiveApi

hive = TheHiveApi(url="http://localhost:9000", apikey="h1v3b33")

alert_to_promote = hive.alert.create(
    alert={
        "type": "promote",
        "source": "tutorial",
        "sourceRef": uuid.uuid4().hex,
        "title": "promote to case",
        "description": "an alert to promote to case",
    }
)

case_from_alert = hive.alert.promote_to_case(alert_id=alert_to_promote["_id"])

Tip

For additional control the method accepts a fields argument which can be used to modify properties on the case. To see all available options please consult the official docs.

Merge into case

Oftentimes new alerts correspond to an already existing case. Fortunately we have the option to merge such alerts into a parent case using the alert.merge_into_case method.

import uuid

from thehive4py import TheHiveApi

hive = TheHiveApi(url="http://localhost:9000", apikey="h1v3b33")


parent_case = hive.case.create(
    case={"title": "parent case", "description": "a simple parent case"}
)

new_alert = hive.alert.create(
    alert={
        "type": "merge-into-case",
        "source": "tutorial",
        "sourceRef": uuid.uuid4().hex,
        "title": "alert to merge",
        "description": "a single alert to merge into a parent case",
    }
)

updated_parent_case = hive.alert.merge_into_case(
    alert_id=new_alert["_id"], case_id=parent_case["_id"]
)

In the above example we prepared a parent_case to which we merge the new_alert using their ids and finally save the updated case in the updated_parent_case variable.

Tip

It can happen that multiple new alerts belong to the same parent case. In such situation we can use the alert.bulk_merge_into_case method for a more convenient merge process.

Delete single and bulk

thehive4py provides two different ways to delete alerts:

  • delete a single alert
  • delete alerts in bulk

Delete single

To delete a single alert the alert.delete method can be used as follows:

import uuid

from thehive4py import TheHiveApi

hive = TheHiveApi(url="http://localhost:9000", apikey="h1v3b33")

alert_to_delete = hive.alert.create(
    alert={
        "type": "delete",
        "source": "tutorial",
        "sourceRef": uuid.uuid4().hex,
        "title": "delete alert",
        "description": "an alert to delete",
    }
)


hive.alert.delete(alert_id=alert_to_delete["_id"])

Delete in bulk

To delete multiple alerts via a single request one can use the alert.bulk_delete method as follows:

import uuid

from thehive4py import TheHiveApi

hive = TheHiveApi(url="http://localhost:9000", apikey="h1v3b33")

alert_ids_to_delete = []

for i in range(2):
    alert_to_delete = hive.alert.create(
        alert={
            "type": "delete",
            "source": "tutorial",
            "sourceRef": uuid.uuid4().hex,
            "title": f"delete alert #{i}",
            "description": "an alert to delete",
        }
    )
    alert_ids_to_delete.append(alert_to_delete["_id"])


hive.alert.bulk_delete(ids=alert_ids_to_delete)

In the above example we created two alerts and saved their ids in the alert_ids_to_delete variable just to pass it in the bulk deletion method.