Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,7 @@
/packages/withsecure_elements @elastic/security-service-integrations
/packages/wiz @elastic/security-service-integrations
/packages/wmi @elastic/obs-infraobs-integrations
/packages/xm_cyber @elastic/security-service-integrations
/packages/zeek @elastic/integration-experience
/packages/zerofox @elastic/security-service-integrations
/packages/zeronetworks @elastic/security-service-integrations
Expand Down
3 changes: 3 additions & 0 deletions packages/xm_cyber/_dev/build/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dependencies:
ecs:
reference: 'git@v9.3.0'
109 changes: 109 additions & 0 deletions packages/xm_cyber/_dev/build/docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# XM Cyber Integration

## Overview

[XM Cyber](https://www.xmcyber.com) is a **Continuous Threat Exposure Management (CTEM)** and attack path management platform. It continuously simulates attacker movement across hybrid environments including on-premises, cloud, and identity infrastructure — combining vulnerabilities, misconfigurations, and overly permissive access into prioritized attack paths that lead to **critical assets**.

This integration collects data from the XM Cyber REST API using scheduled polling. It provides visibility into your organization's security posture across your environment.

### Compatibility

The XM Cyber integration is compatible with the API version **1.0.0**.

### How it works

The integration uses the Elastic Agent CEL (Common Expression Language) input to poll the XM Cyber REST API on a configurable schedule. Each poll:

1. Authenticates with a two-step flow: exchanges the API key for a short-lived Bearer access token via `POST /api/auth`
2. Fetches data from the configured endpoint.
3. Emits each record as an individual event for ingestion and enrichment via the built-in ingest pipeline

## What data does this integration collect?

The XM Cyber integration collects the following types of data:

| Data stream | Description | Endpoint |
|---|---|---|
| `product` | **Product-level** aggregates from VRM: one event per software product with fleet-wide counts (devices where it appears, choke-point presence, affected critical assets, products critical assets at risk, vulnerability count), vendor, and reported operating systems. | `/api/v2/vrm/public/products` |

### Supported use cases

- **Software exposure across the fleet**: Rank products by `product_vulnerabilities`, `devices_found_on`, and `choke_points_found_on`, and slice by `product_operating_systems` to align remediation with platform mix.
- **Critical-asset risk from products**: Use `affected_critical_assets` and `products_critical_assets_at_risk` with vendor and OS context to prioritize patch and upgrade work.

## What do I need to use this integration?

- **XM Cyber tenant**: An active XM Cyber deployment with access to `https://<your-org>.clients.xmcyber.com`
- **API key**: An XM Cyber API key associated with a user holding at minimum the **Security Analyst** role. Create one in **Settings → API / Integrations** in your XM Cyber admin console (refer to the XM Cyber customer portal at https://customers.xmcyber.com for current navigation steps)
- **Elastic Agent**: Version 8.18+ or 9.0+ with Fleet enrollment

## How do I deploy this integration?

This integration supports both Elastic Agentless-based and Agent-based installations.

### Agentless-based installation

Agentless integrations allow you to collect data without having to manage Elastic Agent in your cloud. They make manual agent deployment unnecessary, so you can focus on your data instead of the agent that collects it. For more information, refer to [Agentless integrations](https://www.elastic.co/guide/en/serverless/current/security-agentless-integrations.html) and the [Agentless integrations FAQ](https://www.elastic.co/guide/en/serverless/current/agentless-integration-troubleshooting.html).

Agentless deployments are only supported in Elastic Serverless and Elastic Cloud environments. This functionality is in beta and is subject to change. Beta features are not subject to the support SLA of official GA features.

### Agent-based installation

Elastic Agent must be installed. For more details, check the Elastic Agent [installation instructions](docs-content://reference/fleet/install-elastic-agents.md). You can install only one Elastic Agent per host.

### Configure

1. In Kibana, navigate to **Fleet → Integrations** and search for **XM Cyber**
2. Click **Add XM Cyber**
3. Configure the integration settings:
- **URL**: Your XM Cyber base URL, for example `https://your-org.clients.xmcyber.com`
- **API Key**: Your XM Cyber API key.
- **Interval**: How often to poll for new data (default: `24h`).
4. Select **Save and continue** to save the integration.

### Validation

#### Dashboard populated

1. In the top search bar in Kibana, search for **Dashboards**.
2. In the search bar, type **XM Cyber**, and verify the dashboard information is populated.

## Scaling

For more information on architectures that can be used for scaling this integration, check the [Ingest Architectures](https://www.elastic.co/docs/manage-data/ingest/ingest-reference-architectures) documentation.

## Troubleshooting

- **Authentication failures**: Verify the API key is valid and the URL includes the full `https://` prefix with no trailing slash
- **No data collected**: Check the Elastic Agent logs for CEL program errors. Ensure your XM Cyber user has the Security Analyst role and API access is enabled in your tenant settings
- **Rate limiting**: XM Cyber API rate limits are not publicly documented. If you observe HTTP 429 responses in agent logs, increase the collection interval

For help with Elastic ingest tools, check [Common problems](https://www.elastic.co/docs/troubleshoot/ingest/fleet/common-problems).

## Reference

### Product

#### Product fields

{{fields "product"}}

### Example event

#### Product

{{event "product"}}

### Inputs used

{{ inputDocs }}

### API usage

These XM Cyber REST API endpoints are used by this integration:

| Endpoint | Method | Data stream | Description |
|---|---|---|---|
| `/api/auth` | POST | all | Exchange API key for Bearer access token |
| `/api/refresh-token` | POST | all | Refresh an expired access token |
| `/api/v2/vrm/public/products` | GET | `product` | Paginated product-level exposure aggregates (counts and OS list per product) |
15 changes: 15 additions & 0 deletions packages/xm_cyber/_dev/deploy/docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
version: '3.8'
services:
xm_cyber:
image: docker.elastic.co/observability/stream:v0.20.0
hostname: xm_cyber
ports:
- 8090
volumes:
- ./files:/files:ro
environment:
PORT: '8090'
command:
- http-server
- --addr=:8090
- --config=/files/config.yml
96 changes: 96 additions & 0 deletions packages/xm_cyber/_dev/deploy/docker/files/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
rules:
# ----- Authentication -----
- path: /api/auth
methods: ['POST']
request_headers:
X-Api-Key: "mock-api-key"
responses:
- status_code: 200
headers:
Content-Type:
- 'application/json'
body: |-
{{ minify_json `
{
"accessToken": "mock-access-token-vuln",
"refreshToken": "mock-refresh-token-vuln"
}
`}}

# ----- Refresh-token -----
- path: /api/refresh-token
methods: ['POST']
request_headers:
Content-Type:
- 'application/json'
request_body: /.*"refreshToken".*/
responses:
- status_code: 200
headers:
Content-Type:
- 'application/json'
body: |-
{{ minify_json `
{
"accessToken": "mock-access-token-vuln-refreshed",
"refreshToken": "mock-refresh-token-vuln-refreshed"
}
`}}

- path: /api/v2/vrm/public/products
methods: ['GET']
query_params:
pageSize: '20'
request_headers:
Authorization: "Bearer mock-access-token-vuln"
responses:
- status_code: 200
headers:
Content-Type:
- 'application/json'
body: |-
{{ minify_json `
{
"data": [
{
"affectedCriticalAssets": 2,
"chokePointsFoundOn": 0,
"devicesFoundOn": 2,
"productName": "wget",
"productOperatingSystems": ["Linux sles 12.5 Server"],
"productVulnerabilities": 1,
"productsCriticalAssetsAtRisk": 0,
"vendor": null
},
{
"affectedCriticalAssets": 26,
"chokePointsFoundOn": 6,
"devicesFoundOn": 26,
"productName": ".net framework",
"productOperatingSystems": [
"Windows 10 ver 1909",
"Windows Server 2012 R2",
"Windows 7 SP 1.0",
"Windows Server 2012 R2 (DC)",
"Windows Server 2019 (DC)"
],
"productVulnerabilities": 71,
"productsCriticalAssetsAtRisk": 38,
"vendor": "microsoft"
},
{
"affectedCriticalAssets": 1,
"chokePointsFoundOn": 1,
"devicesFoundOn": 1,
"productName": "ACME Secure Agent",
"productOperatingSystems": ["Windows Server 2019 (DC)", "Ubuntu 22.04"],
"productVulnerabilities": 4243,
"productsCriticalAssetsAtRisk": 12,
"vendor": "ACME"
}
],
"meta": {
"next": null
}
}
`}}
11 changes: 11 additions & 0 deletions packages/xm_cyber/changelog.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# newer versions go on top
- version: 0.1.1
changes:
- description: Add support for product data stream.
type: enhancement
link: https://github.com/elastic/integrations/pull/18993
- version: 0.1.0
changes:
- description: Add support for risk score data stream.
type: enhancement
link: https://github.com/elastic/integrations/pull/18749
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fields:
tags:
- preserve_duplicate_custom_fields
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{"affectedCriticalAssets":2,"chokePointsFoundOn":0,"devicesFoundOn":2,"productName":"wget","productOperatingSystems":["Linux sles 12.5 Server"],"productVulnerabilities":1,"productsCriticalAssetsAtRisk":0,"vendor":null}
{"affectedCriticalAssets":26,"chokePointsFoundOn":6,"devicesFoundOn":26,"productName":".net framework","productOperatingSystems":["Windows 10 ver 1909","Windows Server 2012 R2","Windows 7 SP 1.0","Windows Server 2012 R2 (DC)","Windows Server 2019 (DC)"],"productVulnerabilities":71,"productsCriticalAssetsAtRisk":38,"vendor":"microsoft"}
{"affectedCriticalAssets":1,"chokePointsFoundOn":1,"devicesFoundOn":1,"productName":"ACME Secure Agent","productOperatingSystems":["Windows Server 2019 (DC)","Ubuntu 22.04"],"productVulnerabilities":4243,"productsCriticalAssetsAtRisk":12,"vendor":"ACME"}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
{
"expected": [
{
"ecs": {
"version": "9.3.0"
},
"event": {
"kind": "event",
"original": "{\"affectedCriticalAssets\":2,\"chokePointsFoundOn\":0,\"devicesFoundOn\":2,\"productName\":\"wget\",\"productOperatingSystems\":[\"Linux sles 12.5 Server\"],\"productVulnerabilities\":1,\"productsCriticalAssetsAtRisk\":0,\"vendor\":null}"
},
"tags": [
"preserve_duplicate_custom_fields"
],
"xm_cyber": {
"product": {
"affected_critical_assets": 2,
"choke_points_found_on": 0,
"devices_found_on": 2,
"product_name": "wget",
"product_operating_systems": [
"Linux sles 12.5 Server"
],
"product_vulnerabilities": 1,
"products_critical_assets_at_risk": 0
}
}
},
{
"ecs": {
"version": "9.3.0"
},
"event": {
"kind": "event",
"original": "{\"affectedCriticalAssets\":26,\"chokePointsFoundOn\":6,\"devicesFoundOn\":26,\"productName\":\".net framework\",\"productOperatingSystems\":[\"Windows 10 ver 1909\",\"Windows Server 2012 R2\",\"Windows 7 SP 1.0\",\"Windows Server 2012 R2 (DC)\",\"Windows Server 2019 (DC)\"],\"productVulnerabilities\":71,\"productsCriticalAssetsAtRisk\":38,\"vendor\":\"microsoft\"}"
},
"tags": [
"preserve_duplicate_custom_fields"
],
"xm_cyber": {
"product": {
"affected_critical_assets": 26,
"choke_points_found_on": 6,
"devices_found_on": 26,
"product_name": ".net framework",
"product_operating_systems": [
"Windows 10 ver 1909",
"Windows Server 2012 R2",
"Windows 7 SP 1.0",
"Windows Server 2012 R2 (DC)",
"Windows Server 2019 (DC)"
],
"product_vulnerabilities": 71,
"products_critical_assets_at_risk": 38,
"vendor": "microsoft"
}
}
},
{
"ecs": {
"version": "9.3.0"
},
"event": {
"kind": "event",
"original": "{\"affectedCriticalAssets\":1,\"chokePointsFoundOn\":1,\"devicesFoundOn\":1,\"productName\":\"ACME Secure Agent\",\"productOperatingSystems\":[\"Windows Server 2019 (DC)\",\"Ubuntu 22.04\"],\"productVulnerabilities\":4243,\"productsCriticalAssetsAtRisk\":12,\"vendor\":\"ACME\"}"
},
"tags": [
"preserve_duplicate_custom_fields"
],
"xm_cyber": {
"product": {
"affected_critical_assets": 1,
"choke_points_found_on": 1,
"devices_found_on": 1,
"product_name": "ACME Secure Agent",
"product_operating_systems": [
"Windows Server 2019 (DC)",
"Ubuntu 22.04"
],
"product_vulnerabilities": 4243,
"products_critical_assets_at_risk": 12,
"vendor": "ACME"
}
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
wait_for_data_timeout: 1m
input: cel
service: xm_cyber
vars:
url: http://{{Hostname}}:{{Port}}
api_key: mock-api-key
data_stream:
vars:
interval: 24h
page_size: 20
preserve_original_event: true
preserve_duplicate_custom_fields: true
assert:
min_count: 2
Loading
Loading