DigitalGuardianARCEventCollector

Digital Guardian ARC event collector.

Analytics & SIEM · Digital Guardian

Details

IDDigitalGuardianARCEventCollector
ProviderFortra
CategoryAnalytics & SIEM
From Version6.8.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix XSIAM

README

This is the Digital Guardian ARC event collector integration for Cortex XSIAM.
This integration was integrated and tested with version 3.10.0 of DigitalGuardianARCEventCollector

This is the default integration for this content pack when configured by the Data Onboarder in Cortex XSIAM.

Known Limitations

  • By default, a maximum of 10,000 events can be retrieved per fetch for each Digital Guardian export profile. To increase the volume of fetched events beyond this value, set the “Number of Export Requests per Fetch” configuration parameter to greater than 1. For example, setting this parameter to 4 would fetch up to 40,000 events per export profile. Note that fetching a large number of events may result in exceeding the daily data ingestion quota in the Cortex XSIAM license plan.

  • Events are fetched starting from the Last Exported Record timestamp of the export profile. When first configuring the event collector, it is highly recommended to adjust the value of this field in the selected export profile(s) to a recent timestamp to prevent the fetching of outdated events.

    If older events are still being fetched from the export profile despite updating this setting, you may need to contact Digital Guardian Support.

Configure Digital Guardian ARC Event Collector in Cortex

