Skip to content

Commit 13a96ac

Browse files
feat(arcsight-incidents): add external-import connector for ArcSight ESM cases (#6723) (#6724)
1 parent 79556ea commit 13a96ac

25 files changed

Lines changed: 1703 additions & 0 deletions
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
__metadata__
2+
**/__pycache__
3+
**/__docs__
4+
**/.venv
5+
**/venv
6+
**/logs
7+
**/config.yml
8+
**/*.egg-info
9+
**/*.gql
10+
tests
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
FROM python:3.12-alpine
2+
ENV CONNECTOR_TYPE=EXTERNAL_IMPORT
3+
4+
# Copy the connector
5+
COPY src /opt/opencti-connector-arcsight-incidents
6+
WORKDIR /opt/opencti-connector-arcsight-incidents
7+
8+
# Install Python modules
9+
# hadolint ignore=DL3003
10+
RUN apk update && apk upgrade && \
11+
apk --no-cache add git build-base libmagic libffi-dev libxml2-dev libxslt-dev && \
12+
pip3 install --no-cache-dir -r requirements.txt && \
13+
apk del git build-base
14+
15+
ENTRYPOINT ["python3", "main.py"]
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# OpenCTI ArcSight Incidents Connector
2+
3+
The ArcSight Incidents connector is an **external-import** connector that pulls
4+
cases and their security events from ArcSight ESM into OpenCTI. It is the import
5+
side of a bidirectional integration: pair it with the `stream/arcsight` connector
6+
(which pushes IOCs to ESM Active Lists) to send IOCs out and bring cases in.
7+
8+
ArcSight exposes two distinct concepts that map to two STIX entities:
9+
10+
- **Security events** (detections/alerts) referenced by a case are modeled as
11+
STIX **Incidents**.
12+
- The **case** itself (a case-management artifact) is modeled as a STIX
13+
**Case-Incident** that references the event Incidents it groups through its
14+
`object_refs`.
15+
16+
Table of Contents
17+
18+
- [OpenCTI ArcSight Incidents Connector](#opencti-arcsight-incidents-connector)
19+
- [Introduction](#introduction)
20+
- [Requirements](#requirements)
21+
- [Configuration variables](#configuration-variables)
22+
- [OpenCTI environment variables](#opencti-environment-variables)
23+
- [Base connector environment variables](#base-connector-environment-variables)
24+
- [Connector extra parameters environment variables](#connector-extra-parameters-environment-variables)
25+
- [Deployment](#deployment)
26+
- [Docker Deployment](#docker-deployment)
27+
- [Manual Deployment](#manual-deployment)
28+
- [Behavior](#behavior)
29+
30+
## Introduction
31+
32+
ArcSight ESM (OpenText) is a SIEM platform. This connector periodically queries
33+
the ESM Service Layer REST API (`CaseService` and `SecurityEventService`) for
34+
cases and the events they reference, then imports them into OpenCTI as STIX 2.1
35+
Case-Incidents (the cases) and Incidents (the events), attributed to an ArcSight
36+
author identity and marked with a configurable TLP.
37+
38+
## Requirements
39+
40+
- OpenCTI Platform >= 7.260701.0
41+
- A reachable ArcSight ESM Manager (Service Layer REST API enabled)
42+
- An ESM account allowed to read cases
43+
44+
## Configuration variables
45+
46+
Configuration parameters can be provided in either `config.yml` (see
47+
`config.yml.sample`), `docker-compose.yml` (environment variables) or directly as
48+
environment variables.
49+
50+
### OpenCTI environment variables
51+
52+
| Parameter | config.yml | Docker environment variable | Mandatory | Description |
53+
| ------------- | ---------- | --------------------------- | --------- | ---------------------------------------------------- |
54+
| OpenCTI URL | `url` | `OPENCTI_URL` | Yes | The URL of the OpenCTI platform. |
55+
| OpenCTI Token | `token` | `OPENCTI_TOKEN` | Yes | The default admin token set in the OpenCTI platform. |
56+
57+
### Base connector environment variables
58+
59+
| Parameter | config.yml | Docker environment variable | Default | Mandatory | Description |
60+
| --------------- | ----------------- | ---------------------------- | -------------------- | --------- | --------------------------------------------------- |
61+
| Connector ID | `id` | `CONNECTOR_ID` | / | Yes | A unique `UUIDv4` identifier for this connector. |
62+
| Connector Name | `name` | `CONNECTOR_NAME` | `ArcSight Incidents` | No | Name of the connector. |
63+
| Connector Scope | `scope` | `CONNECTOR_SCOPE` | / | Yes | The scope of the connector. |
64+
| Log Level | `log_level` | `CONNECTOR_LOG_LEVEL` | `error` | No | Logs verbosity (`debug`, `info`, `warn`, `warning`, `error`). |
65+
| Duration Period | `duration_period` | `CONNECTOR_DURATION_PERIOD` | `PT15M` | No | ISO-8601 period between two runs. |
66+
67+
### Connector extra parameters environment variables
68+
69+
| Parameter | config.yml | Docker environment variable | Default | Mandatory | Description |
70+
| ------------ | -------------- | ---------------------------------- | ------- | --------- | ------------------------------------------------- |
71+
| API base URL | `api_base_url` | `ARCSIGHT_INCIDENTS_API_BASE_URL` | / | Yes | Base URL of the ArcSight ESM Manager. |
72+
| Username | `username` | `ARCSIGHT_INCIDENTS_USERNAME` | / | Yes | ESM user name. |
73+
| Password | `password` | `ARCSIGHT_INCIDENTS_PASSWORD` | / | Yes | ESM user password. |
74+
| Max cases | `max_cases` | `ARCSIGHT_INCIDENTS_MAX_CASES` | `200` | No | Maximum number of cases to fetch per run. |
75+
| TLP level | `tlp_level` | `ARCSIGHT_INCIDENTS_TLP_LEVEL` | `amber` | No | TLP marking applied to imported incidents. |
76+
| SSL verify | `ssl_verify` | `ARCSIGHT_INCIDENTS_SSL_VERIFY` | `true` | No | Whether to verify the SSL certificate. |
77+
78+
## Deployment
79+
80+
### Docker Deployment
81+
82+
Build a Docker image using the provided `Dockerfile`:
83+
84+
```shell
85+
docker build . -t opencti/connector-arcsight-incidents:latest
86+
```
87+
88+
Make sure to replace the environment variables in `docker-compose.yml` with the
89+
appropriate configurations, then start the connector:
90+
91+
```shell
92+
docker compose up -d
93+
```
94+
95+
### Manual Deployment
96+
97+
Copy `config.yml.sample` to `src/config.yml` and fill in the values, then:
98+
99+
```shell
100+
cd src
101+
pip install -r requirements.txt
102+
python main.py
103+
```
104+
105+
## Behavior
106+
107+
On each run the connector authenticates against the ESM `LoginService`, lists case
108+
ids via `CaseService` (capped at `max_cases`) and fetches each case. For every case
109+
it also resolves the referenced security events via `SecurityEventService`, converts
110+
each event to a STIX Incident, and converts the case to a STIX Case-Incident that
111+
references those Incidents through its `object_refs`. The resulting bundle is sent
112+
to OpenCTI, which deduplicates both entity types by their deterministic id across
113+
runs.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Connector Configurations
2+
3+
Below is an exhaustive enumeration of all configurable parameters available, each accompanied by detailed explanations of their purposes, default behaviors, and usage guidelines to help you understand and utilize them effectively.
4+
5+
### Type: `object`
6+
7+
| Property | Type | Required | Possible values | Default | Description |
8+
| -------- | ---- | -------- | --------------- | ------- | ----------- |
9+
| OPENCTI_URL | `string` || Format: [`uri`](https://json-schema.org/understanding-json-schema/reference/string#built-in-formats) | | The base URL of the OpenCTI instance. |
10+
| OPENCTI_TOKEN | `string` || string | | The API token to connect to OpenCTI. |
11+
| CONNECTOR_SCOPE | `array` || string | | The scope of the connector, e.g. 'flashpoint'. |
12+
| ARCSIGHT_INCIDENTS_API_BASE_URL | `string` || Format: [`uri`](https://json-schema.org/understanding-json-schema/reference/string#built-in-formats) | | Base URL of the ArcSight ESM Manager (e.g. https://arcsight.example.com:8443). |
13+
| ARCSIGHT_INCIDENTS_USERNAME | `string` || string | | ArcSight ESM user name. |
14+
| ARCSIGHT_INCIDENTS_PASSWORD | `string` || Format: [`password`](https://json-schema.org/understanding-json-schema/reference/string#built-in-formats) | | ArcSight ESM user password. |
15+
| CONNECTOR_NAME | `string` | | string | `"ArcSight Incidents"` | The name of the connector. |
16+
| CONNECTOR_LOG_LEVEL | `string` | | `debug` `info` `warn` `warning` `error` | `"error"` | The minimum level of logs to display. |
17+
| CONNECTOR_TYPE | `const` | | `EXTERNAL_IMPORT` | `"EXTERNAL_IMPORT"` | |
18+
| CONNECTOR_DURATION_PERIOD | `string` | | Format: [`duration`](https://json-schema.org/understanding-json-schema/reference/string#built-in-formats) | `"PT15M"` | The period of time to await between two runs of the connector. |
19+
| ARCSIGHT_INCIDENTS_MAX_CASES | `integer` | | `1 <= x ` | `200` | Maximum number of ESM cases to fetch per run. |
20+
| ARCSIGHT_INCIDENTS_TLP_LEVEL | `string` | | `clear` `white` `green` `amber` `amber+strict` `red` | `"amber"` | TLP marking applied to the imported incidents. |
21+
| ARCSIGHT_INCIDENTS_SSL_VERIFY | `boolean` | | boolean | `true` | Whether to verify the SSL certificate of the ArcSight ESM Manager. |
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
{
2+
"$schema": "https://json-schema.org/draft/2020-12/schema",
3+
"$id": "https://www.filigran.io/connectors/arcsight-incidents_config.schema.json",
4+
"type": "object",
5+
"properties": {
6+
"OPENCTI_URL": {
7+
"description": "The base URL of the OpenCTI instance.",
8+
"format": "uri",
9+
"maxLength": 2083,
10+
"minLength": 1,
11+
"type": "string"
12+
},
13+
"OPENCTI_TOKEN": {
14+
"description": "The API token to connect to OpenCTI.",
15+
"type": "string"
16+
},
17+
"CONNECTOR_NAME": {
18+
"default": "ArcSight Incidents",
19+
"description": "The name of the connector.",
20+
"type": "string"
21+
},
22+
"CONNECTOR_SCOPE": {
23+
"description": "The scope of the connector, e.g. 'flashpoint'.",
24+
"items": {
25+
"type": "string"
26+
},
27+
"type": "array"
28+
},
29+
"CONNECTOR_LOG_LEVEL": {
30+
"default": "error",
31+
"description": "The minimum level of logs to display.",
32+
"enum": [
33+
"debug",
34+
"info",
35+
"warn",
36+
"warning",
37+
"error"
38+
],
39+
"type": "string"
40+
},
41+
"CONNECTOR_TYPE": {
42+
"const": "EXTERNAL_IMPORT",
43+
"default": "EXTERNAL_IMPORT",
44+
"type": "string"
45+
},
46+
"CONNECTOR_DURATION_PERIOD": {
47+
"default": "PT15M",
48+
"description": "The period of time to await between two runs of the connector.",
49+
"format": "duration",
50+
"type": "string"
51+
},
52+
"ARCSIGHT_INCIDENTS_API_BASE_URL": {
53+
"description": "Base URL of the ArcSight ESM Manager (e.g. https://arcsight.example.com:8443).",
54+
"format": "uri",
55+
"maxLength": 2083,
56+
"minLength": 1,
57+
"type": "string"
58+
},
59+
"ARCSIGHT_INCIDENTS_USERNAME": {
60+
"description": "ArcSight ESM user name.",
61+
"type": "string"
62+
},
63+
"ARCSIGHT_INCIDENTS_PASSWORD": {
64+
"description": "ArcSight ESM user password.",
65+
"format": "password",
66+
"type": "string",
67+
"writeOnly": true
68+
},
69+
"ARCSIGHT_INCIDENTS_MAX_CASES": {
70+
"default": 200,
71+
"description": "Maximum number of ESM cases to fetch per run.",
72+
"minimum": 1,
73+
"type": "integer"
74+
},
75+
"ARCSIGHT_INCIDENTS_TLP_LEVEL": {
76+
"default": "amber",
77+
"description": "TLP marking applied to the imported incidents.",
78+
"enum": [
79+
"clear",
80+
"white",
81+
"green",
82+
"amber",
83+
"amber+strict",
84+
"red"
85+
],
86+
"type": "string"
87+
},
88+
"ARCSIGHT_INCIDENTS_SSL_VERIFY": {
89+
"default": true,
90+
"description": "Whether to verify the SSL certificate of the ArcSight ESM Manager.",
91+
"type": "boolean"
92+
}
93+
},
94+
"required": [
95+
"OPENCTI_URL",
96+
"OPENCTI_TOKEN",
97+
"CONNECTOR_SCOPE",
98+
"ARCSIGHT_INCIDENTS_API_BASE_URL",
99+
"ARCSIGHT_INCIDENTS_USERNAME",
100+
"ARCSIGHT_INCIDENTS_PASSWORD"
101+
],
102+
"additionalProperties": true
103+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"title": "ArcSight Incidents",
3+
"slug": "arcsight-incidents",
4+
"description": "The OpenCTI ArcSight Incidents connector imports cases and their security events from ArcSight ESM into OpenCTI. It periodically fetches cases through the ESM Service Layer REST API (CaseService), resolves the referenced security events (SecurityEventService), converts each event (a detection) to a STIX 2.1 Incident, and converts the case (a case-management artifact) to a STIX 2.1 Case-Incident that references those Incidents through its object_refs. Paired with the ArcSight stream connector (which pushes IOCs to ESM Active Lists), it provides a bidirectional integration.",
5+
"short_description": "Import ArcSight ESM cases (Case-Incidents) and their events (Incidents) into OpenCTI (bidirectional import side).",
6+
"logo": null,
7+
"use_cases": [
8+
"Detection & Response Enablement",
9+
"SIEM and Analytics"
10+
],
11+
"verified": false,
12+
"last_verified_date": null,
13+
"playbook_supported": false,
14+
"max_confidence_level": 50,
15+
"support_version": ">=7.260701.0",
16+
"subscription_link": "https://www.opentext.com/products/arcsight-enterprise-security-manager",
17+
"source_code": "https://github.com/OpenCTI-Platform/connectors/tree/master/external-import/arcsight-incidents",
18+
"manager_supported": true,
19+
"container_version": "rolling",
20+
"container_image": "opencti/connector-arcsight-incidents",
21+
"container_type": "EXTERNAL_IMPORT"
22+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
opencti:
2+
url: 'http://localhost'
3+
token: 'ChangeMe'
4+
5+
connector:
6+
id: 'ChangeMe'
7+
type: 'EXTERNAL_IMPORT'
8+
name: 'ArcSight Incidents' # optional (default: 'ArcSight Incidents')
9+
scope: 'arcsight' # required
10+
log_level: 'error' # optional (default: 'error')
11+
duration_period: 'PT15M' # optional (default: 'PT15M')
12+
13+
arcsight_incidents:
14+
api_base_url: 'ChangeMe' # Base URL of the ArcSight ESM Manager, e.g. https://arcsight.example.com:8443
15+
username: 'ChangeMe'
16+
password: 'ChangeMe'
17+
max_cases: 200 # optional (default: 200)
18+
tlp_level: 'amber' # optional, one of clear/white/green/amber/amber+strict/red (default: 'amber')
19+
ssl_verify: true # optional (default: true)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
version: '3'
2+
services:
3+
connector-arcsight-incidents:
4+
image: opencti/connector-arcsight-incidents:latest
5+
environment:
6+
# Generic parameters (connection with OpenCTI)
7+
- OPENCTI_URL=http://localhost
8+
- OPENCTI_TOKEN=ChangeMe
9+
# Common parameters for connectors of type EXTERNAL_IMPORT
10+
- CONNECTOR_ID=ChangeMe
11+
- CONNECTOR_SCOPE=ChangeMe # required, e.g. 'arcsight'
12+
# - CONNECTOR_NAME=ArcSight Incidents # optional (default: 'ArcSight Incidents')
13+
# - CONNECTOR_LOG_LEVEL=error # optional (default: 'error')
14+
# - CONNECTOR_DURATION_PERIOD=PT15M # optional (default: 'PT15M')
15+
# ArcSight parameters
16+
- ARCSIGHT_INCIDENTS_API_BASE_URL=ChangeMe # e.g. https://arcsight.example.com:8443
17+
- ARCSIGHT_INCIDENTS_USERNAME=ChangeMe
18+
- ARCSIGHT_INCIDENTS_PASSWORD=ChangeMe
19+
# - ARCSIGHT_INCIDENTS_MAX_CASES=200 # optional (default: 200)
20+
# - ARCSIGHT_INCIDENTS_TLP_LEVEL=amber # optional (default: 'amber')
21+
# - ARCSIGHT_INCIDENTS_SSL_VERIFY=true # optional (default: true)
22+
restart: always
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from arcsight_client.api_client import ArcSightClient
2+
3+
__all__ = ["ArcSightClient"]

0 commit comments

Comments
 (0)