Parameter Description Required
Auth Server URL (e.g. https://some_url.com)   True
Gateway Base URL (e.g. https://some_url.com)   True
Client ID   True
Client Secret Client Secret True
Trust any certificate (not secure)   False
Use system proxy settings   False
Export Profiles Internal document names or GUIDs of the Digital Guardian ARC export profiles. Custom export profiles are not officially supported. Default is defaultExportProfile. True
Number of Export Requests per Fetch Number of API calls per fetch to export events for each configured Digital Guardian ARC export profile. Use with extreme caution as this might impact data ingestion quota limits and performance. Consult with the engineering team before changing this value. Default is 1. False

Commands

You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.

digital-guardian-get-events


Gets events from the configured Digital Guardian ARC export profiles. This command is intended for development and debugging purposes and should be used with caution as it may create duplicate events.

Base Command

digital-guardian-get-events

Input

Argument Name Description Required
should_push_events If true, the command will create events, otherwise it will only display them. Possible values are: true, false. Default is false. Required
limit Maximum results to return per export profile. Default is 1000. Optional

Command Example

!digital-guardian-get-events limit=2 should_push_events=false

Context Output

There is no context output for this command.

Human Readable Output

Events for Profile defaultExportProfile

dg_agent_version dg_display dg_file_size dg_first dg_guid dg_hc dg_machine_name dg_machine_type dg_mid dg_parent_name dg_processed_time dg_src_dir dg_src_file_ext dg_src_file_name dg_time dg_utype dg_wdb dg_wrv pi_nda uad_sfc
7.9.4.0026 Discovery Event 51 B True 4a2c2692-044c-4f53-ac9b-f0fbd3b0ef3b Yes examplecompany\srt-test-dp1 Windows ffcd1683-7f92-1fd2-fb23-c16ff063bfb4 (unknown) 2024-12-11 04:37:16 PM c:\windows\servicing\lcu\ouppolicy_resources\ adml autoplay.adml 2024-12-11 04:37:16 PM Discovery Event No No No Yes
7.9.4.0026 Discovery Event 27.5 KB True d343c704-7b1f-43c3-b558-178d7780fcd3 Yes examplecompany\srt-test-dp1 Windows ffcd1683-7f92-1fd2-fb23-c16ff063bfb4 (unknown) 2024-12-11 04:37:16 PM c:\windows\servicing\lcu\package_for_rollupfix\ dll settingshandlers_user.dll 2024-12-11 04:37:16 PM Discovery Event No No No Yes

Configuration parameters

  • auth_server_url — Auth Server URL (e.g. https://authsrv.msp.digitalguardian.com) (required)
  • gateway_base_url — Gateway Base URL (e.g. https://accessgw-usw.msp.digitalguardian.com) (required)
  • credentials — Client ID (required)
  • export_profile — Export Profiles (required)
  • export_calls_per_fetch — Number of Export Requests per Fetch
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (1)

  • digital-guardian-get-events

    Gets events from the configured Digital Guardian ARC export profiles. This command is intended for development and debugging purposes and should be used with caution as it may create duplicate events.

import json
from urllib.parse import urljoin
import pytest
from freezegun import freeze_time
from pytest_mock.plugin import MockerFixture
from requests_mock.mocker import Mocker as RequestsMock
from DigitalGuardianARCEventCollector import Client


CLIENT_KWARGS = {
    "verify": False,
    "proxy": False,
    "auth_url": "https://example.com",
    "base_url": "https://example.com",
    "client_id": "11",
    "client_secret": "22",
}
EXPORT_PROFILE = "demisto"


def util_load_json(path):
    with open(path, encoding="utf-8") as f:
        return json.loads(f.read())


@pytest.fixture
def authenticated_client(requests_mock: RequestsMock) -> Client:
    """Fixture to create a Digital Guardian Client instance."""
    token_url = urljoin(CLIENT_KWARGS["auth_url"], "/as/token.oauth2")
    requests_mock.post(token_url, json={"access_token": "123", "expires_in": 10000})

    return Client(**CLIENT_KWARGS)


@freeze_time("2024-11-30 12:12:12 UTC")
def test_get_or_generate_access_token(mocker: MockerFixture):
    """
    Given:
        - A valid access token in the integration context
    When:
        - Calling Client._get_or_generate_access_token
    Then:
        - Ensure the token in the integration context is returned and no new token is requested.
    """
    integration_context_token = {"token": "123", "valid_until": 1733128972}  # 2024-12-02 08:43:55 UTC
    mocker.patch("DigitalGuardianARCEventCollector.get_integration_context", return_value=integration_context_token)
    get_new_token_request = mocker.patch.object(Client, "_http_request")

    client = Client(**CLIENT_KWARGS)
    access_token = client._get_or_generate_access_token()

    assert access_token == integration_context_token["token"]
    assert get_new_token_request.called is False


@pytest.mark.parametrize("index", [0, 1])
def test_create_events_for_push(index: int):
    """
    Given:
        - Index of an item in a list of events and a limit value
    When:
        - Calling create_events_for_push
    Then:
        - Ensure the _time key is added to the events
    """
    from DigitalGuardianARCEventCollector import create_events_for_push, arg_to_datetime, DATE_FORMAT

    limit = 2
    raw_response = util_load_json("test_data/mock_response.json")

    outputted_events = create_events_for_push(raw_response, EXPORT_PROFILE, limit)
    expected_event_time = arg_to_datetime(outputted_events[index]["dg_time"]).strftime(DATE_FORMAT)

    assert outputted_events[index]["_time"] == expected_event_time
    assert outputted_events[index]["dg_export_profile"] == EXPORT_PROFILE
    assert len(outputted_events) == limit


def test_get_fetch_events(mocker: MockerFixture, authenticated_client: Client):
    """
    Given:
        - Digital Guardian ARC client and number of days to get events
    When:
        - Calling fetch_events
    Then:
        - Ensure the events and last run are returned as expected
    """
    from DigitalGuardianARCEventCollector import fetch_events

    raw_response = util_load_json("test_data/mock_response.json")  # contains duplicate events
    mocker.patch.object(authenticated_client, "export_events", return_value=raw_response)
    expected_events = util_load_json("test_data/expected_events.json")

    outputted_events, last_run = fetch_events(authenticated_client, EXPORT_PROFILE)

    assert outputted_events == expected_events
    assert last_run["bookmark_values"] == raw_response["bookmark_values"]
    assert last_run["search_after_values"] == raw_response["search_after_values"]


def test_get_events_command(mocker: MockerFixture, authenticated_client: Client):
    """
    Given:
        - Digital Guardian ARC client and limit of events to get
    When:
        - Calling get_events_command
    Then:
        - Ensure the events are returned as expected and correct arguments are passed to tableToMarkdown
    """
    from DigitalGuardianARCEventCollector import get_events_command

    limit = 1
    raw_response = util_load_json("test_data/mock_response.json")
    mocker.patch.object(authenticated_client, "export_events", return_value=raw_response)
    table_to_markdown = mocker.patch("DigitalGuardianARCEventCollector.tableToMarkdown")

    outputted_events, *_ = get_events_command(authenticated_client, args={"limit": limit}, export_profile=EXPORT_PROFILE)

    expected_events = util_load_json("test_data/expected_events.json")[:limit]
    table_to_markdown_kwargs: dict = table_to_markdown.call_args.kwargs

    assert outputted_events == expected_events
    assert table_to_markdown_kwargs["name"] == f"Events for Profile {EXPORT_PROFILE}"
    assert table_to_markdown_kwargs["t"] == expected_events


def test_push_events(mocker: MockerFixture):
    """
    Given:
        - Digital Guardian ARC client and parsed events
    When:
        - Calling push_events
    Assert:
        - Ensure events are sent to XSIAM with the correct product and vendor.
    """
    from DigitalGuardianARCEventCollector import push_events, VENDOR, PRODUCT

    events = util_load_json("test_data/expected_events.json")

    send_events_to_xsiam = mocker.patch("DigitalGuardianARCEventCollector.send_events_to_xsiam")

    push_events(events, EXPORT_PROFILE)
    send_events_to_xsiam_kwargs: dict = send_events_to_xsiam.call_args.kwargs

    assert send_events_to_xsiam.call_count == 1
    assert send_events_to_xsiam_kwargs["events"] == events
    assert send_events_to_xsiam_kwargs["vendor"] == VENDOR
    assert send_events_to_xsiam_kwargs["product"] == PRODUCT


def test_set_export_bookmark(mocker: MockerFixture, authenticated_client: Client):
    """
    Given:
        - Digital Guardian ARC client and events last run
    When:
        - Calling set_export_bookmark
    Assert:
        - Ensure correct API call is performed.
    """
    from DigitalGuardianARCEventCollector import set_export_bookmark

    last_run = {"bookmark_values": [], "search_after_values": []}

    client_http_request = mocker.patch.object(authenticated_client, "_http_request")

    set_export_bookmark(authenticated_client, last_run, EXPORT_PROFILE)
    client_http_request_kwargs: dict = client_http_request.call_args.kwargs

    assert client_http_request.call_count == 1
    assert client_http_request_kwargs["method"] == "POST"
    assert client_http_request_kwargs["url_suffix"] == f"/rest/2.0/export_profiles/{EXPORT_PROFILE}/acknowledge"