From a1c425e69d5c36ab305e86b5df8b2c911f8df6be Mon Sep 17 00:00:00 2001
From: Kfir Peled <61654899+kfirpeled@users.noreply.github.com>
Date: Fri, 25 Oct 2024 15:30:15 +0100
Subject: [PATCH] [Cloud Security] Added graph visualization in alert's flyout
(#196034)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## Summary
Enables a new experimental feature. To visualize an alert/event by a
graph.
When the alert/event does not contain the relevant data the graph
preview will not be visible (confirmed by @tinnytintin10)
To enable the feature through kibana's config:
```yaml
xpack.securitySolution.enableExperimental: ['graphVisualizationInFlyoutEnabled']
```
Event's graph visualization: 🎥
https://github.com/user-attachments/assets/4cee2032-173e-4b44-b371-a8e187763764
Alert's graph visualization: 🎥
https://github.com/user-attachments/assets/4fb942d0-6704-4c79-862c-956821ce59b6
Alert in rule preview: 🎥
https://github.com/user-attachments/assets/4f8d086e-1ee4-414f-8efa-4715c1d5e1f6
**List of TODO's**
- Add FTR test to host's flyout
- Add FTR test to alerts preview
- Enhance graph_preview_container UT to cover all edge cases
- Enhance visualization_section UT to cover all edge cases
**List of open issues (will be tracked in a different ticket):**
- Graph preview search on the past 60 days, which can lead to an empty
graph
- API should return 404 when the feature is not enabled
- ~Empty state message~ Not showing the graph preview instead.
**How to test:**
First, enable the feature, add to `config/kibana.dev.yml`:
```yaml
xpack.securitySolution.enableExperimental: ['graphVisualizationInFlyoutEnabled']
```
Second, load mocked data
```bash
node scripts/es_archiver load x-pack/test/cloud_security_posture_functional/es_archives/logs_gcp_audit \
--es-url http://elastic:changeme@localhost:9200 \
--kibana-url http://elastic:changeme@localhost:5601
node scripts/es_archiver load x-pack/test/cloud_security_posture_functional/es_archives/security_alerts \
--es-url http://elastic:changeme@localhost:9200 \
--kibana-url http://elastic:changeme@localhost:5601
```
1. Go to the alerts page
2. Change the query time range to show alerts from the 13th of October
2024
3. Open the alerts flyout
4. Scroll to see the graph visualization : D
### Checklist
Delete any items that are not applicable to this PR.
- [x] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [x]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
- [x] [Flaky Test
Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was
used on any tests changed
- [x] Any UI touched in this PR is usable by keyboard only (learn more
about [keyboard accessibility](https://webaim.org/techniques/keyboard/))
- [ ] Any UI touched in this PR does not create any new axe failures
(run axe in browser:
[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),
[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))
- [ ] This renders correctly on smaller devices using a responsive
layout. (You can test this [in your
browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))
- [ ] This was checked for [cross-browser
compatibility](https://www.elastic.co/support/matrix#matrix_browsers)
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
(cherry picked from commit b4a80d8d506dd474b4dfb599fc123cb612a5d79b)
---
.../steps/storybooks/build_and_upload.ts | 17 +-
.github/CODEOWNERS | 2 +-
.../src/worker/webpack.config.ts | 21 +
packages/kbn-storybook/src/webpack.config.ts | 19 +
.../common/kibana.jsonc | 9 +-
.../common/package.json | 14 +-
.../common/schema/graph/v1.ts | 4 -
.../graph/README.md | 99 +-
.../kbn-cloud-security-posture/graph/index.ts | 2 +
.../graph/jest.config.js | 2 +
.../graph/kibana.jsonc | 4 +-
.../graph/setup_tests.ts | 13 +
.../graph/src/components/graph/graph.test.tsx | 110 +
.../graph/src/components/graph/graph.tsx | 204 +
.../src/components/graph/layout_graph.ts | 87 +-
...h.stories.tsx => graph_layout.stories.tsx} | 184 +-
.../graph/src/components/index.ts | 11 +
.../graph/src/components/mock/react_flow.ts | 69 +
.../src/components/mock/test_providers.tsx | 23 +
.../src/components/node/button.stories.tsx | 6 +-
.../src/components/node/diamond_node.tsx | 91 +-
.../src/components/node/ellipse_node.tsx | 95 +-
.../src/components/node/hexagon_node.tsx | 91 +-
.../src/components/node/pentagon_node.tsx | 91 +-
.../src/components/node/rectangle_node.tsx | 99 +-
.../components/node/shapes/diamond_shape.tsx | 26 +
.../components/node/shapes/ellipse_shape.tsx | 17 +
.../components/node/shapes/hexagon_shape.tsx | 26 +
.../components/node/shapes/pentagon_shape.tsx | 26 +
.../node/shapes/rectangle_shape.tsx | 26 +
.../graph/src/components/node/shapes/types.ts | 15 +
.../graph/src/components/node/styles.tsx | 30 +-
.../graph/src/components/types.ts | 33 +-
.../graph/storybook/config/main.ts | 44 -
.../graph/tsconfig.json | 2 +-
.../public/kibana.jsonc | 8 +-
.../storybook/config/README.mdx | 3 +
.../{graph => }/storybook/config/constants.ts | 0
.../{graph => }/storybook/config/index.ts | 0
.../storybook/config/main.ts | 16 +
.../{graph => }/storybook/config/manager.ts | 0
.../storybook/config/package.json | 6 +
.../{graph => }/storybook/config/preview.ts | 0
.../{graph => }/storybook/config/styles.css | 0
.../storybook/config/tsconfig.json | 20 +
.../common/components/expandable_panel.tsx | 16 +-
.../server/routes/graph/v1.ts | 66 +-
.../cloud_security_posture/tsconfig.json | 1 -
.../security_solution/common/constants.ts | 2 +
.../common/experimental_features.ts | 5 +
.../right/components/graph_preview.test.tsx | 72 +
.../right/components/graph_preview.tsx | 102 +
.../graph_preview_container.test.tsx | 110 +
.../components/graph_preview_container.tsx | 72 +
.../right/components/test_ids.ts | 3 +
.../visualizations_section.test.tsx | 42 +-
.../components/visualizations_section.tsx | 21 +
.../right/hooks/use_fetch_graph_data.ts | 83 +
.../right/hooks/use_graph_preview.test.tsx | 137 +
.../right/hooks/use_graph_preview.ts | 65 +
.../plugins/security_solution/tsconfig.json | 1 +
.../config.ts | 3 +
.../es_archives/logs_gcp_audit/data.json | 634 ++
.../es_archives/logs_gcp_audit/mappings.json | 628 ++
.../es_archives/security_alerts/data.json.gz | Bin 0 -> 3143 bytes
.../es_archives/security_alerts/mappings.json | 8667 +++++++++++++++++
.../page_objects/alerts_page.ts | 107 +
.../page_objects/index.ts | 2 +
.../pages/alerts_flyout.ts | 62 +
.../pages/index.ts | 1 +
70 files changed, 11990 insertions(+), 577 deletions(-)
create mode 100644 x-pack/packages/kbn-cloud-security-posture/graph/setup_tests.ts
create mode 100644 x-pack/packages/kbn-cloud-security-posture/graph/src/components/graph/graph.test.tsx
create mode 100644 x-pack/packages/kbn-cloud-security-posture/graph/src/components/graph/graph.tsx
rename x-pack/packages/kbn-cloud-security-posture/graph/src/components/{dagree_layout_graph.stories.tsx => graph_layout.stories.tsx} (76%)
create mode 100644 x-pack/packages/kbn-cloud-security-posture/graph/src/components/mock/react_flow.ts
create mode 100644 x-pack/packages/kbn-cloud-security-posture/graph/src/components/mock/test_providers.tsx
create mode 100644 x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/shapes/diamond_shape.tsx
create mode 100644 x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/shapes/ellipse_shape.tsx
create mode 100644 x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/shapes/hexagon_shape.tsx
create mode 100644 x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/shapes/pentagon_shape.tsx
create mode 100644 x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/shapes/rectangle_shape.tsx
create mode 100644 x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/shapes/types.ts
delete mode 100644 x-pack/packages/kbn-cloud-security-posture/graph/storybook/config/main.ts
create mode 100644 x-pack/packages/kbn-cloud-security-posture/storybook/config/README.mdx
rename x-pack/packages/kbn-cloud-security-posture/{graph => }/storybook/config/constants.ts (100%)
rename x-pack/packages/kbn-cloud-security-posture/{graph => }/storybook/config/index.ts (100%)
create mode 100644 x-pack/packages/kbn-cloud-security-posture/storybook/config/main.ts
rename x-pack/packages/kbn-cloud-security-posture/{graph => }/storybook/config/manager.ts (100%)
create mode 100644 x-pack/packages/kbn-cloud-security-posture/storybook/config/package.json
rename x-pack/packages/kbn-cloud-security-posture/{graph => }/storybook/config/preview.ts (100%)
rename x-pack/packages/kbn-cloud-security-posture/{graph => }/storybook/config/styles.css (100%)
create mode 100644 x-pack/packages/kbn-cloud-security-posture/storybook/config/tsconfig.json
create mode 100644 x-pack/plugins/security_solution/public/flyout/document_details/right/components/graph_preview.test.tsx
create mode 100644 x-pack/plugins/security_solution/public/flyout/document_details/right/components/graph_preview.tsx
create mode 100644 x-pack/plugins/security_solution/public/flyout/document_details/right/components/graph_preview_container.test.tsx
create mode 100644 x-pack/plugins/security_solution/public/flyout/document_details/right/components/graph_preview_container.tsx
create mode 100644 x-pack/plugins/security_solution/public/flyout/document_details/right/hooks/use_fetch_graph_data.ts
create mode 100644 x-pack/plugins/security_solution/public/flyout/document_details/right/hooks/use_graph_preview.test.tsx
create mode 100644 x-pack/plugins/security_solution/public/flyout/document_details/right/hooks/use_graph_preview.ts
create mode 100644 x-pack/test/cloud_security_posture_functional/es_archives/logs_gcp_audit/data.json
create mode 100644 x-pack/test/cloud_security_posture_functional/es_archives/logs_gcp_audit/mappings.json
create mode 100644 x-pack/test/cloud_security_posture_functional/es_archives/security_alerts/data.json.gz
create mode 100644 x-pack/test/cloud_security_posture_functional/es_archives/security_alerts/mappings.json
create mode 100644 x-pack/test/cloud_security_posture_functional/page_objects/alerts_page.ts
create mode 100644 x-pack/test/cloud_security_posture_functional/pages/alerts_flyout.ts
diff --git a/.buildkite/scripts/steps/storybooks/build_and_upload.ts b/.buildkite/scripts/steps/storybooks/build_and_upload.ts
index 393b89a97acb2..a6bb3f062986a 100644
--- a/.buildkite/scripts/steps/storybooks/build_and_upload.ts
+++ b/.buildkite/scripts/steps/storybooks/build_and_upload.ts
@@ -18,15 +18,16 @@ const STORYBOOKS = [
'canvas',
'cases',
'cell_actions',
- 'coloring',
'chart_icons',
+ 'cloud_security_posture_packages',
+ 'coloring',
'content_management_examples',
'custom_integrations',
'dashboard_enhanced',
'dashboard',
'data',
- 'logs_explorer',
'embeddable',
+ 'esql_editor',
'expression_error',
'expression_image',
'expression_metric',
@@ -34,27 +35,27 @@ const STORYBOOKS = [
'expression_reveal_image',
'expression_shape',
'expression_tagcloud',
- 'management',
'fleet',
'grouping',
'home',
'infra',
'kibana_react',
+ 'language_documentation_popover',
'lists',
- 'observability',
+ 'logs_explorer',
+ 'management',
'observability_ai_assistant',
'observability_shared',
+ 'observability',
'presentation',
- 'security_solution',
+ 'random_sampling',
'security_solution_packages',
+ 'security_solution',
'serverless',
'shared_ux',
'triggers_actions_ui',
'ui_actions_enhanced',
- 'language_documentation_popover',
'unified_search',
- 'random_sampling',
- 'esql_editor',
];
const GITHUB_CONTEXT = 'Build and Publish Storybooks';
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 87b36355bd90e..d9f8f310f330e 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1841,10 +1841,10 @@ x-pack/plugins/osquery @elastic/security-defend-workflows
/x-pack/plugins/security_solution/public/detections/components/osquery @elastic/security-defend-workflows
# Cloud Defend
-/x-pack/plugins/cloud_defend/ @elastic/kibana-cloud-security-posture
/x-pack/plugins/security_solution/public/cloud_defend @elastic/kibana-cloud-security-posture
# Cloud Security Posture
+x-pack/packages/kbn-cloud-security-posture @elastic/kibana-cloud-security-posture
/x-pack/test_serverless/functional/test_suites/security/config.cloud_security_posture.* @elastic/kibana-cloud-security-posture
/x-pack/plugins/security_solution/public/cloud_security_posture @elastic/kibana-cloud-security-posture
/x-pack/test/api_integration/apis/cloud_security_posture/ @elastic/kibana-cloud-security-posture
diff --git a/packages/kbn-optimizer/src/worker/webpack.config.ts b/packages/kbn-optimizer/src/worker/webpack.config.ts
index 52a837724480d..96a17a6ae7229 100644
--- a/packages/kbn-optimizer/src/worker/webpack.config.ts
+++ b/packages/kbn-optimizer/src/worker/webpack.config.ts
@@ -259,6 +259,27 @@ export function getWebpackConfig(
},
},
},
+ {
+ test: /\.js$/,
+ include: /node_modules[\\\/]@dagrejs/,
+ use: {
+ loader: 'babel-loader',
+ options: {
+ envName: worker.dist ? 'production' : 'development',
+ presets: ['@babel/preset-env'], // Doesn't work with BABEL_PRESET
+ plugins: ['@babel/plugin-proposal-class-properties'],
+ },
+ },
+ },
+ {
+ test: /node_modules[\/\\]@?xyflow[\/\\].*.js$/,
+ loaders: 'babel-loader',
+ options: {
+ envName: worker.dist ? 'production' : 'development',
+ presets: [BABEL_PRESET],
+ plugins: ['@babel/plugin-transform-logical-assignment-operators'],
+ },
+ },
{
test: /\.(html|md|txt|tmpl)$/,
use: {
diff --git a/packages/kbn-storybook/src/webpack.config.ts b/packages/kbn-storybook/src/webpack.config.ts
index b03d78dbbc190..fad795a1e4619 100644
--- a/packages/kbn-storybook/src/webpack.config.ts
+++ b/packages/kbn-storybook/src/webpack.config.ts
@@ -136,6 +136,25 @@ export default ({ config: storybookConfig }: { config: Configuration }) => {
},
},
},
+ {
+ test: /\.js$/,
+ include: /node_modules[\\\/]@dagrejs/,
+ use: {
+ loader: 'babel-loader',
+ options: {
+ presets: ['@babel/preset-env'], // Doesn't work with @kbn/babel-preset/webpack_preset
+ plugins: ['@babel/plugin-proposal-class-properties'],
+ },
+ },
+ },
+ {
+ test: /node_modules[\/\\]@?xyflow[\/\\].*.js$/,
+ loaders: 'babel-loader',
+ options: {
+ presets: [require.resolve('@kbn/babel-preset/webpack_preset')],
+ plugins: ['@babel/plugin-transform-logical-assignment-operators'],
+ },
+ },
],
},
plugins: [new IgnoreNotFoundExportPlugin()],
diff --git a/x-pack/packages/kbn-cloud-security-posture/common/kibana.jsonc b/x-pack/packages/kbn-cloud-security-posture/common/kibana.jsonc
index 21721cfb69f44..f3bd18f10c7a8 100644
--- a/x-pack/packages/kbn-cloud-security-posture/common/kibana.jsonc
+++ b/x-pack/packages/kbn-cloud-security-posture/common/kibana.jsonc
@@ -1,6 +1,5 @@
-
{
- "id": "@kbn/cloud-security-posture-common",
- "owner": "@elastic/kibana-cloud-security-posture",
- "type": "shared-common"
- }
\ No newline at end of file
+ "id": "@kbn/cloud-security-posture-common",
+ "owner": "@elastic/kibana-cloud-security-posture",
+ "type": "shared-common"
+}
diff --git a/x-pack/packages/kbn-cloud-security-posture/common/package.json b/x-pack/packages/kbn-cloud-security-posture/common/package.json
index 8ead7b37ceeb6..37276e735987d 100644
--- a/x-pack/packages/kbn-cloud-security-posture/common/package.json
+++ b/x-pack/packages/kbn-cloud-security-posture/common/package.json
@@ -1,8 +1,8 @@
{
- "name": "@kbn/cloud-security-posture-common",
- "private": true,
- "version": "1.0.0",
- "license": "Elastic License 2.0",
- "description": "Shared components for cloud security posture, both client and server side",
- "sideEffects": false
- }
\ No newline at end of file
+ "name": "@kbn/cloud-security-posture-common",
+ "private": true,
+ "version": "1.0.0",
+ "license": "Elastic License 2.0",
+ "description": "Shared components for cloud security posture, both client and server side",
+ "sideEffects": false
+}
diff --git a/x-pack/packages/kbn-cloud-security-posture/common/schema/graph/v1.ts b/x-pack/packages/kbn-cloud-security-posture/common/schema/graph/v1.ts
index f27ddb397c57c..3d37331b4cc5d 100644
--- a/x-pack/packages/kbn-cloud-security-posture/common/schema/graph/v1.ts
+++ b/x-pack/packages/kbn-cloud-security-posture/common/schema/graph/v1.ts
@@ -71,8 +71,6 @@ export const groupNodeDataSchema = schema.allOf([
export const labelNodeDataSchema = schema.allOf([
nodeBaseDataSchema,
schema.object({
- source: schema.string(),
- target: schema.string(),
shape: schema.literal('label'),
parentId: schema.maybe(schema.string()),
color: colorSchema,
@@ -82,8 +80,6 @@ export const labelNodeDataSchema = schema.allOf([
export const edgeDataSchema = schema.object({
id: schema.string(),
source: schema.string(),
- sourceShape: nodeShapeSchema,
target: schema.string(),
- targetShape: nodeShapeSchema,
color: colorSchema,
});
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/README.md b/x-pack/packages/kbn-cloud-security-posture/graph/README.md
index c67ca622fe414..bde99acb4e7a6 100644
--- a/x-pack/packages/kbn-cloud-security-posture/graph/README.md
+++ b/x-pack/packages/kbn-cloud-security-posture/graph/README.md
@@ -7,11 +7,104 @@ security solution plugin.
## How to use this
-Standalone examples will follow. In the meantime check out storybook to view the graph's progress.
+### Step 1: Import the Component
-## The most important public api members
+First, import the `Graph` component into your desired file.
-- GraphComponent itself (comming soon..)
+```tsx
+import { Graph } from '@kbn/cloud-security-posture-graph';
+```
+
+### Step 2: Prepare the Data
+
+Create the nodes and edges data models. These should follow the `NodeViewModel` and `EdgeViewModel` interfaces.
+
+```tsx
+const nodes: NodeViewModel[] = [
+ {
+ id: 'node1',
+ label: 'Node 1',
+ color: 'primary',
+ shape: 'ellipse',
+ icon: 'user',
+ },
+ {
+ id: 'node2',
+ label: 'Node 2',
+ color: 'primary',
+ shape: 'hexagon',
+ icon: 'questionInCircle',
+ },
+];
+
+const edges: EdgeViewModel[] = [
+ {
+ id: 'edge1',
+ source: 'node1',
+ target: 'node2',
+ color: 'primary',
+ },
+];
+```
+
+### Step 3: Render the Component
+
+Use the `Graph` component in your JSX/TSX, passing the nodes, edges, and interactivity flag as props.
+
+```tsx
+
+```
+
+### Example Usage
+
+Here is a complete example of how to use the `Graph` component in a React component.
+
+```tsx
+import React from 'react';
+import { Graph } from '@kbn/cloud-security-posture-graph';
+import type { NodeViewModel, EdgeViewModel } from '@kbn/cloud-security-posture-graph';
+
+const App: React.FC = () => {
+ const nodes: NodeViewModel[] = [
+ {
+ id: 'node1',
+ label: 'Node 1',
+ color: 'primary',
+ shape: 'ellipse',
+ icon: 'user',
+ },
+ {
+ id: 'node2',
+ label: 'Node 2',
+ color: 'primary',
+ shape: 'hexagon',
+ icon: 'questionInCircle',
+ },
+ ];
+
+ const edges: EdgeViewModel[] = [
+ {
+ id: 'edge1',
+ source: 'node1',
+ target: 'node2',
+ color: 'primary',
+ },
+ ];
+
+ return (
+
+
Graph Visualization
+
+
+ );
+};
+
+export default App;
+```
+
+### Storybook Example
+
+You can also see how the `Graph` component is used in the Storybook file `graph_layout.stories.tsx`.
### Extras
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/index.ts b/x-pack/packages/kbn-cloud-security-posture/graph/index.ts
index 1fec1c76430eb..c50969cfd6402 100644
--- a/x-pack/packages/kbn-cloud-security-posture/graph/index.ts
+++ b/x-pack/packages/kbn-cloud-security-posture/graph/index.ts
@@ -4,3 +4,5 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
+
+export * from './src/components';
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/jest.config.js b/x-pack/packages/kbn-cloud-security-posture/graph/jest.config.js
index 9e295d0f4d626..3b8fbbd9384a4 100644
--- a/x-pack/packages/kbn-cloud-security-posture/graph/jest.config.js
+++ b/x-pack/packages/kbn-cloud-security-posture/graph/jest.config.js
@@ -9,4 +9,6 @@ module.exports = {
preset: '@kbn/test',
roots: ['/x-pack/packages/kbn-cloud-security-posture/graph'],
rootDir: '../../../..',
+ setupFiles: ['jest-canvas-mock'],
+ setupFilesAfterEnv: ['/x-pack/packages/kbn-cloud-security-posture/graph/setup_tests.ts'],
};
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/kibana.jsonc b/x-pack/packages/kbn-cloud-security-posture/graph/kibana.jsonc
index 455f1607a22a2..513861b347059 100644
--- a/x-pack/packages/kbn-cloud-security-posture/graph/kibana.jsonc
+++ b/x-pack/packages/kbn-cloud-security-posture/graph/kibana.jsonc
@@ -1,5 +1,5 @@
{
- "type": "shared-browser",
"id": "@kbn/cloud-security-posture-graph",
- "owner": "@elastic/kibana-cloud-security-posture"
+ "owner": "@elastic/kibana-cloud-security-posture",
+ "type": "shared-browser"
}
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/setup_tests.ts b/x-pack/packages/kbn-cloud-security-posture/graph/setup_tests.ts
new file mode 100644
index 0000000000000..7f6858c0fd40d
--- /dev/null
+++ b/x-pack/packages/kbn-cloud-security-posture/graph/setup_tests.ts
@@ -0,0 +1,13 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+// eslint-disable-next-line @kbn/imports/no_boundary_crossing
+import { mockReactFlow } from './src/components/mock/react_flow';
+// eslint-disable-next-line import/no-extraneous-dependencies
+import '@testing-library/jest-dom';
+
+mockReactFlow();
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/graph/graph.test.tsx b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/graph/graph.test.tsx
new file mode 100644
index 0000000000000..18ba84207f962
--- /dev/null
+++ b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/graph/graph.test.tsx
@@ -0,0 +1,110 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { render } from '@testing-library/react';
+import React from 'react';
+import { Graph, type GraphProps } from './graph';
+import { TestProviders } from '../mock/test_providers';
+
+const renderGraphPreview = (props: GraphProps) =>
+ render(
+
+
+
+ );
+
+describe('', () => {
+ it('should render empty graph', () => {
+ const { container } = renderGraphPreview({
+ nodes: [],
+ edges: [],
+ interactive: false,
+ });
+
+ expect(container).not.toBeNull();
+ const nodes = container.querySelectorAll('.react-flow__nodes .react-flow__node');
+ expect(nodes).toHaveLength(0);
+ });
+
+ it('should render hexagon node', () => {
+ const { container } = renderGraphPreview({
+ nodes: [
+ {
+ id: '1',
+ label: 'Node 1',
+ color: 'primary',
+ shape: 'hexagon',
+ },
+ ],
+ edges: [],
+ interactive: false,
+ });
+
+ const nodeEl = container.querySelector('[data-id="1"]');
+ expect(nodeEl).not.toBeNull();
+ expect(nodeEl?.textContent).toBe('Node 1');
+ });
+
+ it('should render label node', () => {
+ const { container } = renderGraphPreview({
+ nodes: [
+ {
+ id: '2',
+ label: 'Node 2',
+ color: 'primary',
+ shape: 'label',
+ },
+ ],
+ edges: [],
+ interactive: false,
+ });
+
+ const nodeEl = container.querySelector('[data-id="2"]');
+ expect(nodeEl).not.toBeNull();
+ expect(nodeEl?.textContent).toBe('Node 2');
+ });
+
+ it('should render 2 nodes connected', () => {
+ const { container } = renderGraphPreview({
+ nodes: [
+ {
+ id: '1',
+ label: 'Node 1',
+ color: 'primary',
+ shape: 'hexagon',
+ },
+ {
+ id: '2',
+ label: 'Node 2',
+ color: 'primary',
+ shape: 'label',
+ },
+ ],
+ edges: [
+ {
+ id: 'a(1)-b(2)',
+ color: 'primary',
+ source: '1',
+ target: '2',
+ },
+ ],
+ interactive: false,
+ });
+
+ const srcNodeEl = container.querySelector('[data-id="1"]');
+ expect(srcNodeEl).not.toBeNull();
+ expect(srcNodeEl?.textContent).toBe('Node 1');
+
+ const targetNodeEl = container.querySelector('[data-id="2"]');
+ expect(targetNodeEl).not.toBeNull();
+ expect(targetNodeEl?.textContent).toBe('Node 2');
+
+ // TODO: Fix this test (currently it is not rendered in xyflow version 12) https://github.com/xyflow/xyflow/issues/716#issuecomment-2414721074
+ // const edgeEl = container.querySelector('[data-id="a(1)-b(2)"]');
+ // expect(edgeEl).not.toBeNull();
+ });
+});
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/graph/graph.tsx b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/graph/graph.tsx
new file mode 100644
index 0000000000000..eca9872d73897
--- /dev/null
+++ b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/graph/graph.tsx
@@ -0,0 +1,204 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import React, { useMemo, useRef, useState, useCallback } from 'react';
+import {
+ Background,
+ Controls,
+ Position,
+ ReactFlow,
+ useEdgesState,
+ useNodesState,
+} from '@xyflow/react';
+import type { Edge, Node } from '@xyflow/react';
+import type { CommonProps } from '@elastic/eui';
+import { SvgDefsMarker } from '../edge/styles';
+import {
+ HexagonNode,
+ PentagonNode,
+ EllipseNode,
+ RectangleNode,
+ DiamondNode,
+ LabelNode,
+ EdgeGroupNode,
+} from '../node';
+import { layoutGraph } from './layout_graph';
+import { DefaultEdge } from '../edge';
+import type { EdgeViewModel, NodeViewModel } from '../types';
+
+import '@xyflow/react/dist/style.css';
+
+export interface GraphProps extends CommonProps {
+ nodes: NodeViewModel[];
+ edges: EdgeViewModel[];
+ interactive: boolean;
+}
+
+const nodeTypes = {
+ hexagon: HexagonNode,
+ pentagon: PentagonNode,
+ ellipse: EllipseNode,
+ rectangle: RectangleNode,
+ diamond: DiamondNode,
+ label: LabelNode,
+ group: EdgeGroupNode,
+};
+
+const edgeTypes = {
+ default: DefaultEdge,
+};
+
+/**
+ * Graph component renders a graph visualization using ReactFlow.
+ * It takes nodes and edges as input and provides interactive controls
+ * for panning, zooming, and manipulating the graph.
+ *
+ * @component
+ * @param {GraphProps} props - The properties for the Graph component.
+ * @param {NodeViewModel[]} props.nodes - Array of node view models to be rendered in the graph.
+ * @param {EdgeViewModel[]} props.edges - Array of edge view models to be rendered in the graph.
+ * @param {boolean} props.interactive - Flag to enable or disable interactivity (panning, zooming, etc.).
+ * @param {CommonProps} [props.rest] - Additional common properties.
+ *
+ * @returns {JSX.Element} The rendered Graph component.
+ */
+export const Graph: React.FC = ({ nodes, edges, interactive, ...rest }) => {
+ const layoutCalled = useRef(false);
+ const [isGraphLocked, setIsGraphLocked] = useState(interactive);
+ const { initialNodes, initialEdges } = useMemo(
+ () => processGraph(nodes, edges, isGraphLocked),
+ [nodes, edges, isGraphLocked]
+ );
+
+ const [nodesState, setNodes, onNodesChange] = useNodesState(initialNodes);
+ const [edgesState, _setEdges, onEdgesChange] = useEdgesState(initialEdges);
+
+ if (!layoutCalled.current) {
+ const { nodes: layoutedNodes } = layoutGraph(nodesState, edgesState);
+ setNodes(layoutedNodes);
+ layoutCalled.current = true;
+ }
+
+ const onInteractiveStateChange = useCallback(
+ (interactiveStatus: boolean): void => {
+ setIsGraphLocked(interactiveStatus);
+ setNodes((prevNodes) =>
+ prevNodes.map((node) => ({
+ ...node,
+ data: {
+ ...node.data,
+ interactive: interactiveStatus,
+ },
+ }))
+ );
+ },
+ [setNodes]
+ );
+
+ return (
+
+
+ {
+ window.requestAnimationFrame(() => xyflow.fitView());
+
+ // When the graph is not initialized as interactive, we need to fit the view on resize
+ if (!interactive) {
+ const resizeObserver = new ResizeObserver(() => {
+ xyflow.fitView();
+ });
+ resizeObserver.observe(document.querySelector('.react-flow') as Element);
+ return () => resizeObserver.disconnect();
+ }
+ }}
+ nodeTypes={nodeTypes}
+ edgeTypes={edgeTypes}
+ nodes={nodesState}
+ edges={edgesState}
+ onNodesChange={onNodesChange}
+ onEdgesChange={onEdgesChange}
+ proOptions={{ hideAttribution: true }}
+ panOnDrag={isGraphLocked}
+ zoomOnScroll={isGraphLocked}
+ zoomOnPinch={isGraphLocked}
+ zoomOnDoubleClick={isGraphLocked}
+ preventScrolling={isGraphLocked}
+ nodesDraggable={interactive && isGraphLocked}
+ maxZoom={1.3}
+ >
+ {interactive && }
+
+
+
+ );
+};
+
+const processGraph = (
+ nodesModel: NodeViewModel[],
+ edgesModel: EdgeViewModel[],
+ interactive: boolean
+): {
+ initialNodes: Array>;
+ initialEdges: Array>;
+} => {
+ const nodesById: { [key: string]: NodeViewModel } = {};
+
+ const initialNodes = nodesModel.map((nodeData) => {
+ nodesById[nodeData.id] = nodeData;
+
+ const node: Node = {
+ id: nodeData.id,
+ type: nodeData.shape,
+ data: { ...nodeData, interactive },
+ position: { x: 0, y: 0 }, // Default position, should be updated later
+ };
+
+ if (node.type === 'group' && nodeData.shape === 'group') {
+ node.sourcePosition = Position.Right;
+ node.targetPosition = Position.Left;
+ node.resizing = false;
+ node.focusable = false;
+ } else if (nodeData.shape === 'label' && nodeData.parentId) {
+ node.parentId = nodeData.parentId;
+ node.extent = 'parent';
+ node.expandParent = false;
+ node.draggable = false;
+ }
+
+ return node;
+ });
+
+ const initialEdges: Array> = edgesModel.map((edgeData) => {
+ const isIn =
+ nodesById[edgeData.source].shape !== 'label' && nodesById[edgeData.target].shape === 'group';
+ const isInside =
+ nodesById[edgeData.source].shape === 'group' && nodesById[edgeData.target].shape === 'label';
+ const isOut =
+ nodesById[edgeData.source].shape === 'label' && nodesById[edgeData.target].shape === 'group';
+ const isOutside =
+ nodesById[edgeData.source].shape === 'group' && nodesById[edgeData.target].shape !== 'label';
+
+ return {
+ id: edgeData.id,
+ type: 'default',
+ source: edgeData.source,
+ sourceHandle: isInside ? 'inside' : isOutside ? 'outside' : undefined,
+ target: edgeData.target,
+ targetHandle: isIn ? 'in' : isOut ? 'out' : undefined,
+ focusable: false,
+ selectable: false,
+ data: {
+ ...edgeData,
+ sourceShape: nodesById[edgeData.source].shape,
+ targetShape: nodesById[edgeData.target].shape,
+ },
+ };
+ });
+
+ return { initialNodes, initialEdges };
+};
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/graph/layout_graph.ts b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/graph/layout_graph.ts
index d9f637483c115..868461f99cdee 100644
--- a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/graph/layout_graph.ts
+++ b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/graph/layout_graph.ts
@@ -6,18 +6,16 @@
*/
import Dagre from '@dagrejs/dagre';
-import type {
- EdgeDataModel,
- NodeDataModel,
-} from '@kbn/cloud-security-posture-common/types/graph/latest';
-import type { NodeViewModel, Size } from '../types';
+import type { Node, Edge } from '@xyflow/react';
+import type { EdgeViewModel, NodeViewModel, Size } from '../types';
import { calcLabelSize } from './utils';
+import { GroupStyleOverride, NODE_HEIGHT, NODE_WIDTH } from '../node/styles';
export const layoutGraph = (
- nodes: NodeDataModel[],
- edges: EdgeDataModel[]
-): { nodes: NodeViewModel[] } => {
- const nodesById: { [key: string]: NodeViewModel } = {};
+ nodes: Array>,
+ edges: Array>
+): { nodes: Array> } => {
+ const nodesById: { [key: string]: Node } = {};
const graphOpts = {
compound: true,
};
@@ -29,28 +27,27 @@ export const layoutGraph = (
edges.forEach((edge) => g.setEdge(edge.source, edge.target));
nodes.forEach((node) => {
- let size = { width: 90, height: 90 };
- const position = { x: 0, y: 0 };
+ let size = { width: NODE_WIDTH, height: node.measured?.height ?? NODE_HEIGHT };
- if (node.shape === 'label') {
- size = calcLabelSize(node.label);
+ if (node.data.shape === 'label') {
+ size = calcLabelSize(node.data.label);
// TODO: waiting for a fix: https://github.com/dagrejs/dagre/issues/238
// if (node.parentId) {
// g.setParent(node.id, node.parentId);
// }
- } else if (node.shape === 'group') {
+ } else if (node.data.shape === 'group') {
const res = layoutGroupChildren(node, nodes);
size = res.size;
res.children.forEach((child) => {
- nodesById[child.id] = { ...child };
+ nodesById[child.data.id] = child;
});
}
if (!nodesById[node.id]) {
- nodesById[node.id] = { ...node, position };
+ nodesById[node.id] = node;
}
g.setNode(node.id, {
@@ -61,8 +58,8 @@ export const layoutGraph = (
Dagre.layout(g);
- const nodesViewModel: NodeViewModel[] = nodes.map((nodeData) => {
- const dagreNode = g.node(nodeData.id);
+ const layoutedNodes = nodes.map((node) => {
+ const dagreNode = g.node(node.data.id);
// We are shifting the dagre node position (anchor=center center) to the top left
// so it matches the React Flow node anchor point (top left).
@@ -70,37 +67,43 @@ export const layoutGraph = (
const y = dagreNode.y - (dagreNode.height ?? 0) / 2;
// For grouped nodes, we want to keep the original position relative to the parent
- if (nodeData.shape === 'label' && nodeData.parentId) {
+ if (node.data.shape === 'label' && node.data.parentId) {
return {
- ...nodeData,
- position: nodesById[nodeData.id].position,
+ ...node,
+ position: nodesById[node.data.id].position,
};
- } else if (nodeData.shape === 'group') {
+ } else if (node.data.shape === 'group') {
return {
- ...nodeData,
+ ...node,
position: { x, y },
- size: {
+ style: GroupStyleOverride({
width: dagreNode.width,
height: dagreNode.height,
- },
+ }),
+ };
+ } else if (node.data.shape === 'label') {
+ return {
+ ...node,
+ position: { x, y },
+ };
+ } else {
+ // Align nodes to labels by shifting the node position by it's label height
+ return {
+ ...node,
+ position: { x, y: y + (dagreNode.height - NODE_HEIGHT) / 2 },
};
}
-
- return {
- ...nodeData,
- position: { x, y },
- };
});
- return { nodes: nodesViewModel };
+ return { nodes: layoutedNodes };
};
const layoutGroupChildren = (
- groupNode: NodeDataModel,
- nodes: NodeDataModel[]
-): { size: Size; children: NodeViewModel[] } => {
+ groupNode: Node,
+ nodes: Array>
+): { size: Size; children: Array> } => {
const children = nodes.filter(
- (child) => child.shape === 'label' && child.parentId === groupNode.id
+ (child) => child.data.shape === 'label' && child.parentId === groupNode.id
);
const STACK_VERTICAL_PADDING = 20;
@@ -108,7 +111,7 @@ const layoutGroupChildren = (
const PADDING = 20;
const stackSize = children.length;
const allChildrenHeight = children.reduce(
- (prevHeight, node) => prevHeight + calcLabelSize(node.label).height,
+ (prevHeight, node) => prevHeight + calcLabelSize(node.data.label).height,
0
);
const stackHeight = Math.max(
@@ -118,23 +121,21 @@ const layoutGroupChildren = (
const space = (stackHeight - allChildrenHeight) / (stackSize - 1);
const groupNodeWidth = children.reduce((acc, child) => {
- const currLblWidth = PADDING * 2 + calcLabelSize(child.label).width;
+ const currLblWidth = PADDING * 2 + calcLabelSize(child.data.label).width;
return Math.max(acc, currLblWidth);
}, 0);
// Layout children relative to parent
- const positionedChildren: NodeViewModel[] = children.map((child, index) => {
- const childSize = calcLabelSize(child.label);
- const childPosition = {
+ children.forEach((child, index) => {
+ const childSize = calcLabelSize(child.data.label);
+ child.position = {
x: groupNodeWidth / 2 - childSize.width / 2,
y: index * (childSize.height * 2 + space),
};
-
- return { ...child, position: childPosition };
});
return {
size: { width: groupNodeWidth, height: stackHeight },
- children: positionedChildren,
+ children,
};
};
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/dagree_layout_graph.stories.tsx b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/graph_layout.stories.tsx
similarity index 76%
rename from x-pack/packages/kbn-cloud-security-posture/graph/src/components/dagree_layout_graph.stories.tsx
rename to x-pack/packages/kbn-cloud-security-posture/graph/src/components/graph_layout.stories.tsx
index 94bc7e8af353b..140e81238d390 100644
--- a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/dagree_layout_graph.stories.tsx
+++ b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/graph_layout.stories.tsx
@@ -7,68 +7,40 @@
import React from 'react';
import { ThemeProvider } from '@emotion/react';
-import {
- ReactFlow,
- Controls,
- Background,
- Node,
- Edge,
- Position,
- useNodesState,
- useEdgesState,
-} from '@xyflow/react';
import { Story } from '@storybook/react';
-import type {
- EdgeDataModel,
- LabelNodeDataModel,
- NodeDataModel,
-} from '@kbn/cloud-security-posture-common/types/graph/latest';
import { Writable } from '@kbn/utility-types';
-import {
- HexagonNode,
- PentagonNode,
- EllipseNode,
- RectangleNode,
- DiamondNode,
- LabelNode,
- EdgeGroupNode,
-} from './node';
-import type { NodeViewModel } from './types';
-import { DefaultEdge } from './edge';
-import { SvgDefsMarker } from './edge/styles';
-import { GroupStyleOverride } from './node/styles';
-
-import '@xyflow/react/dist/style.css';
-import { layoutGraph } from './graph/layout_graph';
+import { css } from '@emotion/react';
+import type {
+ EdgeViewModel,
+ LabelNodeViewModel,
+ NodeViewModel,
+ EntityNodeViewModel,
+ GroupNodeViewModel,
+} from '.';
+import { Graph } from '.';
export default {
- title: 'Components/Graph Components/Dagree Layout Graph',
+ title: 'Components/Graph Components/Graph Layout',
description: 'CDR - Graph visualization',
-};
-
-const nodeTypes = {
- hexagon: HexagonNode,
- pentagon: PentagonNode,
- ellipse: EllipseNode,
- rectangle: RectangleNode,
- diamond: DiamondNode,
- label: LabelNode,
- group: EdgeGroupNode,
-};
-
-const edgeTypes = {
- default: DefaultEdge,
+ argTypes: {
+ interactive: { control: 'boolean', defaultValue: true },
+ },
};
interface GraphData {
- nodes: NodeDataModel[];
- edges: EdgeDataModel[];
+ nodes: NodeViewModel[];
+ edges: EdgeViewModel[];
interactive: boolean;
}
+type EnhancedNodeViewModel =
+ | EntityNodeViewModel
+ | GroupNodeViewModel
+ | (LabelNodeViewModel & { source: string; target: string });
+
const extractEdges = (
- graphData: NodeDataModel[]
-): { nodes: NodeDataModel[]; edges: EdgeDataModel[] } => {
+ graphData: EnhancedNodeViewModel[]
+): { nodes: NodeViewModel[]; edges: EdgeViewModel[] } => {
// Process nodes, transform nodes of id in the format of a(source)-b(target) to edges from a to label and from label to b
// If there are multiple edges from a to b, create a parent node and group the labels under it. The parent node will be a group node.
// Connect from a to the group node and from the group node to all the labels. and from the labels to the group again and from the group to b.
@@ -77,14 +49,14 @@ const extractEdges = (
[key: string]: { source: string; target: string; edgesStacked: number; edges: string[] };
} = {};
const labelsMetadata: {
- [key: string]: { source: string; target: string; labelsNodes: LabelNodeDataModel[] };
+ [key: string]: { source: string; target: string; labelsNodes: LabelNodeViewModel[] };
} = {};
- const nodes: { [key: string]: NodeDataModel } = {};
- const edges: EdgeDataModel[] = [];
+ const nodes: { [key: string]: NodeViewModel } = {};
+ const edges: EdgeViewModel[] = [];
graphData.forEach((node) => {
if (node.shape === 'label') {
- const labelNode = { ...node, id: `${node.id}label(${node.label})` };
+ const labelNode: LabelNodeViewModel = { ...node, id: `${node.id}label(${node.label})` };
const { source, target } = node;
if (labelsMetadata[node.id]) {
@@ -119,7 +91,7 @@ const extractEdges = (
Object.values(labelsMetadata).forEach((edge) => {
if (edge.labelsNodes.length > 1) {
- const groupNode: NodeDataModel = {
+ const groupNode: NodeViewModel = {
id: `grp(a(${edge.source})-b(${edge.target}))`,
shape: 'group',
};
@@ -143,7 +115,7 @@ const extractEdges = (
color: edge.labelsNodes[0].color,
});
- edge.labelsNodes.forEach((labelNode: Writable) => {
+ edge.labelsNodes.forEach((labelNode: Writable) => {
labelNode.parentId = groupNode.id;
edges.push({
@@ -189,28 +161,18 @@ const extractEdges = (
return { nodes: Object.values(nodes).reverse(), edges };
};
-const Template: Story = ({ nodes, edges }: GraphData) => {
- const { initialNodes, initialEdges } = processGraph(nodes, edges);
-
- const [nodesState, _setNodes, onNodesChange] = useNodesState(initialNodes);
- const [edgesState, _setEdges, onEdgesChange] = useEdgesState(initialEdges);
-
+const Template: Story = ({ nodes, edges, interactive }: GraphData) => {
return (
-
-
-
-
-
+
);
};
@@ -359,8 +321,8 @@ GroupWithWarningAPIMock.args = {
],
};
-export const Graph = Template.bind({});
-const baseGraph: NodeDataModel[] = [
+export const LargeGraph = Template.bind({});
+const baseGraph: EnhancedNodeViewModel[] = [
{
id: 'siem-windows',
label: '',
@@ -483,7 +445,7 @@ const baseGraph: NodeDataModel[] = [
},
];
-Graph.args = {
+LargeGraph.args = {
...extractEdges(baseGraph),
};
@@ -541,67 +503,3 @@ GraphStackedEdgeCases.args = {
},
]),
};
-
-function processGraph(
- nodesModel: NodeDataModel[],
- edgesModel: EdgeDataModel[]
-): {
- initialNodes: Node[];
- initialEdges: Edge[];
-} {
- const { nodes: nodesViewModel } = layoutGraph(nodesModel, edgesModel);
-
- const nodesById: { [key: string]: NodeViewModel } = {};
-
- const initialNodes = nodesViewModel.map((nodeData) => {
- nodesById[nodeData.id] = nodeData;
-
- const node: Node = {
- id: nodeData.id,
- type: nodeData.shape,
- data: { ...nodeData, interactive: true },
- position: nodeData.position,
- draggable: true,
- };
-
- if (node.type === 'group' && nodeData.shape === 'group') {
- node.sourcePosition = Position.Right;
- node.targetPosition = Position.Left;
- node.resizing = false;
- node.style = GroupStyleOverride({
- width: nodeData.size?.width ?? 0,
- height: nodeData.size?.height ?? 0,
- });
- } else if (nodeData.shape === 'label' && nodeData.parentId) {
- node.parentId = nodeData.parentId;
- node.extent = 'parent';
- node.expandParent = false;
- node.draggable = false;
- }
-
- return node;
- });
-
- const initialEdges: Edge[] = edgesModel.map((edgeData) => {
- const isIn =
- nodesById[edgeData.source].shape !== 'label' && nodesById[edgeData.target].shape === 'group';
- const isInside =
- nodesById[edgeData.source].shape === 'group' && nodesById[edgeData.target].shape === 'label';
- const isOut =
- nodesById[edgeData.source].shape === 'label' && nodesById[edgeData.target].shape === 'group';
- const isOutside =
- nodesById[edgeData.source].shape === 'group' && nodesById[edgeData.target].shape !== 'label';
-
- return {
- id: edgeData.id,
- type: 'default',
- source: edgeData.source,
- sourceHandle: isInside ? 'inside' : isOutside ? 'outside' : undefined,
- target: edgeData.target,
- targetHandle: isIn ? 'in' : isOut ? 'out' : undefined,
- data: { ...edgeData },
- };
- });
-
- return { initialNodes, initialEdges };
-}
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/index.ts b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/index.ts
index 1fec1c76430eb..5b2f8d71323bb 100644
--- a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/index.ts
+++ b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/index.ts
@@ -4,3 +4,14 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
+
+export { Graph } from './graph/graph';
+export type { GraphProps } from './graph/graph';
+export type {
+ NodeViewModel,
+ EdgeViewModel,
+ GroupNodeViewModel,
+ LabelNodeViewModel,
+ EntityNodeViewModel,
+ NodeProps,
+} from './types';
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/mock/react_flow.ts b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/mock/react_flow.ts
new file mode 100644
index 0000000000000..35282dedcc6de
--- /dev/null
+++ b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/mock/react_flow.ts
@@ -0,0 +1,69 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+/* eslint-disable max-classes-per-file */
+
+// Copied from https://reactflow.dev/learn/advanced-use/testing#using-jest
+
+// To make sure that the tests are working, it's important that you are using
+// this implementation of ResizeObserver and DOMMatrixReadOnly
+class ResizeObserver {
+ callback: globalThis.ResizeObserverCallback;
+
+ constructor(callback: globalThis.ResizeObserverCallback) {
+ this.callback = callback;
+ }
+
+ observe(target: Element) {
+ this.callback([{ target } as globalThis.ResizeObserverEntry], this);
+ }
+
+ unobserve() {}
+
+ disconnect() {}
+}
+
+class DOMMatrixReadOnly {
+ m22: number;
+ constructor(transform: string) {
+ const scale = transform?.match(/scale\(([1-9.])\)/)?.[1];
+ this.m22 = scale !== undefined ? +scale : 1;
+ }
+}
+
+// Only run the shim once when requested
+let init = false;
+
+export const mockReactFlow = () => {
+ if (init) return;
+ init = true;
+
+ global.ResizeObserver = ResizeObserver;
+
+ // @ts-ignore
+ global.DOMMatrixReadOnly = DOMMatrixReadOnly;
+
+ Object.defineProperties(global.HTMLElement.prototype, {
+ offsetHeight: {
+ get() {
+ return parseFloat(this.style.height) || 1;
+ },
+ },
+ offsetWidth: {
+ get() {
+ return parseFloat(this.style.width) || 1;
+ },
+ },
+ });
+
+ (global.SVGElement as any).prototype.getBBox = () => ({
+ x: 0,
+ y: 0,
+ width: 0,
+ height: 0,
+ });
+};
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/mock/test_providers.tsx b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/mock/test_providers.tsx
new file mode 100644
index 0000000000000..3d07c1c6037ed
--- /dev/null
+++ b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/mock/test_providers.tsx
@@ -0,0 +1,23 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import React from 'react';
+import { euiDarkVars } from '@kbn/ui-theme';
+import { ThemeProvider } from '@emotion/react';
+
+interface Props {
+ children?: React.ReactNode;
+}
+
+/** A utility for wrapping children in the providers required to run most tests */
+export const TestProvidersComponent: React.FC = ({ children }) => {
+ return (
+ ({ eui: euiDarkVars, darkMode: true })}>{children}
+ );
+};
+
+export const TestProviders = React.memo(TestProvidersComponent);
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/button.stories.tsx b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/button.stories.tsx
index 5e6e4cd37b432..4a034c05ee166 100644
--- a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/button.stories.tsx
+++ b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/button.stories.tsx
@@ -8,7 +8,7 @@
import React from 'react';
import { ThemeProvider } from '@emotion/react';
import { Story } from '@storybook/react';
-import { NodeButton, type NodeButtonProps, NodeContainer } from './styles';
+import { NodeButton, type NodeButtonProps, NodeShapeContainer } from './styles';
export default {
title: 'Components/Graph Components',
@@ -20,10 +20,10 @@ export default {
const Template: Story = (args) => (
-
+
Hover me
-
+
);
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/diamond_node.tsx b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/diamond_node.tsx
index 76e7a3cd9eeeb..f96068061a433 100644
--- a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/diamond_node.tsx
+++ b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/diamond_node.tsx
@@ -10,7 +10,7 @@ import { useEuiBackgroundColor, useEuiTheme } from '@elastic/eui';
import { Handle, Position } from '@xyflow/react';
import type { EntityNodeViewModel, NodeProps } from '../types';
import {
- NodeContainer,
+ NodeShapeContainer,
NodeLabel,
NodeShapeOnHoverSvg,
NodeShapeSvg,
@@ -18,6 +18,7 @@ import {
NodeButton,
HandleStyleOverride,
} from './styles';
+import { DiamondHoverShape, DiamondShape } from './shapes/diamond_shape';
const NODE_WIDTH = 99;
const NODE_HEIGHT = 98;
@@ -27,59 +28,55 @@ export const DiamondNode: React.FC = memo((props: NodeProps) => {
props.data as EntityNodeViewModel;
const { euiTheme } = useEuiTheme();
return (
-
- {interactive && (
-
+
+ {interactive && (
+
+
+
+ )}
+
-
-
- )}
-
- }
+
+ {interactive && (
+ expandButtonClick?.(e, props)}
+ x={`${NODE_WIDTH - NodeButton.ExpandButtonSize}px`}
+ y={`${(NODE_HEIGHT - NodeButton.ExpandButtonSize) / 2 - 4}px`}
+ />
+ )}
+
- {icon && }
-
- {interactive && (
- expandButtonClick?.(e, props)}
- x={`${NODE_WIDTH - NodeButton.ExpandButtonSize}px`}
- y={`${(NODE_HEIGHT - NodeButton.ExpandButtonSize) / 2 - 4}px`}
+
- )}
-
-
+
{Boolean(label) ? label : id}
-
+ >
);
});
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/ellipse_node.tsx b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/ellipse_node.tsx
index 3359905196b9d..987b9d7577812 100644
--- a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/ellipse_node.tsx
+++ b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/ellipse_node.tsx
@@ -9,7 +9,7 @@ import React, { memo } from 'react';
import { useEuiBackgroundColor, useEuiTheme } from '@elastic/eui';
import { Handle, Position } from '@xyflow/react';
import {
- NodeContainer,
+ NodeShapeContainer,
NodeLabel,
NodeShapeOnHoverSvg,
NodeShapeSvg,
@@ -18,6 +18,7 @@ import {
HandleStyleOverride,
} from './styles';
import type { EntityNodeViewModel, NodeProps } from '../types';
+import { EllipseHoverShape, EllipseShape } from './shapes/ellipse_shape';
const NODE_WIDTH = 90;
const NODE_HEIGHT = 90;
@@ -27,63 +28,55 @@ export const EllipseNode: React.FC = memo((props: NodeProps) => {
props.data as EntityNodeViewModel;
const { euiTheme } = useEuiTheme();
return (
-
- {interactive && (
-
+
+ {interactive && (
+
+
+
+ )}
+
-
-
- )}
-
- }
+
+ {interactive && (
+ expandButtonClick?.(e, props)}
+ x={`${NODE_WIDTH - NodeButton.ExpandButtonSize / 2}px`}
+ y={`${(NODE_HEIGHT - NodeButton.ExpandButtonSize) / 2}px`}
+ />
+ )}
+
- {icon && }
-
- {interactive && (
- expandButtonClick?.(e, props)}
- x={`${NODE_WIDTH - NodeButton.ExpandButtonSize / 2}px`}
- y={`${(NODE_HEIGHT - NodeButton.ExpandButtonSize) / 2}px`}
+
- )}
-
-
+
{Boolean(label) ? label : id}
-
+ >
);
});
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/hexagon_node.tsx b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/hexagon_node.tsx
index dee8df697c844..0bd8c33fc6484 100644
--- a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/hexagon_node.tsx
+++ b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/hexagon_node.tsx
@@ -9,7 +9,7 @@ import React, { memo } from 'react';
import { useEuiBackgroundColor, useEuiTheme } from '@elastic/eui';
import { Handle, Position } from '@xyflow/react';
import {
- NodeContainer,
+ NodeShapeContainer,
NodeLabel,
NodeShapeOnHoverSvg,
NodeShapeSvg,
@@ -18,6 +18,7 @@ import {
HandleStyleOverride,
} from './styles';
import type { EntityNodeViewModel, NodeProps } from '../types';
+import { HexagonHoverShape, HexagonShape } from './shapes/hexagon_shape';
const NODE_WIDTH = 87;
const NODE_HEIGHT = 96;
@@ -27,59 +28,55 @@ export const HexagonNode: React.FC = memo((props: NodeProps) => {
props.data as EntityNodeViewModel;
const { euiTheme } = useEuiTheme();
return (
-
- {interactive && (
-
+
+ {interactive && (
+
+
+
+ )}
+
-
-
- )}
-
- }
+
+ {interactive && (
+ expandButtonClick?.(e, props)}
+ x={`${NODE_WIDTH - NodeButton.ExpandButtonSize / 2 + 2}px`}
+ y={`${(NODE_HEIGHT - NodeButton.ExpandButtonSize) / 2 - 2}px`}
+ />
+ )}
+
- {icon && }
-
- {interactive && (
- expandButtonClick?.(e, props)}
- x={`${NODE_WIDTH - NodeButton.ExpandButtonSize / 2 + 2}px`}
- y={`${(NODE_HEIGHT - NodeButton.ExpandButtonSize) / 2 - 2}px`}
+
- )}
-
-
+
{Boolean(label) ? label : id}
-
+ >
);
});
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/pentagon_node.tsx b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/pentagon_node.tsx
index 74ea8c05b5940..f2282e9fa2d7d 100644
--- a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/pentagon_node.tsx
+++ b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/pentagon_node.tsx
@@ -10,7 +10,7 @@ import { useEuiBackgroundColor, useEuiTheme } from '@elastic/eui';
import styled from '@emotion/styled';
import { Handle, Position } from '@xyflow/react';
import {
- NodeContainer,
+ NodeShapeContainer,
NodeLabel,
NodeShapeOnHoverSvg,
NodeShapeSvg,
@@ -19,6 +19,7 @@ import {
HandleStyleOverride,
} from './styles';
import type { EntityNodeViewModel, NodeProps } from '../types';
+import { PentagonHoverShape, PentagonShape } from './shapes/pentagon_shape';
const PentagonShapeOnHover = styled(NodeShapeOnHoverSvg)`
transform: translate(-50%, -51.5%);
@@ -32,59 +33,55 @@ export const PentagonNode: React.FC = memo((props: NodeProps) => {
props.data as EntityNodeViewModel;
const { euiTheme } = useEuiTheme();
return (
-
- {interactive && (
-
+
+ {interactive && (
+
+
+
+ )}
+
-
-
- )}
-
- }
+
+ {interactive && (
+ expandButtonClick?.(e, props)}
+ x={`${NODE_WIDTH - NodeButton.ExpandButtonSize / 2}px`}
+ y={`${(NODE_HEIGHT - NodeButton.ExpandButtonSize) / 2}px`}
+ />
+ )}
+
- {icon && }
-
- {interactive && (
- expandButtonClick?.(e, props)}
- x={`${NODE_WIDTH - NodeButton.ExpandButtonSize / 2}px`}
- y={`${(NODE_HEIGHT - NodeButton.ExpandButtonSize) / 2}px`}
+
- )}
-
-
+
{Boolean(label) ? label : id}
-
+ >
);
});
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/rectangle_node.tsx b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/rectangle_node.tsx
index 22d9fbf25a4eb..7a5fc14855bc9 100644
--- a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/rectangle_node.tsx
+++ b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/rectangle_node.tsx
@@ -9,7 +9,7 @@ import React, { memo } from 'react';
import { useEuiBackgroundColor, useEuiTheme } from '@elastic/eui';
import { Handle, Position } from '@xyflow/react';
import {
- NodeContainer,
+ NodeShapeContainer,
NodeLabel,
NodeShapeOnHoverSvg,
NodeShapeSvg,
@@ -18,6 +18,7 @@ import {
HandleStyleOverride,
} from './styles';
import type { EntityNodeViewModel, NodeProps } from '../types';
+import { RectangleHoverShape, RectangleShape } from './shapes/rectangle_shape';
const NODE_WIDTH = 81;
const NODE_HEIGHT = 80;
@@ -27,67 +28,55 @@ export const RectangleNode: React.FC = memo((props: NodeProps) => {
props.data as EntityNodeViewModel;
const { euiTheme } = useEuiTheme();
return (
-
- {interactive && (
-
+
+ {interactive && (
+
+
+
+ )}
+
-
-
- )}
-
- }
+
+ {interactive && (
+ expandButtonClick?.(e, props)}
+ x={`${NODE_WIDTH - NodeButton.ExpandButtonSize / 4}px`}
+ y={`${(NODE_HEIGHT - NodeButton.ExpandButtonSize / 2) / 2}px`}
+ />
+ )}
+
- {icon && }
-
- {interactive && (
- expandButtonClick?.(e, props)}
- x={`${NODE_WIDTH - NodeButton.ExpandButtonSize / 4}px`}
- y={`${(NODE_HEIGHT - NodeButton.ExpandButtonSize / 2) / 2}px`}
+
- )}
-
-
+
{Boolean(label) ? label : id}
-
+ >
);
});
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/shapes/diamond_shape.tsx b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/shapes/diamond_shape.tsx
new file mode 100644
index 0000000000000..126a5702cf5d0
--- /dev/null
+++ b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/shapes/diamond_shape.tsx
@@ -0,0 +1,26 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import React, { memo } from 'react';
+import type { HoverShapeProps, ShapeProps } from './types';
+
+export const DiamondHoverShape: React.FC = memo(({ stroke }) => (
+
+));
+
+export const DiamondShape: React.FC = memo(({ stroke, fill }) => (
+
+));
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/shapes/ellipse_shape.tsx b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/shapes/ellipse_shape.tsx
new file mode 100644
index 0000000000000..18fe56440c5f5
--- /dev/null
+++ b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/shapes/ellipse_shape.tsx
@@ -0,0 +1,17 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import React, { memo } from 'react';
+import type { HoverShapeProps, ShapeProps } from './types';
+
+export const EllipseHoverShape: React.FC = memo(({ stroke }) => (
+
+));
+
+export const EllipseShape: React.FC = memo(({ stroke, fill }) => (
+
+));
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/shapes/hexagon_shape.tsx b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/shapes/hexagon_shape.tsx
new file mode 100644
index 0000000000000..12aeebec88605
--- /dev/null
+++ b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/shapes/hexagon_shape.tsx
@@ -0,0 +1,26 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import React, { memo } from 'react';
+import type { HoverShapeProps, ShapeProps } from './types';
+
+export const HexagonHoverShape: React.FC = memo(({ stroke }) => (
+
+));
+
+export const HexagonShape: React.FC = memo(({ stroke, fill }) => (
+
+));
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/shapes/pentagon_shape.tsx b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/shapes/pentagon_shape.tsx
new file mode 100644
index 0000000000000..f4d07fc69db79
--- /dev/null
+++ b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/shapes/pentagon_shape.tsx
@@ -0,0 +1,26 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import React, { memo } from 'react';
+import type { HoverShapeProps, ShapeProps } from './types';
+
+export const PentagonHoverShape: React.FC = memo(({ stroke }) => (
+
+));
+
+export const PentagonShape: React.FC = memo(({ stroke, fill }) => (
+
+));
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/shapes/rectangle_shape.tsx b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/shapes/rectangle_shape.tsx
new file mode 100644
index 0000000000000..7d019ce331baf
--- /dev/null
+++ b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/shapes/rectangle_shape.tsx
@@ -0,0 +1,26 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import React, { memo } from 'react';
+import type { HoverShapeProps, ShapeProps } from './types';
+
+export const RectangleHoverShape: React.FC = memo(({ stroke }) => (
+
+));
+
+export const RectangleShape: React.FC = memo(({ stroke, fill }) => (
+
+));
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/shapes/types.ts b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/shapes/types.ts
new file mode 100644
index 0000000000000..0f6910258fed6
--- /dev/null
+++ b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/shapes/types.ts
@@ -0,0 +1,15 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export interface HoverShapeProps {
+ stroke: string;
+}
+
+export interface ShapeProps {
+ stroke: string;
+ fill: string;
+}
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/styles.tsx b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/styles.tsx
index f1bee0cf95e30..e76da737af0f9 100644
--- a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/styles.tsx
+++ b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/styles.tsx
@@ -23,6 +23,7 @@ export const LABEL_PADDING_X = 15;
export const LABEL_BORDER_WIDTH = 1;
export const NODE_WIDTH = 90;
export const NODE_HEIGHT = 90;
+const NODE_LABEL_WIDTH = 120;
export const LabelNodeContainer = styled.div`
text-wrap: nowrap;
@@ -79,9 +80,13 @@ export const LabelShapeOnHover = styled.div`
${LabelNodeContainer}:hover & {
opacity: 1; /* Show on hover */
}
+
+ .react-flow__node:focus:focus-visible & {
+ opacity: 1; /* Show on hover */
+ }
`;
-export const NodeContainer = styled.div`
+export const NodeShapeContainer = styled.div`
position: relative;
width: ${NODE_WIDTH}px;
height: ${NODE_HEIGHT}px;
@@ -99,7 +104,11 @@ export const NodeShapeOnHoverSvg = styled(NodeShapeSvg)`
opacity: 0; /* Hidden by default */
transition: opacity 0.2s ease; /* Smooth transition */
- ${NodeContainer}:hover & {
+ ${NodeShapeContainer}:hover & {
+ opacity: 1; /* Show on hover */
+ }
+
+ .react-flow__node:focus:focus-visible & {
opacity: 1; /* Show on hover */
}
`;
@@ -124,11 +133,8 @@ export const NodeIcon = ({ icon, color, x, y }: NodeIconProps) => {
};
export const NodeLabel = styled(EuiText)`
- position: absolute;
- top: 108%;
- left: 50%;
- transform: translateX(-50%);
- width: 130%;
+ width: ${NODE_LABEL_WIDTH}px;
+ margin-left: ${-(NODE_LABEL_WIDTH - NODE_WIDTH) / 2}px;
text-overflow: ellipsis;
// white-space: nowrap;
overflow: hidden;
@@ -167,9 +173,17 @@ export const StyledNodeButton = styled.div`
position: absolute;
z-index: 1;
- ${NodeContainer}:hover & {
+ ${NodeShapeContainer}:hover & {
opacity: 1; /* Show on hover */
}
+
+ &:has(button:focus) {
+ opacity: 1; /* Show when button is active */
+ }
+
+ .react-flow__node:focus:focus-visible & {
+ opacity: 1; /* Show on node focus */
+ }
`;
export interface NodeButtonProps {
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/types.ts b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/types.ts
index 262254c80afe3..27ec18f35f45b 100644
--- a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/types.ts
+++ b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/types.ts
@@ -10,29 +10,17 @@ import type {
GroupNodeDataModel,
LabelNodeDataModel,
EdgeDataModel,
+ NodeShape,
} from '@kbn/cloud-security-posture-common/types/graph/latest';
import type { Node, NodeProps as xyNodeProps } from '@xyflow/react';
import type { Edge, EdgeProps as xyEdgeProps } from '@xyflow/react';
-export interface PositionXY {
- x: number;
- y: number;
-}
-
export interface Size {
width: number;
height: number;
}
-export interface GraphMetadata {
- nodes: { [key: string]: { edgesIn: number; edgesOut: number } };
- edges: {
- [key: string]: { source: string; target: string; edgesStacked: number; edges: string[] };
- };
-}
-
interface BaseNodeDataViewModel {
- position: PositionXY;
interactive?: boolean;
}
@@ -46,9 +34,7 @@ export interface EntityNodeViewModel
export interface GroupNodeViewModel
extends Record,
GroupNodeDataModel,
- BaseNodeDataViewModel {
- size?: Size;
-}
+ BaseNodeDataViewModel {}
export interface LabelNodeViewModel
extends Record,
@@ -61,10 +47,13 @@ export type NodeViewModel = EntityNodeViewModel | GroupNodeViewModel | LabelNode
export type NodeProps = xyNodeProps>;
-export interface EdgeViewModel extends Record, EdgeDataModel {
- graphMetadata?: GraphMetadata;
- interactive?: boolean;
- onClick?: (e: React.MouseEvent, edge: EdgeProps) => void;
-}
+export interface EdgeViewModel extends Record, EdgeDataModel {}
-export type EdgeProps = xyEdgeProps>;
+export type EdgeProps = xyEdgeProps<
+ Edge<
+ EdgeViewModel & {
+ sourceShape: NodeShape;
+ targetShape: NodeShape;
+ }
+ >
+>;
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/storybook/config/main.ts b/x-pack/packages/kbn-cloud-security-posture/graph/storybook/config/main.ts
deleted file mode 100644
index 186e1a2a76bed..0000000000000
--- a/x-pack/packages/kbn-cloud-security-posture/graph/storybook/config/main.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-import { defaultConfig } from '@kbn/storybook';
-import { Configuration } from 'webpack';
-
-module.exports = {
- ...defaultConfig,
- stories: ['../../**/*.stories.+(tsx|mdx)'],
- reactOptions: {
- strictMode: true,
- },
- webpack: (config: Configuration) => {
- config.module?.rules.push({
- test: /\.js$/,
- include: /node_modules[\\\/]@dagrejs/,
- use: {
- loader: 'babel-loader',
- options: {
- presets: ['@babel/preset-env'],
- plugins: ['@babel/plugin-proposal-class-properties'],
- },
- },
- });
- config.module?.rules.push({
- test: /node_modules[\/\\]@?xyflow[\/\\].*.js$/,
- loaders: 'babel-loader',
- options: {
- presets: [['@babel/preset-env', { modules: false }], '@babel/preset-react'],
- plugins: [
- '@babel/plugin-proposal-optional-chaining',
- '@babel/plugin-proposal-nullish-coalescing-operator',
- '@babel/plugin-transform-logical-assignment-operators',
- ],
- },
- });
-
- return config;
- },
-};
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/tsconfig.json b/x-pack/packages/kbn-cloud-security-posture/graph/tsconfig.json
index d97809a59772d..d0056e29e6784 100644
--- a/x-pack/packages/kbn-cloud-security-posture/graph/tsconfig.json
+++ b/x-pack/packages/kbn-cloud-security-posture/graph/tsconfig.json
@@ -13,6 +13,6 @@
"kbn_references": [
"@kbn/cloud-security-posture-common",
"@kbn/utility-types",
- "@kbn/storybook"
+ "@kbn/ui-theme",
]
}
diff --git a/x-pack/packages/kbn-cloud-security-posture/public/kibana.jsonc b/x-pack/packages/kbn-cloud-security-posture/public/kibana.jsonc
index 4c5a4f1f0165d..811a1ab5dad41 100644
--- a/x-pack/packages/kbn-cloud-security-posture/public/kibana.jsonc
+++ b/x-pack/packages/kbn-cloud-security-posture/public/kibana.jsonc
@@ -1,5 +1,5 @@
{
- "id": "@kbn/cloud-security-posture",
- "owner": "@elastic/kibana-cloud-security-posture",
- "type": "shared-browser"
-}
\ No newline at end of file
+ "id": "@kbn/cloud-security-posture",
+ "owner": "@elastic/kibana-cloud-security-posture",
+ "type": "shared-browser"
+}
diff --git a/x-pack/packages/kbn-cloud-security-posture/storybook/config/README.mdx b/x-pack/packages/kbn-cloud-security-posture/storybook/config/README.mdx
new file mode 100644
index 0000000000000..ab9ce5263ec69
--- /dev/null
+++ b/x-pack/packages/kbn-cloud-security-posture/storybook/config/README.mdx
@@ -0,0 +1,3 @@
+# @kbn/cloud-security-posture-storybook-config
+
+Storybook configuration used by `yarn storybook`. Refer to `@kbn/storybook` for more information.
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/storybook/config/constants.ts b/x-pack/packages/kbn-cloud-security-posture/storybook/config/constants.ts
similarity index 100%
rename from x-pack/packages/kbn-cloud-security-posture/graph/storybook/config/constants.ts
rename to x-pack/packages/kbn-cloud-security-posture/storybook/config/constants.ts
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/storybook/config/index.ts b/x-pack/packages/kbn-cloud-security-posture/storybook/config/index.ts
similarity index 100%
rename from x-pack/packages/kbn-cloud-security-posture/graph/storybook/config/index.ts
rename to x-pack/packages/kbn-cloud-security-posture/storybook/config/index.ts
diff --git a/x-pack/packages/kbn-cloud-security-posture/storybook/config/main.ts b/x-pack/packages/kbn-cloud-security-posture/storybook/config/main.ts
new file mode 100644
index 0000000000000..4e7fca030c2f6
--- /dev/null
+++ b/x-pack/packages/kbn-cloud-security-posture/storybook/config/main.ts
@@ -0,0 +1,16 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { defaultConfig } from '@kbn/storybook';
+
+module.exports = {
+ ...defaultConfig,
+ stories: ['../../**/*.stories.+(tsx|mdx)'],
+ reactOptions: {
+ strictMode: true,
+ },
+};
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/storybook/config/manager.ts b/x-pack/packages/kbn-cloud-security-posture/storybook/config/manager.ts
similarity index 100%
rename from x-pack/packages/kbn-cloud-security-posture/graph/storybook/config/manager.ts
rename to x-pack/packages/kbn-cloud-security-posture/storybook/config/manager.ts
diff --git a/x-pack/packages/kbn-cloud-security-posture/storybook/config/package.json b/x-pack/packages/kbn-cloud-security-posture/storybook/config/package.json
new file mode 100644
index 0000000000000..4ba8c8fd3d57f
--- /dev/null
+++ b/x-pack/packages/kbn-cloud-security-posture/storybook/config/package.json
@@ -0,0 +1,6 @@
+{
+ "name": "@kbn/cloud-security-posture-storybook-config",
+ "private": true,
+ "version": "1.0.0",
+ "license": "Elastic License 2.0"
+}
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/storybook/config/preview.ts b/x-pack/packages/kbn-cloud-security-posture/storybook/config/preview.ts
similarity index 100%
rename from x-pack/packages/kbn-cloud-security-posture/graph/storybook/config/preview.ts
rename to x-pack/packages/kbn-cloud-security-posture/storybook/config/preview.ts
diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/storybook/config/styles.css b/x-pack/packages/kbn-cloud-security-posture/storybook/config/styles.css
similarity index 100%
rename from x-pack/packages/kbn-cloud-security-posture/graph/storybook/config/styles.css
rename to x-pack/packages/kbn-cloud-security-posture/storybook/config/styles.css
diff --git a/x-pack/packages/kbn-cloud-security-posture/storybook/config/tsconfig.json b/x-pack/packages/kbn-cloud-security-posture/storybook/config/tsconfig.json
new file mode 100644
index 0000000000000..1f8b2275f5191
--- /dev/null
+++ b/x-pack/packages/kbn-cloud-security-posture/storybook/config/tsconfig.json
@@ -0,0 +1,20 @@
+{
+ "extends": "../../../../../tsconfig.base.json",
+ "compilerOptions": {
+ "outDir": "target/types",
+ "types": [
+ "jest",
+ "node",
+ "@kbn/ambient-storybook-types",
+ ]
+ },
+ "include": [
+ "**/*.ts"
+ ],
+ "kbn_references": [
+ "@kbn/storybook",
+ ],
+ "exclude": [
+ "target/**/*",
+ ]
+}
diff --git a/x-pack/packages/security-solution/common/src/flyout/common/components/expandable_panel.tsx b/x-pack/packages/security-solution/common/src/flyout/common/components/expandable_panel.tsx
index 4f1890e58554f..383bbbb341c8e 100644
--- a/x-pack/packages/security-solution/common/src/flyout/common/components/expandable_panel.tsx
+++ b/x-pack/packages/security-solution/common/src/flyout/common/components/expandable_panel.tsx
@@ -22,7 +22,7 @@ import {
EuiSkeletonText,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import type { IconType } from '@elastic/eui';
+import type { EuiPanelProps, IconType } from '@elastic/eui';
import { css } from '@emotion/react';
export interface ExpandablePanelPanelProps {
@@ -59,6 +59,10 @@ export interface ExpandablePanelPanelProps {
* Returns a null component if true
*/
error?: boolean;
+ /**
+ * Content's padding size
+ */
+ paddingSize?: EuiPanelProps['paddingSize'];
};
expand?: {
/**
@@ -84,7 +88,11 @@ export interface ExpandablePanelPanelProps {
*/
export const ExpandablePanel: FC> = ({
header: { title, link, iconType, headerContent },
- content: { loading, error } = { loading: false, error: false },
+ content: { loading, error, paddingSize: contentPaddingSize } = {
+ loading: false,
+ error: false,
+ paddingSize: 'm',
+ },
expand: { expandable, expandedOnFirstRender } = {
expandable: false,
expandedOnFirstRender: false,
@@ -228,7 +236,9 @@ export const ExpandablePanel: FC> =
{showContent && (
- {content}
+
+ {content}
+
)}
diff --git a/x-pack/plugins/cloud_security_posture/server/routes/graph/v1.ts b/x-pack/plugins/cloud_security_posture/server/routes/graph/v1.ts
index eb372a2bfea4f..5102d153c1905 100644
--- a/x-pack/plugins/cloud_security_posture/server/routes/graph/v1.ts
+++ b/x-pack/plugins/cloud_security_posture/server/routes/graph/v1.ts
@@ -6,6 +6,7 @@
*/
import { castArray } from 'lodash';
+import { v4 as uuidv4 } from 'uuid';
import type { Logger, IScopedClusterClient } from '@kbn/core/server';
import type {
EdgeDataModel,
@@ -13,10 +14,9 @@ import type {
EntityNodeDataModel,
LabelNodeDataModel,
GroupNodeDataModel,
- NodeShape,
} from '@kbn/cloud-security-posture-common/types/graph/latest';
import type { EsqlToRecords } from '@elastic/elasticsearch/lib/helpers';
-import type { Writeable } from '@kbn/zod';
+import type { Writable } from '@kbn/utility-types';
import type { GraphContextServices, GraphContext } from './types';
interface GraphEdge {
@@ -31,6 +31,11 @@ interface GraphEdge {
isAlert: boolean;
}
+interface LabelEdges {
+ source: string;
+ target: string;
+}
+
export const getGraph = async (
services: GraphContextServices,
query: {
@@ -63,28 +68,29 @@ export const getGraph = async (
interface ParseContext {
nodesMap: Record;
- edgeLabelsNodes: Record;
edgesMap: Record;
+ edgeLabelsNodes: Record;
+ labelEdges: Record;
}
const parseRecords = (logger: Logger, records: GraphEdge[]): GraphContext => {
- const nodesMap: Record = {};
- const edgeLabelsNodes: Record = {};
- const edgesMap: Record = {};
+ const ctx: ParseContext = { nodesMap: {}, edgeLabelsNodes: {}, edgesMap: {}, labelEdges: {} };
logger.trace(`Parsing records [length: ${records.length}]`);
- createNodes(logger, records, { nodesMap, edgeLabelsNodes });
- createEdgesAndGroups(logger, { edgeLabelsNodes, edgesMap, nodesMap });
+ createNodes(logger, records, ctx);
+ createEdgesAndGroups(logger, ctx);
logger.trace(
- `Parsed [nodes: ${Object.keys(nodesMap).length}, edges: ${Object.keys(edgesMap).length}]`
+ `Parsed [nodes: ${Object.keys(ctx.nodesMap).length}, edges: ${
+ Object.keys(ctx.edgesMap).length
+ }]`
);
// Sort groups to be first (fixes minor layout issue)
- const nodes = sortNodes(nodesMap);
+ const nodes = sortNodes(ctx.nodesMap);
- return { nodes, edges: Object.values(edgesMap) };
+ return { nodes, edges: Object.values(ctx.edgesMap) };
};
const fetchGraph = async ({
@@ -168,12 +174,21 @@ const createNodes = (
records: GraphEdge[],
context: Omit
) => {
- const { nodesMap, edgeLabelsNodes } = context;
+ const { nodesMap, edgeLabelsNodes, labelEdges } = context;
for (const record of records) {
const { ips, hosts, users, actorIds, action, targetIds, isAlert, eventOutcome } = record;
const actorIdsArray = castArray(actorIds);
const targetIdsArray = castArray(targetIds);
+ const unknownTargets: string[] = [];
+
+ // Ensure all targets has an id (target can return null from the query)
+ targetIdsArray.forEach((id, idx) => {
+ if (!id) {
+ targetIdsArray[idx] = `unknown ${uuidv4()}`;
+ unknownTargets.push(targetIdsArray[idx]);
+ }
+ });
logger.trace(
`Parsing record [actorIds: ${actorIdsArray.join(
@@ -186,7 +201,7 @@ const createNodes = (
if (nodesMap[id] === undefined) {
nodesMap[id] = {
id,
- label: id,
+ label: unknownTargets.includes(id) ? 'Unknown' : undefined,
color: isAlert ? 'danger' : 'primary',
...determineEntityNodeShape(id, ips ?? [], hosts ?? [], users ?? []),
};
@@ -204,19 +219,18 @@ const createNodes = (
edgeLabelsNodes[edgeId] = [];
}
- const labelNode = {
+ const labelNode: LabelNodeDataModel = {
id: edgeId + `label(${action})outcome(${eventOutcome})`,
label: action,
- source: actorId,
- target: targetId,
color: isAlert ? 'danger' : eventOutcome === 'failed' ? 'warning' : 'primary',
shape: 'label',
- } as LabelNodeDataModel;
+ };
logger.trace(`Creating label node [${labelNode.id}]`);
nodesMap[labelNode.id] = labelNode;
edgeLabelsNodes[edgeId].push(labelNode.id);
+ labelEdges[labelNode.id] = { source: actorId, target: targetId };
}
}
}
@@ -265,7 +279,7 @@ const sortNodes = (nodesMap: Record) => {
};
const createEdgesAndGroups = (logger: Logger, context: ParseContext) => {
- const { edgeLabelsNodes, edgesMap, nodesMap } = context;
+ const { edgeLabelsNodes, edgesMap, nodesMap, labelEdges } = context;
Object.entries(edgeLabelsNodes).forEach(([edgeId, edgeLabelsIds]) => {
// When there's more than one edge label, create a group node
@@ -276,9 +290,9 @@ const createEdgesAndGroups = (logger: Logger, context: ParseContext) => {
logger,
edgesMap,
nodesMap,
- (nodesMap[edgeLabelId] as LabelNodeDataModel).source,
+ labelEdges[edgeLabelId].source,
edgeLabelId,
- (nodesMap[edgeLabelId] as LabelNodeDataModel).target
+ labelEdges[edgeLabelId].target
);
} else {
const groupNode: GroupNodeDataModel = {
@@ -291,13 +305,13 @@ const createEdgesAndGroups = (logger: Logger, context: ParseContext) => {
logger,
edgesMap,
nodesMap,
- (nodesMap[edgeLabelsIds[0]] as LabelNodeDataModel).source,
+ labelEdges[edgeLabelsIds[0]].source,
groupNode.id,
- (nodesMap[edgeLabelsIds[0]] as LabelNodeDataModel).target
+ labelEdges[edgeLabelsIds[0]].target
);
edgeLabelsIds.forEach((edgeLabelId) => {
- (nodesMap[edgeLabelId] as Writeable).parentId = groupNode.id;
+ (nodesMap[edgeLabelId] as Writable).parentId = groupNode.id;
connectEntitiesAndLabelNode(
logger,
edgesMap,
@@ -332,7 +346,7 @@ const connectNodes = (
nodesMap: Record,
sourceNodeId: string,
targetNodeId: string
-) => {
+): EdgeDataModel => {
const sourceNode = nodesMap[sourceNodeId];
const targetNode = nodesMap[targetNodeId];
const color =
@@ -345,9 +359,7 @@ const connectNodes = (
return {
id: `a(${sourceNodeId})-b(${targetNodeId})`,
source: sourceNodeId,
- sourceShape: nodesMap[sourceNodeId].shape as NodeShape,
target: targetNodeId,
- targetShape: nodesMap[targetNodeId].shape as NodeShape,
color,
- } as EdgeDataModel;
+ };
};
diff --git a/x-pack/plugins/cloud_security_posture/tsconfig.json b/x-pack/plugins/cloud_security_posture/tsconfig.json
index 456035c9112d1..f3883e0fc43c6 100755
--- a/x-pack/plugins/cloud_security_posture/tsconfig.json
+++ b/x-pack/plugins/cloud_security_posture/tsconfig.json
@@ -66,7 +66,6 @@
"@kbn/cloud-security-posture-common",
"@kbn/cloud-security-posture",
"@kbn/analytics",
- "@kbn/zod"
],
"exclude": ["target/**/*"]
}
diff --git a/x-pack/plugins/security_solution/common/constants.ts b/x-pack/plugins/security_solution/common/constants.ts
index 584b992a0f61d..68aaf7bf9cf04 100644
--- a/x-pack/plugins/security_solution/common/constants.ts
+++ b/x-pack/plugins/security_solution/common/constants.ts
@@ -280,6 +280,8 @@ export const PINNED_EVENT_URL = '/api/pinned_event' as const;
export const SOURCERER_API_URL = '/internal/security_solution/sourcerer' as const;
export const RISK_SCORE_INDEX_STATUS_API_URL = '/internal/risk_score/index_status' as const;
+export const EVENT_GRAPH_VISUALIZATION_API = '/internal/cloud_security_posture/graph' as const;
+
/**
* Default signals index key for kibana.dev.yml
*/
diff --git a/x-pack/plugins/security_solution/common/experimental_features.ts b/x-pack/plugins/security_solution/common/experimental_features.ts
index ffb9e9748d9c1..792b6352912b3 100644
--- a/x-pack/plugins/security_solution/common/experimental_features.ts
+++ b/x-pack/plugins/security_solution/common/experimental_features.ts
@@ -190,6 +190,11 @@ export const allowedExperimentalValues = Object.freeze({
*/
analyzerDatePickersAndSourcererDisabled: false,
+ /**
+ * Enables graph visualization in alerts flyout
+ */
+ graphVisualizationInFlyoutEnabled: false,
+
/**
* Enables an ability to customize Elastic prebuilt rules.
*
diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/graph_preview.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/graph_preview.test.tsx
new file mode 100644
index 0000000000000..22ac27eaa4e00
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/graph_preview.test.tsx
@@ -0,0 +1,72 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { render } from '@testing-library/react';
+import React from 'react';
+import { TestProviders } from '../../../../common/mock';
+import { mockContextValue } from '../../shared/mocks/mock_context';
+import { DocumentDetailsContext } from '../../shared/context';
+import { GraphPreview, type GraphPreviewProps } from './graph_preview';
+import { GRAPH_PREVIEW_TEST_ID, GRAPH_PREVIEW_LOADING_TEST_ID } from './test_ids';
+
+const mockGraph = () => ;
+
+jest.mock('@kbn/cloud-security-posture-graph', () => {
+ return { Graph: mockGraph };
+});
+
+const renderGraphPreview = (contextValue: DocumentDetailsContext, props: GraphPreviewProps) =>
+ render(
+
+
+
+
+
+ );
+
+const ERROR_MESSAGE = 'An error is preventing this alert from being visualized.';
+
+describe('', () => {
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ it('shows graph preview correctly when data is loaded', async () => {
+ const graphProps = {
+ isLoading: false,
+ isError: false,
+ data: { nodes: [], edges: [] },
+ };
+
+ const { findByTestId } = renderGraphPreview(mockContextValue, graphProps);
+
+ // Using findByTestId to wait for the component to be rendered because it is a lazy loaded component
+ expect(await findByTestId(GRAPH_PREVIEW_TEST_ID)).toBeInTheDocument();
+ });
+
+ it('shows loading when data is loading', () => {
+ const graphProps = {
+ isLoading: true,
+ isError: false,
+ };
+
+ const { getByTestId } = renderGraphPreview(mockContextValue, graphProps);
+
+ expect(getByTestId(GRAPH_PREVIEW_LOADING_TEST_ID)).toBeInTheDocument();
+ });
+
+ it('shows error message when there is an error', () => {
+ const graphProps = {
+ isLoading: false,
+ isError: true,
+ };
+
+ const { getByText } = renderGraphPreview(mockContextValue, graphProps);
+
+ expect(getByText(ERROR_MESSAGE)).toBeInTheDocument();
+ });
+});
diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/graph_preview.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/graph_preview.tsx
new file mode 100644
index 0000000000000..c3c6d65c7e986
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/graph_preview.tsx
@@ -0,0 +1,102 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import React, { memo, useMemo } from 'react';
+import { EuiSkeletonText } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+import { css } from '@emotion/react';
+import { FormattedMessage } from '@kbn/i18n-react';
+import type {
+ NodeDataModel,
+ EdgeDataModel,
+} from '@kbn/cloud-security-posture-common/types/graph/latest';
+import { GRAPH_PREVIEW_TEST_ID, GRAPH_PREVIEW_LOADING_TEST_ID } from './test_ids';
+
+/**
+ * Props for the GraphPreview component.
+ */
+export interface GraphPreviewProps {
+ /**
+ * Indicates whether the graph is currently loading.
+ */
+ isLoading: boolean;
+
+ /**
+ * Indicates whether there was an error loading the graph.
+ */
+ isError: boolean;
+
+ /**
+ * Optional data for the graph, including nodes and edges.
+ */
+ data?: {
+ /**
+ * Array of node data models.
+ */
+ nodes: NodeDataModel[];
+
+ /**
+ * Array of edge data models.
+ */
+ edges: EdgeDataModel[];
+ };
+}
+
+const GraphLazy = React.lazy(() =>
+ import('@kbn/cloud-security-posture-graph').then((module) => ({ default: module.Graph }))
+);
+
+const LoadingComponent = () => (
+
+);
+
+/**
+ * Graph preview under Overview, Visualizations. It shows a graph without abilities to expand.
+ */
+export const GraphPreview: React.FC = memo(
+ ({ isLoading, isError, data }: GraphPreviewProps) => {
+ const memoizedNodes = useMemo(() => data?.nodes ?? [], [data?.nodes]);
+ const memoizedEdges = useMemo(() => data?.edges ?? [], [data?.edges]);
+
+ return isLoading ? (
+
+ ) : isError ? (
+
+ ) : (
+ }>
+
+
+ );
+ }
+);
+
+GraphPreview.displayName = 'GraphPreview';
diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/graph_preview_container.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/graph_preview_container.test.tsx
new file mode 100644
index 0000000000000..6b30e2127a2f8
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/graph_preview_container.test.tsx
@@ -0,0 +1,110 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { render } from '@testing-library/react';
+import { TestProviders } from '../../../../common/mock';
+import React from 'react';
+import { DocumentDetailsContext } from '../../shared/context';
+import { mockContextValue } from '../../shared/mocks/mock_context';
+import { GraphPreviewContainer } from './graph_preview_container';
+import { GRAPH_PREVIEW_TEST_ID } from './test_ids';
+import { useGraphPreview } from '../hooks/use_graph_preview';
+import { useFetchGraphData } from '../hooks/use_fetch_graph_data';
+
+import {
+ EXPANDABLE_PANEL_CONTENT_TEST_ID,
+ EXPANDABLE_PANEL_HEADER_TITLE_ICON_TEST_ID,
+ EXPANDABLE_PANEL_HEADER_TITLE_LINK_TEST_ID,
+ EXPANDABLE_PANEL_HEADER_TITLE_TEXT_TEST_ID,
+ EXPANDABLE_PANEL_TOGGLE_ICON_TEST_ID,
+} from '@kbn/security-solution-common';
+
+jest.mock('../hooks/use_graph_preview');
+jest.mock('../hooks/use_fetch_graph_data', () => ({
+ useFetchGraphData: jest.fn(),
+}));
+const mockUseFetchGraphData = useFetchGraphData as jest.Mock;
+
+const mockUseUiSetting = jest.fn().mockReturnValue([false]);
+jest.mock('@kbn/kibana-react-plugin/public', () => {
+ const original = jest.requireActual('@kbn/kibana-react-plugin/public');
+ return {
+ ...original,
+ useUiSetting$: () => mockUseUiSetting(),
+ };
+});
+
+const mockGraph = () => ;
+
+jest.mock('@kbn/cloud-security-posture-graph', () => {
+ return { Graph: mockGraph };
+});
+
+const renderGraphPreview = (context = mockContextValue) =>
+ render(
+
+
+
+
+
+ );
+
+describe('', () => {
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ it('should render component and link in header', async () => {
+ mockUseFetchGraphData.mockReturnValue({
+ isLoading: false,
+ isError: false,
+ data: { nodes: [], edges: [] },
+ });
+
+ (useGraphPreview as jest.Mock).mockReturnValue({
+ isAuditLog: true,
+ });
+
+ const { getByTestId, queryByTestId, findByTestId } = renderGraphPreview();
+
+ // Using findByTestId to wait for the component to be rendered because it is a lazy loaded component
+ expect(await findByTestId(GRAPH_PREVIEW_TEST_ID)).toBeInTheDocument();
+ expect(
+ queryByTestId(EXPANDABLE_PANEL_HEADER_TITLE_LINK_TEST_ID(GRAPH_PREVIEW_TEST_ID))
+ ).not.toBeInTheDocument();
+ expect(
+ queryByTestId(EXPANDABLE_PANEL_TOGGLE_ICON_TEST_ID(GRAPH_PREVIEW_TEST_ID))
+ ).not.toBeInTheDocument();
+ expect(
+ getByTestId(EXPANDABLE_PANEL_HEADER_TITLE_ICON_TEST_ID(GRAPH_PREVIEW_TEST_ID))
+ ).toBeInTheDocument();
+ expect(
+ getByTestId(EXPANDABLE_PANEL_CONTENT_TEST_ID(GRAPH_PREVIEW_TEST_ID))
+ ).toBeInTheDocument();
+ expect(
+ getByTestId(EXPANDABLE_PANEL_HEADER_TITLE_TEXT_TEST_ID(GRAPH_PREVIEW_TEST_ID))
+ ).toBeInTheDocument();
+ });
+
+ it('should render error message and text in header', () => {
+ mockUseFetchGraphData.mockReturnValue({
+ isLoading: false,
+ isError: false,
+ data: undefined,
+ });
+
+ (useGraphPreview as jest.Mock).mockReturnValue({
+ isAuditLog: false,
+ });
+
+ const { getByTestId } = renderGraphPreview();
+
+ expect(
+ getByTestId(EXPANDABLE_PANEL_HEADER_TITLE_TEXT_TEST_ID(GRAPH_PREVIEW_TEST_ID))
+ ).toBeInTheDocument();
+ });
+});
diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/graph_preview_container.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/graph_preview_container.tsx
new file mode 100644
index 0000000000000..1bc6a8dd7e547
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/graph_preview_container.tsx
@@ -0,0 +1,72 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import React from 'react';
+import { FormattedMessage } from '@kbn/i18n-react';
+import { ExpandablePanel } from '@kbn/security-solution-common';
+import { useDocumentDetailsContext } from '../../shared/context';
+import { GRAPH_PREVIEW_TEST_ID } from './test_ids';
+import { GraphPreview } from './graph_preview';
+import { useFetchGraphData } from '../hooks/use_fetch_graph_data';
+import { useGraphPreview } from '../hooks/use_graph_preview';
+
+const DEFAULT_FROM = 'now-60d/d';
+const DEFAULT_TO = 'now/d';
+
+/**
+ * Graph preview under Overview, Visualizations. It shows a graph representation of entities.
+ */
+export const GraphPreviewContainer: React.FC = () => {
+ const { dataAsNestedObject, getFieldsData } = useDocumentDetailsContext();
+
+ const { eventIds } = useGraphPreview({
+ getFieldsData,
+ ecsData: dataAsNestedObject,
+ });
+
+ // TODO: default start and end might not capture the original event
+ const graphFetchQuery = useFetchGraphData({
+ req: {
+ query: {
+ actorIds: [],
+ eventIds,
+ start: DEFAULT_FROM,
+ end: DEFAULT_TO,
+ },
+ },
+ });
+
+ return (
+
+ ),
+ iconType: 'indexMapping',
+ }}
+ data-test-subj={GRAPH_PREVIEW_TEST_ID}
+ content={
+ !graphFetchQuery.isLoading && !graphFetchQuery.isError
+ ? {
+ paddingSize: 'none',
+ }
+ : undefined
+ }
+ >
+
+
+ );
+};
+
+GraphPreviewContainer.displayName = 'GraphPreviewContainer';
diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/test_ids.ts b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/test_ids.ts
index e0d8bc6db0f5c..e649c578bf487 100644
--- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/test_ids.ts
+++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/test_ids.ts
@@ -178,6 +178,9 @@ export const SESSION_PREVIEW_TEST_ID = `${PREFIX}SessionPreview` as const;
export const SESSION_PREVIEW_RULE_DETAILS_LINK_TEST_ID =
`${SESSION_PREVIEW_TEST_ID}RuleDetailsLink` as const;
+export const GRAPH_PREVIEW_TEST_ID = `${PREFIX}GraphPreview` as const;
+export const GRAPH_PREVIEW_LOADING_TEST_ID = `${GRAPH_PREVIEW_TEST_ID}Loading` as const;
+
/* Response section */
const RESPONSE_TEST_ID = `${PREFIX}Response` as const;
diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/visualizations_section.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/visualizations_section.test.tsx
index 9af61e21fb67d..3aeb7d30f8e48 100644
--- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/visualizations_section.test.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/visualizations_section.test.tsx
@@ -11,6 +11,7 @@ import { render } from '@testing-library/react';
import {
ANALYZER_PREVIEW_TEST_ID,
SESSION_PREVIEW_TEST_ID,
+ GRAPH_PREVIEW_TEST_ID,
VISUALIZATIONS_SECTION_CONTENT_TEST_ID,
VISUALIZATIONS_SECTION_HEADER_TEST_ID,
} from './test_ids';
@@ -24,6 +25,9 @@ import { TestProvider } from '@kbn/expandable-flyout/src/test/provider';
import { useExpandSection } from '../hooks/use_expand_section';
import { useInvestigateInTimeline } from '../../../../detections/components/alerts_table/timeline_actions/use_investigate_in_timeline';
import { useIsInvestigateInResolverActionEnabled } from '../../../../detections/components/alerts_table/timeline_actions/investigate_in_resolver';
+import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features';
+import { useGraphPreview } from '../hooks/use_graph_preview';
+import { useFetchGraphData } from '../hooks/use_fetch_graph_data';
jest.mock('../hooks/use_expand_section');
jest.mock('../../shared/hooks/use_alert_prevalence_from_process_tree', () => ({
@@ -49,6 +53,11 @@ jest.mock(
jest.mock(
'../../../../detections/components/alerts_table/timeline_actions/investigate_in_resolver'
);
+jest.mock('../../../../common/hooks/use_experimental_features', () => ({
+ useIsExperimentalFeatureEnabled: jest.fn(),
+}));
+
+const useIsExperimentalFeatureEnabledMock = useIsExperimentalFeatureEnabled as jest.Mock;
const mockUseUiSetting = jest.fn().mockReturnValue([false]);
jest.mock('@kbn/kibana-react-plugin/public', () => {
@@ -58,6 +67,15 @@ jest.mock('@kbn/kibana-react-plugin/public', () => {
useUiSetting$: () => mockUseUiSetting(),
};
});
+jest.mock('../hooks/use_graph_preview');
+
+const mockUseGraphPreview = useGraphPreview as jest.Mock;
+
+jest.mock('../hooks/use_fetch_graph_data', () => ({
+ useFetchGraphData: jest.fn(),
+}));
+
+const mockUseFetchGraphData = useFetchGraphData as jest.Mock;
const panelContextValue = {
...mockContextValue,
@@ -84,6 +102,17 @@ describe('', () => {
alertIds: undefined,
statsNodes: undefined,
});
+ mockUseGraphPreview.mockReturnValue({
+ isAuditLog: true,
+ });
+ mockUseFetchGraphData.mockReturnValue({
+ isLoading: false,
+ isError: false,
+ data: {
+ nodes: [],
+ edges: [],
+ },
+ });
});
it('should render visualizations component', () => {
@@ -107,11 +136,22 @@ describe('', () => {
});
(useIsInvestigateInResolverActionEnabled as jest.Mock).mockReturnValue(true);
(useExpandSection as jest.Mock).mockReturnValue(true);
+ useIsExperimentalFeatureEnabledMock.mockReturnValue(false);
- const { getByTestId } = renderVisualizationsSection();
+ const { getByTestId, queryByTestId } = renderVisualizationsSection();
expect(getByTestId(VISUALIZATIONS_SECTION_CONTENT_TEST_ID)).toBeVisible();
expect(getByTestId(`${SESSION_PREVIEW_TEST_ID}LeftSection`)).toBeInTheDocument();
expect(getByTestId(`${ANALYZER_PREVIEW_TEST_ID}LeftSection`)).toBeInTheDocument();
+ expect(queryByTestId(`${GRAPH_PREVIEW_TEST_ID}LeftSection`)).not.toBeInTheDocument();
+ });
+
+ it('should render the graph preview component if the feature is enabled', () => {
+ (useExpandSection as jest.Mock).mockReturnValue(true);
+ useIsExperimentalFeatureEnabledMock.mockReturnValue(true);
+
+ const { getByTestId } = renderVisualizationsSection();
+
+ expect(getByTestId(`${GRAPH_PREVIEW_TEST_ID}LeftSection`)).toBeInTheDocument();
});
});
diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/visualizations_section.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/visualizations_section.tsx
index afb828ebdb4e8..c328036eece43 100644
--- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/visualizations_section.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/visualizations_section.tsx
@@ -13,6 +13,10 @@ import { AnalyzerPreviewContainer } from './analyzer_preview_container';
import { SessionPreviewContainer } from './session_preview_container';
import { ExpandableSection } from './expandable_section';
import { VISUALIZATIONS_TEST_ID } from './test_ids';
+import { GraphPreviewContainer } from './graph_preview_container';
+import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features';
+import { useDocumentDetailsContext } from '../../shared/context';
+import { useGraphPreview } from '../hooks/use_graph_preview';
const KEY = 'visualizations';
@@ -21,6 +25,17 @@ const KEY = 'visualizations';
*/
export const VisualizationsSection = memo(() => {
const expanded = useExpandSection({ title: KEY, defaultValue: false });
+ const graphVisualizationInFlyoutEnabled = useIsExperimentalFeatureEnabled(
+ 'graphVisualizationInFlyoutEnabled'
+ );
+
+ const { dataAsNestedObject, getFieldsData } = useDocumentDetailsContext();
+
+ // Decide whether to show the graph preview or not
+ const { isAuditLog: isGraphPreviewEnabled } = useGraphPreview({
+ getFieldsData,
+ ecsData: dataAsNestedObject,
+ });
return (
{
+ {graphVisualizationInFlyoutEnabled && isGraphPreviewEnabled && (
+ <>
+
+
+ >
+ )}
);
});
diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/hooks/use_fetch_graph_data.ts b/x-pack/plugins/security_solution/public/flyout/document_details/right/hooks/use_fetch_graph_data.ts
new file mode 100644
index 0000000000000..2304cfb8d4fd2
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/hooks/use_fetch_graph_data.ts
@@ -0,0 +1,83 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { useQuery } from '@tanstack/react-query';
+import type {
+ GraphRequest,
+ GraphResponse,
+} from '@kbn/cloud-security-posture-common/types/graph/latest';
+import { EVENT_GRAPH_VISUALIZATION_API } from '../../../../../common/constants';
+import { useHttp } from '../../../../common/lib/kibana';
+
+/**
+ * Interface for the input parameters of the useFetchGraphData hook.
+ */
+export interface UseFetchGraphDataParams {
+ /**
+ * The request object containing the query parameters for the graph data.
+ */
+ req: GraphRequest;
+ /**
+ * Optional configuration options for the query.
+ */
+ options?: {
+ /**
+ * If false, the query will not automatically run.
+ * Defaults to true.
+ */
+ enabled?: boolean;
+ };
+}
+
+/**
+ * Interface for the result of the useFetchGraphData hook.
+ */
+export interface UseFetchGraphDataResult {
+ /**
+ * Indicates if the query is currently loading.
+ */
+ isLoading: boolean;
+ /**
+ * Indicates if there was an error during the query.
+ */
+ isError: boolean;
+ /**
+ * The data returned from the query.
+ */
+ data?: GraphResponse;
+}
+
+/**
+ * Hook to fetch event's graph visualization data.
+ *
+ * @param params - The input parameters for the hook.
+ * @returns The result of the hook.
+ */
+export const useFetchGraphData = ({
+ req,
+ options,
+}: UseFetchGraphDataParams): UseFetchGraphDataResult => {
+ const { actorIds, eventIds, start, end } = req.query;
+ const http = useHttp();
+
+ const { isLoading, isError, data } = useQuery(
+ ['useFetchGraphData', actorIds, eventIds, start, end],
+ () => {
+ return http.post(EVENT_GRAPH_VISUALIZATION_API, {
+ version: '1',
+ body: JSON.stringify(req),
+ });
+ },
+ options
+ );
+
+ return {
+ isLoading,
+ isError,
+ data,
+ };
+};
diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/hooks/use_graph_preview.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/hooks/use_graph_preview.test.tsx
new file mode 100644
index 0000000000000..ff6118ec9b743
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/hooks/use_graph_preview.test.tsx
@@ -0,0 +1,137 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type { RenderHookResult } from '@testing-library/react-hooks';
+import { renderHook } from '@testing-library/react-hooks';
+import type { UseGraphPreviewParams, UseGraphPreviewResult } from './use_graph_preview';
+import { useGraphPreview } from './use_graph_preview';
+import type { GetFieldsData } from '../../shared/hooks/use_get_fields_data';
+import { mockFieldData } from '../../shared/mocks/mock_get_fields_data';
+
+describe('useGraphPreview', () => {
+ let hookResult: RenderHookResult;
+
+ it(`should return false when missing actor`, () => {
+ const getFieldsData: GetFieldsData = (field: string) => {
+ if (field === 'kibana.alert.original_event.id') {
+ return field;
+ }
+ return mockFieldData[field];
+ };
+
+ hookResult = renderHook((props: UseGraphPreviewParams) => useGraphPreview(props), {
+ initialProps: {
+ getFieldsData,
+ ecsData: {
+ _id: 'id',
+ event: {
+ action: ['action'],
+ },
+ },
+ },
+ });
+
+ expect(hookResult.result.current.isAuditLog).toEqual(false);
+ });
+
+ it(`should return false when missing event.action`, () => {
+ const getFieldsData: GetFieldsData = (field: string) => {
+ if (field === 'kibana.alert.original_event.id') {
+ return 'eventId';
+ } else if (field === 'actor.entity.id') {
+ return 'actorId';
+ }
+ return mockFieldData[field];
+ };
+
+ hookResult = renderHook((props: UseGraphPreviewParams) => useGraphPreview(props), {
+ initialProps: {
+ getFieldsData,
+ ecsData: {
+ _id: 'id',
+ },
+ },
+ });
+
+ expect(hookResult.result.current.isAuditLog).toEqual(false);
+ });
+
+ it(`should return false when missing original_event.id`, () => {
+ const getFieldsData: GetFieldsData = (field: string) => {
+ if (field === 'actor.entity.id') {
+ return 'actorId';
+ }
+ return mockFieldData[field];
+ };
+
+ hookResult = renderHook((props: UseGraphPreviewParams) => useGraphPreview(props), {
+ initialProps: {
+ getFieldsData,
+ ecsData: {
+ _id: 'id',
+ event: {
+ action: ['action'],
+ },
+ },
+ },
+ });
+
+ expect(hookResult.result.current.isAuditLog).toEqual(false);
+ });
+
+ it(`should return true when alert is has graph preview`, () => {
+ const getFieldsData: GetFieldsData = (field: string) => {
+ if (field === 'kibana.alert.original_event.id') {
+ return 'eventId';
+ } else if (field === 'actor.entity.id') {
+ return 'actorId';
+ }
+
+ return mockFieldData[field];
+ };
+
+ hookResult = renderHook((props: UseGraphPreviewParams) => useGraphPreview(props), {
+ initialProps: {
+ getFieldsData,
+ ecsData: {
+ _id: 'id',
+ event: {
+ action: ['action'],
+ },
+ },
+ },
+ });
+
+ expect(hookResult.result.current.isAuditLog).toEqual(true);
+ });
+
+ it(`should return true when alert is has graph preview with multiple values`, () => {
+ const getFieldsData: GetFieldsData = (field: string) => {
+ if (field === 'kibana.alert.original_event.id') {
+ return ['id1', 'id2'];
+ } else if (field === 'actor.entity.id') {
+ return ['actorId1', 'actorId2'];
+ }
+
+ return mockFieldData[field];
+ };
+
+ hookResult = renderHook((props: UseGraphPreviewParams) => useGraphPreview(props), {
+ initialProps: {
+ getFieldsData,
+ ecsData: {
+ _id: 'id',
+ event: {
+ action: ['action1', 'action2'],
+ },
+ },
+ },
+ });
+
+ expect(hookResult.result.current.isAuditLog).toEqual(true);
+ });
+});
diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/hooks/use_graph_preview.ts b/x-pack/plugins/security_solution/public/flyout/document_details/right/hooks/use_graph_preview.ts
new file mode 100644
index 0000000000000..d833c0aa86dbc
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/hooks/use_graph_preview.ts
@@ -0,0 +1,65 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs';
+import { get } from 'lodash/fp';
+import type { GetFieldsData } from '../../shared/hooks/use_get_fields_data';
+import { getFieldArray } from '../../shared/utils';
+
+export interface UseGraphPreviewParams {
+ /**
+ * Retrieves searchHit values for the provided field
+ */
+ getFieldsData: GetFieldsData;
+
+ /**
+ * An object with top level fields from the ECS object
+ */
+ ecsData: Ecs;
+}
+/**
+ * Interface for the result of the useGraphPreview hook
+ */
+export interface UseGraphPreviewResult {
+ /**
+ * Array of event IDs associated with the alert
+ */
+ eventIds: string[];
+
+ /**
+ * Array of actor entity IDs associated with the alert
+ */
+ actorIds: string[];
+
+ /**
+ * Action associated with the event
+ */
+ action: string | undefined;
+
+ /**
+ * Boolean indicating if the event is an audit log (contains event ids, actor ids and action)
+ */
+ isAuditLog: boolean;
+}
+
+/**
+ * Hook that returns the graph view configuration if the graph view is available for the alert
+ */
+export const useGraphPreview = ({
+ getFieldsData,
+ ecsData,
+}: UseGraphPreviewParams): UseGraphPreviewResult => {
+ const originalEventId = getFieldsData('kibana.alert.original_event.id');
+ const eventId = getFieldsData('event.id');
+ const eventIds = originalEventId ? getFieldArray(originalEventId) : getFieldArray(eventId);
+
+ const actorIds = getFieldArray(getFieldsData('actor.entity.id'));
+ const action = get(['event', 'action'], ecsData);
+ const isAuditLog = actorIds.length > 0 && action?.length > 0 && eventIds.length > 0;
+
+ return { eventIds, actorIds, action, isAuditLog };
+};
diff --git a/x-pack/plugins/security_solution/tsconfig.json b/x-pack/plugins/security_solution/tsconfig.json
index b6742540a8d56..75773154798ff 100644
--- a/x-pack/plugins/security_solution/tsconfig.json
+++ b/x-pack/plugins/security_solution/tsconfig.json
@@ -220,6 +220,7 @@
"@kbn/cloud-security-posture",
"@kbn/security-solution-distribution-bar",
"@kbn/cloud-security-posture-common",
+ "@kbn/cloud-security-posture-graph",
"@kbn/presentation-publishing",
"@kbn/inference-plugin",
"@kbn/entityManager-plugin",
diff --git a/x-pack/test/cloud_security_posture_functional/config.ts b/x-pack/test/cloud_security_posture_functional/config.ts
index 28283fe427949..7e80788ffccfe 100644
--- a/x-pack/test/cloud_security_posture_functional/config.ts
+++ b/x-pack/test/cloud_security_posture_functional/config.ts
@@ -38,6 +38,9 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) {
* 1. release a new package to EPR
* 2. merge the updated version number change to kibana
*/
+ `--xpack.securitySolution.enableExperimental=${JSON.stringify([
+ 'graphVisualizationInFlyoutEnabled',
+ ])}`,
`--xpack.fleet.packages.0.name=cloud_security_posture`,
`--xpack.fleet.packages.0.version=${CLOUD_SECURITY_PLUGIN_VERSION}`,
// `--xpack.fleet.registryUrl=https://localhost:8080`,
diff --git a/x-pack/test/cloud_security_posture_functional/es_archives/logs_gcp_audit/data.json b/x-pack/test/cloud_security_posture_functional/es_archives/logs_gcp_audit/data.json
new file mode 100644
index 0000000000000..5e3d4cdfdffd5
--- /dev/null
+++ b/x-pack/test/cloud_security_posture_functional/es_archives/logs_gcp_audit/data.json
@@ -0,0 +1,634 @@
+{
+ "type": "doc",
+ "value": {
+ "data_stream": "logs-gcp.audit-default",
+ "id": "1",
+ "index": ".ds-logs-gcp.audit-default-2024.10.07-000001",
+ "source": {
+ "@timestamp": "2024-09-01T12:34:56.789Z",
+ "actor": {
+ "entity": {
+ "id": "admin@example.com"
+ }
+ },
+ "client": {
+ "user": {
+ "email": "admin@example.com"
+ }
+ },
+ "cloud": {
+ "project": {
+ "id": "your-project-id"
+ },
+ "provider": "gcp"
+ },
+ "ecs": {
+ "version": "8.11.0"
+ },
+ "event": {
+ "action": "google.iam.admin.v1.CreateRole",
+ "agent_id_status": "missing",
+ "category": [
+ "session",
+ "network",
+ "configuration"
+ ],
+ "id": "kabcd1234efgh5678",
+ "ingested": "2024-10-07T17:47:35Z",
+ "kind": "event",
+ "outcome": "success",
+ "provider": "activity",
+ "type": [
+ "end",
+ "access",
+ "allowed"
+ ]
+ },
+ "gcp": {
+ "audit": {
+ "authorization_info": [
+ {
+ "granted": true,
+ "permission": "iam.roles.create",
+ "resource": "projects/your-project-id"
+ }
+ ],
+ "logentry_operation": {
+ "id": "operation-0987654321"
+ },
+ "request": {
+ "@type": "type.googleapis.com/google.iam.admin.v1.CreateRoleRequest",
+ "parent": "projects/your-project-id",
+ "role": {
+ "description": "A custom role with specific permissions",
+ "includedPermissions": [
+ "resourcemanager.projects.get",
+ "resourcemanager.projects.list"
+ ],
+ "name": "projects/your-project-id/roles/customRole",
+ "title": "Custom Role"
+ },
+ "roleId": "customRole"
+ },
+ "resource_name": "projects/your-project-id/roles/customRole",
+ "response": {
+ "@type": "type.googleapis.com/google.iam.admin.v1.Role",
+ "description": "A custom role with specific permissions",
+ "includedPermissions": [
+ "resourcemanager.projects.get",
+ "resourcemanager.projects.list"
+ ],
+ "name": "projects/your-project-id/roles/customRole",
+ "stage": "GA",
+ "title": "Custom Role"
+ },
+ "type": "type.googleapis.com/google.cloud.audit.AuditLog"
+ }
+ },
+ "log": {
+ "level": "NOTICE",
+ "logger": "projects/your-project-id/logs/cloudaudit.googleapis.com%2Factivity"
+ },
+ "related": {
+ "ip": [
+ "10.0.0.1"
+ ],
+ "user": [
+ "admin@example.com"
+ ]
+ },
+ "service": {
+ "name": "iam.googleapis.com"
+ },
+ "source": {
+ "ip": "10.0.0.1"
+ },
+ "tags": [
+ "_geoip_database_unavailable_GeoLite2-City.mmdb",
+ "_geoip_database_unavailable_GeoLite2-ASN.mmdb"
+ ],
+ "target": {
+ "entity": {
+ "id": "projects/your-project-id/roles/customRole"
+ }
+ },
+ "user_agent": {
+ "device": {
+ "name": "Other"
+ },
+ "name": "Other",
+ "original": "google-cloud-sdk/324.0.0"
+ }
+ }
+ }
+}
+
+{
+ "type": "doc",
+ "value": {
+ "data_stream": "logs-gcp.audit-default",
+ "id": "2",
+ "index": ".ds-logs-gcp.audit-default-2024.10.07-000001",
+ "source": {
+ "@timestamp": "2024-09-01T12:34:56.789Z",
+ "actor": {
+ "entity": {
+ "id": "admin2@example.com"
+ }
+ },
+ "client": {
+ "user": {
+ "email": "admin2@example.com"
+ }
+ },
+ "cloud": {
+ "project": {
+ "id": "your-project-id"
+ },
+ "provider": "gcp"
+ },
+ "ecs": {
+ "version": "8.11.0"
+ },
+ "event": {
+ "action": "google.iam.admin.v1.CreateRole",
+ "agent_id_status": "missing",
+ "category": [
+ "session",
+ "network",
+ "configuration"
+ ],
+ "id": "failed-event",
+ "ingested": "2024-10-07T17:47:35Z",
+ "kind": "event",
+ "outcome": "failed",
+ "provider": "activity",
+ "type": [
+ "end",
+ "access",
+ "allowed"
+ ]
+ },
+ "gcp": {
+ "audit": {
+ "authorization_info": [
+ {
+ "granted": true,
+ "permission": "iam.roles.create",
+ "resource": "projects/your-project-id"
+ }
+ ],
+ "logentry_operation": {
+ "id": "operation-0987654321"
+ },
+ "request": {
+ "@type": "type.googleapis.com/google.iam.admin.v1.CreateRoleRequest",
+ "parent": "projects/your-project-id",
+ "role": {
+ "description": "A custom role with specific permissions",
+ "includedPermissions": [
+ "resourcemanager.projects.get",
+ "resourcemanager.projects.list"
+ ],
+ "name": "projects/your-project-id/roles/customRole",
+ "title": "Custom Role"
+ },
+ "roleId": "customRole"
+ },
+ "resource_name": "projects/your-project-id/roles/customRole",
+ "response": {
+ "@type": "type.googleapis.com/google.iam.admin.v1.Role",
+ "description": "A custom role with specific permissions",
+ "includedPermissions": [
+ "resourcemanager.projects.get",
+ "resourcemanager.projects.list"
+ ],
+ "name": "projects/your-project-id/roles/customRole",
+ "stage": "GA",
+ "title": "Custom Role"
+ },
+ "type": "type.googleapis.com/google.cloud.audit.AuditLog"
+ }
+ },
+ "log": {
+ "level": "NOTICE",
+ "logger": "projects/your-project-id/logs/cloudaudit.googleapis.com%2Factivity"
+ },
+ "related": {
+ "ip": [
+ "10.0.0.1"
+ ],
+ "user": [
+ "admin2@example.com"
+ ]
+ },
+ "service": {
+ "name": "iam.googleapis.com"
+ },
+ "source": {
+ "ip": "10.0.0.1"
+ },
+ "tags": [
+ "_geoip_database_unavailable_GeoLite2-City.mmdb",
+ "_geoip_database_unavailable_GeoLite2-ASN.mmdb"
+ ],
+ "target": {
+ "entity": {
+ "id": "projects/your-project-id/roles/customRole"
+ }
+ },
+ "user_agent": {
+ "device": {
+ "name": "Other"
+ },
+ "name": "Other",
+ "original": "google-cloud-sdk/324.0.0"
+ }
+ }
+ }
+}
+
+{
+ "type": "doc",
+ "value": {
+ "data_stream": "logs-gcp.audit-default",
+ "id": "3",
+ "index": ".ds-logs-gcp.audit-default-2024.10.07-000001",
+ "source": {
+ "@timestamp": "2024-09-01T12:34:56.789Z",
+ "actor": {
+ "entity": {
+ "id": "admin3@example.com"
+ }
+ },
+ "client": {
+ "user": {
+ "email": "admin3@example.com"
+ }
+ },
+ "cloud": {
+ "project": {
+ "id": "your-project-id"
+ },
+ "provider": "gcp"
+ },
+ "ecs": {
+ "version": "8.11.0"
+ },
+ "event": {
+ "action": "google.iam.admin.v1.CreateRole",
+ "agent_id_status": "missing",
+ "category": [
+ "session",
+ "network",
+ "configuration"
+ ],
+ "id": "grouped-event1",
+ "ingested": "2024-10-07T17:47:35Z",
+ "kind": "event",
+ "outcome": "failed",
+ "provider": "activity",
+ "type": [
+ "end",
+ "access",
+ "allowed"
+ ]
+ },
+ "gcp": {
+ "audit": {
+ "authorization_info": [
+ {
+ "granted": true,
+ "permission": "iam.roles.create",
+ "resource": "projects/your-project-id"
+ }
+ ],
+ "logentry_operation": {
+ "id": "operation-0987654321"
+ },
+ "request": {
+ "@type": "type.googleapis.com/google.iam.admin.v1.CreateRoleRequest",
+ "parent": "projects/your-project-id",
+ "role": {
+ "description": "A custom role with specific permissions",
+ "includedPermissions": [
+ "resourcemanager.projects.get",
+ "resourcemanager.projects.list"
+ ],
+ "name": "projects/your-project-id/roles/customRole",
+ "title": "Custom Role"
+ },
+ "roleId": "customRole"
+ },
+ "resource_name": "projects/your-project-id/roles/customRole",
+ "response": {
+ "@type": "type.googleapis.com/google.iam.admin.v1.Role",
+ "description": "A custom role with specific permissions",
+ "includedPermissions": [
+ "resourcemanager.projects.get",
+ "resourcemanager.projects.list"
+ ],
+ "name": "projects/your-project-id/roles/customRole",
+ "stage": "GA",
+ "title": "Custom Role"
+ },
+ "type": "type.googleapis.com/google.cloud.audit.AuditLog"
+ }
+ },
+ "log": {
+ "level": "NOTICE",
+ "logger": "projects/your-project-id/logs/cloudaudit.googleapis.com%2Factivity"
+ },
+ "related": {
+ "ip": [
+ "10.0.0.1"
+ ],
+ "user": [
+ "admin3@example.com"
+ ]
+ },
+ "service": {
+ "name": "iam.googleapis.com"
+ },
+ "source": {
+ "ip": "10.0.0.1"
+ },
+ "tags": [
+ "_geoip_database_unavailable_GeoLite2-City.mmdb",
+ "_geoip_database_unavailable_GeoLite2-ASN.mmdb"
+ ],
+ "target": {
+ "entity": {
+ "id": "projects/your-project-id/roles/customRole"
+ }
+ },
+ "user_agent": {
+ "device": {
+ "name": "Other"
+ },
+ "name": "Other",
+ "original": "google-cloud-sdk/324.0.0"
+ }
+ }
+ }
+}
+
+{
+ "type": "doc",
+ "value": {
+ "data_stream": "logs-gcp.audit-default",
+ "id": "4",
+ "index": ".ds-logs-gcp.audit-default-2024.10.07-000001",
+ "source": {
+ "@timestamp": "2024-09-01T12:34:56.789Z",
+ "actor": {
+ "entity": {
+ "id": "admin3@example.com"
+ }
+ },
+ "client": {
+ "user": {
+ "email": "admin3@example.com"
+ }
+ },
+ "cloud": {
+ "project": {
+ "id": "your-project-id"
+ },
+ "provider": "gcp"
+ },
+ "ecs": {
+ "version": "8.11.0"
+ },
+ "event": {
+ "action": "google.iam.admin.v1.CreateRole",
+ "agent_id_status": "missing",
+ "category": [
+ "session",
+ "network",
+ "configuration"
+ ],
+ "id": "grouped-event2",
+ "ingested": "2024-10-07T17:47:35Z",
+ "kind": "event",
+ "outcome": "success",
+ "provider": "activity",
+ "type": [
+ "end",
+ "access",
+ "allowed"
+ ]
+ },
+ "gcp": {
+ "audit": {
+ "authorization_info": [
+ {
+ "granted": true,
+ "permission": "iam.roles.create",
+ "resource": "projects/your-project-id"
+ }
+ ],
+ "logentry_operation": {
+ "id": "operation-0987654321"
+ },
+ "request": {
+ "@type": "type.googleapis.com/google.iam.admin.v1.CreateRoleRequest",
+ "parent": "projects/your-project-id",
+ "role": {
+ "description": "A custom role with specific permissions",
+ "includedPermissions": [
+ "resourcemanager.projects.get",
+ "resourcemanager.projects.list"
+ ],
+ "name": "projects/your-project-id/roles/customRole",
+ "title": "Custom Role"
+ },
+ "roleId": "customRole"
+ },
+ "resource_name": "projects/your-project-id/roles/customRole",
+ "response": {
+ "@type": "type.googleapis.com/google.iam.admin.v1.Role",
+ "description": "A custom role with specific permissions",
+ "includedPermissions": [
+ "resourcemanager.projects.get",
+ "resourcemanager.projects.list"
+ ],
+ "name": "projects/your-project-id/roles/customRole",
+ "stage": "GA",
+ "title": "Custom Role"
+ },
+ "type": "type.googleapis.com/google.cloud.audit.AuditLog"
+ }
+ },
+ "log": {
+ "level": "NOTICE",
+ "logger": "projects/your-project-id/logs/cloudaudit.googleapis.com%2Factivity"
+ },
+ "related": {
+ "ip": [
+ "10.0.0.1"
+ ],
+ "user": [
+ "admin3@example.com"
+ ]
+ },
+ "service": {
+ "name": "iam.googleapis.com"
+ },
+ "source": {
+ "ip": "10.0.0.1"
+ },
+ "tags": [
+ "_geoip_database_unavailable_GeoLite2-City.mmdb",
+ "_geoip_database_unavailable_GeoLite2-ASN.mmdb"
+ ],
+ "target": {
+ "entity": {
+ "id": "projects/your-project-id/roles/customRole"
+ }
+ },
+ "user_agent": {
+ "device": {
+ "name": "Other"
+ },
+ "name": "Other",
+ "original": "google-cloud-sdk/324.0.0"
+ }
+ }
+ }
+}
+
+{
+ "type": "doc",
+ "value": {
+ "data_stream": "logs-gcp.audit-default",
+ "id": "5",
+ "index": ".ds-logs-gcp.audit-default-2024.10.07-000001",
+ "source": {
+ "@timestamp": "2024-09-01T12:34:56.789Z",
+ "actor": {
+ "entity": {
+ "id": "admin4@example.com"
+ }
+ },
+ "client": {
+ "user": {
+ "email": "admin4@example.com"
+ }
+ },
+ "cloud": {
+ "project": {
+ "id": "your-project-id"
+ },
+ "provider": "gcp"
+ },
+ "ecs": {
+ "version": "8.11.0"
+ },
+ "event": {
+ "action": "google.iam.admin.v1.CreateRole",
+ "agent_id_status": "missing",
+ "category": [
+ "session",
+ "network",
+ "configuration"
+ ],
+ "id": "host-event",
+ "ingested": "2024-10-07T17:47:35Z",
+ "kind": "event",
+ "outcome": "success",
+ "provider": "activity",
+ "type": [
+ "end",
+ "access",
+ "allowed"
+ ]
+ },
+ "gcp": {
+ "audit": {
+ "authorization_info": [
+ {
+ "granted": true,
+ "permission": "iam.roles.create",
+ "resource": "projects/your-project-id"
+ }
+ ],
+ "logentry_operation": {
+ "id": "operation-0987654321"
+ },
+ "request": {
+ "@type": "type.googleapis.com/google.iam.admin.v1.CreateRoleRequest",
+ "parent": "projects/your-project-id",
+ "role": {
+ "description": "A custom role with specific permissions",
+ "includedPermissions": [
+ "resourcemanager.projects.get",
+ "resourcemanager.projects.list"
+ ],
+ "name": "projects/your-project-id/roles/customRole",
+ "title": "Custom Role"
+ },
+ "roleId": "customRole"
+ },
+ "resource_name": "projects/your-project-id/roles/customRole",
+ "response": {
+ "@type": "type.googleapis.com/google.iam.admin.v1.Role",
+ "description": "A custom role with specific permissions",
+ "includedPermissions": [
+ "resourcemanager.projects.get",
+ "resourcemanager.projects.list"
+ ],
+ "name": "projects/your-project-id/roles/customRole",
+ "stage": "GA",
+ "title": "Custom Role"
+ },
+ "type": "type.googleapis.com/google.cloud.audit.AuditLog"
+ }
+ },
+ "host": {
+ "hostname": "host1.example.com",
+ "name": "host1.example.com",
+ "ip": "192.168.1.1",
+ "os": {
+ "name": "Linux",
+ "version": "5.4.0-42-generic"
+ }
+ },
+ "log": {
+ "level": "NOTICE",
+ "logger": "projects/your-project-id/logs/cloudaudit.googleapis.com%2Factivity"
+ },
+ "related": {
+ "ip": [
+ "10.0.0.1"
+ ],
+ "user": [
+ "admin4@example.com"
+ ]
+ },
+ "service": {
+ "name": "iam.googleapis.com"
+ },
+ "source": {
+ "ip": "10.0.0.1"
+ },
+ "tags": [
+ "_geoip_database_unavailable_GeoLite2-City.mmdb",
+ "_geoip_database_unavailable_GeoLite2-ASN.mmdb"
+ ],
+ "target": {
+ "entity": {
+ "id": "projects/your-project-id/roles/customRole"
+ }
+ },
+ "user_agent": {
+ "device": {
+ "name": "Other"
+ },
+ "name": "Other",
+ "original": "google-cloud-sdk/324.0.0"
+ }
+ }
+ }
+}
+
diff --git a/x-pack/test/cloud_security_posture_functional/es_archives/logs_gcp_audit/mappings.json b/x-pack/test/cloud_security_posture_functional/es_archives/logs_gcp_audit/mappings.json
new file mode 100644
index 0000000000000..085fc6d11d475
--- /dev/null
+++ b/x-pack/test/cloud_security_posture_functional/es_archives/logs_gcp_audit/mappings.json
@@ -0,0 +1,628 @@
+{
+ "type": "data_stream",
+ "value": {
+ "data_stream": "logs-gcp.audit-default",
+ "template": {
+ "_meta": {
+ "managed": true,
+ "managed_by": "fleet",
+ "package": {
+ "name": "gcp"
+ }
+ },
+ "data_stream": {
+ "allow_custom_routing": false,
+ "hidden": false
+ },
+ "ignore_missing_component_templates": [
+ "logs-gcp.audit@custom"
+ ],
+ "index_patterns": [
+ "logs-gcp.audit-*"
+ ],
+ "name": "logs-gcp.audit",
+ "priority": 200,
+ "template": {
+ "mappings": {
+ "_meta": {
+ "managed": true,
+ "managed_by": "fleet",
+ "package": {
+ "name": "gcp"
+ }
+ },
+ "date_detection": false,
+ "dynamic_templates": [
+ {
+ "ecs_message_match_only_text": {
+ "mapping": {
+ "type": "match_only_text"
+ },
+ "path_match": [
+ "message",
+ "*.message"
+ ],
+ "unmatch_mapping_type": "object"
+ }
+ },
+ {
+ "ecs_non_indexed_keyword": {
+ "mapping": {
+ "doc_values": false,
+ "index": false,
+ "type": "keyword"
+ },
+ "path_match": [
+ "*event.original"
+ ]
+ }
+ },
+ {
+ "ecs_non_indexed_long": {
+ "mapping": {
+ "doc_values": false,
+ "index": false,
+ "type": "long"
+ },
+ "path_match": [
+ "*.x509.public_key_exponent"
+ ]
+ }
+ },
+ {
+ "ecs_ip": {
+ "mapping": {
+ "type": "ip"
+ },
+ "match_mapping_type": "string",
+ "path_match": [
+ "ip",
+ "*.ip",
+ "*_ip"
+ ]
+ }
+ },
+ {
+ "ecs_wildcard": {
+ "mapping": {
+ "type": "wildcard"
+ },
+ "path_match": [
+ "*.io.text",
+ "*.message_id",
+ "*registry.data.strings",
+ "*url.path"
+ ],
+ "unmatch_mapping_type": "object"
+ }
+ },
+ {
+ "ecs_path_match_wildcard_and_match_only_text": {
+ "mapping": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "type": "wildcard"
+ },
+ "path_match": [
+ "*.body.content",
+ "*url.full",
+ "*url.original"
+ ],
+ "unmatch_mapping_type": "object"
+ }
+ },
+ {
+ "ecs_match_wildcard_and_match_only_text": {
+ "mapping": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "type": "wildcard"
+ },
+ "match": [
+ "*command_line",
+ "*stack_trace"
+ ],
+ "unmatch_mapping_type": "object"
+ }
+ },
+ {
+ "ecs_path_match_keyword_and_match_only_text": {
+ "mapping": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "type": "keyword"
+ },
+ "path_match": [
+ "*.title",
+ "*.executable",
+ "*.name",
+ "*.working_directory",
+ "*.full_name",
+ "*file.path",
+ "*file.target_path",
+ "*os.full",
+ "*email.subject",
+ "*vulnerability.description",
+ "*user_agent.original"
+ ],
+ "unmatch_mapping_type": "object"
+ }
+ },
+ {
+ "ecs_date": {
+ "mapping": {
+ "type": "date"
+ },
+ "path_match": [
+ "*.timestamp",
+ "*_timestamp",
+ "*.not_after",
+ "*.not_before",
+ "*.accessed",
+ "created",
+ "*.created",
+ "*.installed",
+ "*.creation_date",
+ "*.ctime",
+ "*.mtime",
+ "ingested",
+ "*.ingested",
+ "*.start",
+ "*.end",
+ "*.indicator.first_seen",
+ "*.indicator.last_seen",
+ "*.indicator.modified_at",
+ "*threat.enrichments.matched.occurred"
+ ],
+ "unmatch_mapping_type": "object"
+ }
+ },
+ {
+ "ecs_path_match_float": {
+ "mapping": {
+ "type": "float"
+ },
+ "path_match": [
+ "*.score.*",
+ "*_score*"
+ ],
+ "path_unmatch": "*.version",
+ "unmatch_mapping_type": "object"
+ }
+ },
+ {
+ "ecs_usage_double_scaled_float": {
+ "mapping": {
+ "scaling_factor": 1000,
+ "type": "scaled_float"
+ },
+ "match_mapping_type": [
+ "double",
+ "long",
+ "string"
+ ],
+ "path_match": "*.usage"
+ }
+ },
+ {
+ "ecs_geo_point": {
+ "mapping": {
+ "type": "geo_point"
+ },
+ "path_match": [
+ "*.geo.location"
+ ]
+ }
+ },
+ {
+ "ecs_flattened": {
+ "mapping": {
+ "type": "flattened"
+ },
+ "match_mapping_type": "object",
+ "path_match": [
+ "*structured_data",
+ "*exports",
+ "*imports"
+ ]
+ }
+ },
+ {
+ "all_strings_to_keywords": {
+ "mapping": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "match_mapping_type": "string"
+ }
+ }
+ ],
+ "properties": {
+ "@timestamp": {
+ "ignore_malformed": false,
+ "type": "date"
+ },
+ "cloud": {
+ "properties": {
+ "image": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "data_stream": {
+ "properties": {
+ "dataset": {
+ "type": "constant_keyword"
+ },
+ "namespace": {
+ "type": "constant_keyword"
+ },
+ "type": {
+ "type": "constant_keyword"
+ }
+ }
+ },
+ "data_stream.dataset": {
+ "type": "constant_keyword"
+ },
+ "data_stream.namespace": {
+ "type": "constant_keyword"
+ },
+ "data_stream.type": {
+ "type": "constant_keyword",
+ "value": "logs"
+ },
+ "event": {
+ "properties": {
+ "agent_id_status": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "dataset": {
+ "type": "constant_keyword",
+ "value": "gcp.audit"
+ },
+ "ingested": {
+ "format": "strict_date_time_no_millis||strict_date_optional_time||epoch_millis",
+ "ignore_malformed": false,
+ "type": "date"
+ },
+ "module": {
+ "type": "constant_keyword",
+ "value": "gcp"
+ }
+ }
+ },
+ "gcp": {
+ "properties": {
+ "audit": {
+ "properties": {
+ "authentication_info": {
+ "properties": {
+ "authority_selector": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "principal_email": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "principal_subject": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "service_account_delegation_info": {
+ "type": "flattened"
+ },
+ "service_account_key_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "third_party_principal": {
+ "type": "flattened"
+ }
+ }
+ },
+ "authorization_info": {
+ "properties": {
+ "granted": {
+ "type": "boolean"
+ },
+ "permission": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "resource": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "resource_attributes": {
+ "properties": {
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "service": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ },
+ "type": "nested"
+ },
+ "flattened": {
+ "type": "flattened"
+ },
+ "labels": {
+ "type": "flattened"
+ },
+ "logentry_operation": {
+ "properties": {
+ "first": {
+ "type": "boolean"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "last": {
+ "type": "boolean"
+ },
+ "producer": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "metadata": {
+ "type": "flattened"
+ },
+ "method_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "num_response_items": {
+ "type": "long"
+ },
+ "policy_violation_info": {
+ "properties": {
+ "payload": {
+ "type": "flattened"
+ },
+ "resource_tags": {
+ "type": "flattened"
+ },
+ "resource_type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "violations": {
+ "properties": {
+ "checkedValue": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "constraint": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "errorMessage": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "policyType": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ },
+ "type": "nested"
+ }
+ }
+ },
+ "request": {
+ "type": "flattened"
+ },
+ "request_metadata": {
+ "properties": {
+ "caller_ip": {
+ "type": "ip"
+ },
+ "caller_supplied_user_agent": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "raw": {
+ "properties": {
+ "caller_ip": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "resource_location": {
+ "properties": {
+ "current_locations": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "resource_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "response": {
+ "type": "flattened"
+ },
+ "service_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "status": {
+ "properties": {
+ "code": {
+ "type": "long"
+ },
+ "details": {
+ "type": "flattened"
+ },
+ "message": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "destination": {
+ "properties": {
+ "instance": {
+ "properties": {
+ "project_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "region": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "zone": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "vpc": {
+ "properties": {
+ "project_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "subnetwork_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "vpc_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "source": {
+ "properties": {
+ "instance": {
+ "properties": {
+ "project_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "region": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "zone": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "vpc": {
+ "properties": {
+ "project_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "subnetwork_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "vpc_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "host": {
+ "properties": {
+ "containerized": {
+ "type": "boolean"
+ },
+ "os": {
+ "properties": {
+ "build": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "codename": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "input": {
+ "properties": {
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "log": {
+ "properties": {
+ "offset": {
+ "type": "long"
+ }
+ }
+ }
+ }
+ },
+ "settings": {
+ "index": {
+ "codec": "best_compression",
+ "final_pipeline": ".fleet_final_pipeline-1",
+ "mapping": {
+ "ignore_malformed": "true",
+ "total_fields": {
+ "ignore_dynamic_beyond_limit": "true",
+ "limit": "1000"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/x-pack/test/cloud_security_posture_functional/es_archives/security_alerts/data.json.gz b/x-pack/test/cloud_security_posture_functional/es_archives/security_alerts/data.json.gz
new file mode 100644
index 0000000000000000000000000000000000000000..93b2c20b81c86a7cd2edc5006f73c3668bf404a1
GIT binary patch
literal 3143
zcma)2c{mde1D0bb$>_H*M{<_*bCZ$Wi8;&Bl!#@M|lyjJJA9Kt#
zx7gS;OXQy8`+eVE-}m45{`EfZ`@HY-KCd{2i{;;76=1-;{ASeok8_;Ei00nY38qQ>
z+xj78LtZL5>Ry=#sDQ?P#Lb777tL9DSo&V5?5}IET*i9mFL$)ytFukPKGlI!oK5FI
zlL13~!mCX@#`3E9=(s_`Immm;O8P&dzDGyNz7{O%hXU1KkEI6}Y562GUtO&TV`q;v^oZs_+;pr4x5$Fu;p%t?jN^M>Rs;S5{@RSBYMbF1
zN9)(aTn+Gp&pR_NOBqFRp{MFK2l$`G-ZJ6D?k=CS=+b1k**??z{5Zap3fmBp&kbMm
zy=R|ey5W2g7fcJdlx}f(QSqL2h}~$_qcL8e8i}crae2PG>wcUzO5dU3g>>d;5)n?i
z2Qc@a@{sJ1IhDRRRy!IHfDe{9(xowH8iVxcaYstQaB#Ci941AYQwXfTp=Cp=^F1W`WTkz
zVgY>Kbzk>g9R(J_R>B^f<}L491Mk0satsJe&V1a|qh!X6y|TV8kvB$*Q5rz6^Hj($
z^tU{K$^59n3pbQb9HvPv0j}_&M!o!YGkqX>o$4a8yG?`U1qqx@=(Dp+PTrAjx-f$Z
zp|?hlYD#4Oc{t-jd6_%!nND$mIksDbP?(`?8%`ej2dfRy5_!HIev
zsa$LigX%#-sXy+i$yl*cFa8Kz^i|5`7>#viEQdfVBkHfq&DrgA&SSGqaGl2OLbhFB
z-^RAef{IgzJ3L)tTThKSSR_qc?HdI2RP=4j`g4E-yH%
zv@T3g*3=>lU%{oOXYPJS^s&-`wwF#a08m=-L<2zKTeY-n;oYu>3|C^m<%^{{(uP;_JNaVIycoIPW
zhOoF~;YJrS@YVd`7T>dKjRdEo-}kpdL_>F_lCQ`D!OJ49n_=piT=at+x+R_G
zOErMQ7BR2}-6ia_?=_R*PG_ay81CLJ3gS!8kK!%eU$)%aNiBQ*(-ewZedL`Y<~lX=
zIo)@s?nx36@RyeWQRZw&&mJ5sHZgxjbf|Sxwj5EFIWX6$tX+4^Uv;Ir)`60
z{ASFWVPB#fnRQc#bVx5iJKLnPx(B_ffNvcxN#nFb!>&9Po>J&x4|p3NRZ6eDq@P*J
zj*-+4VqLbYM9pc0jHG#z&i;Pqb0aR!!sEeIFSF#20q-VnOW#|ql>84ru2`P=CI>)N
zKB{o8!#H+MDXH6$>>oF;3XEK=Y>Q6>$#D$tcEqw-jnj6bq`8;$
z3%IOutj{>V_e^pf;Ic?|oi?O!8*x8G*1(e)4y<6v-5x&7CjeTyqY;rGLr^2HJ=SB+7g^L#EKmMqyQR25arY%pC-!98YWD_X-|s7V
zyCy&IH#5Ww(|mjH0Tud&9D
zYuT1>H1y!tY?UsFs=QAqy@-78ciIL)xJ(8YKhsN?o0yZAm#E$%v16b<9*CW3g2{r}
zJ>+NuO)jO4f>X6WLgfePZso>aKRd2$Z4$Mw{+OSp1y3C2Gz@|AQDpF
z1?74+Gy#*vpvfT)xlHZ$liJav-Xmc43-AYKo+I;%g-;sx$&ixn(^&$}tut^n2s7zd
zV);mxOX5Y^*Vx5w%<>bZGvUi_N=S9Dxph$99Xcyr1|Me^Nu>``=Roy+bLrWq{htP%
zjDyx(4(S~c{ij!khDn9z42<}f37Uvbo3w|BrT1yqiH+=U;;Q2z^Wmh9UM@Z$B1#Rj
z(}-+QQ=VW>7=K}NbkchJ=DZ$>#F-BBj%The{9P>pRmZ}U%hT;E@%mJI`_RU{qDaB7
z?zc#DP?zEIKXziZfNrxv)ppa~3|um`kgU=c>>OR&MVW?T(|(+86uMAgMb5AHIXQ|3
zd|6)e;uS4D3Sh|R_=@4}o3LI`itKwuvqQtd+MjrNEyNWjv9y}uH`{E4a&A@9B>t`a
zNw2v3?7>K&Zy`fFw=Hv2_mf(a#`+C`Y7itbnfS(5_hUl&X1*Ij)c!y^>pC4(v>2>+
z5()KbNJg(vYMN((r~gQ?uRy(9A$AsJ>sL{zz8Z}$+X)ml@~qO`uDHS*U-v$%Q4LDR
zaxRWY9`#_6%?O8mvn1Cp`%Yl}>BhgIhKEGs-|x69yIY@UCzX$c+P=P4g}zI5JZ#=S
zSm{Gy|3Vt(*}_S@d1@;@nUy*#2qr5P;qr$Z4k!QGEy3u3B(>(~rGwiDCr?Hs^g=Z=
z(p+5!{)HU2L2h3XCp{>B(%l`=@p3a)xbzdxZ~T9alU!+kGlgE~XgxYt$BVJm)KGa;~s?O#B(l_r&~X)Am;-ruJGk9e!Ra2-oQ_3Y~#
zM^;kJB
zU3K&Ed}^Q~HmKF2Hk{kkHb9IJjg0;Ho`j5k
zCOm>*!IRrBJwq3oWDmFhFlY4!jwqhi))M`n#D9hVZ@R~@hiC`FHhYlKvM5*W|7;Fj
VLPjs>Eq*^?iI?8NxVx~h{0rLzLWckV
literal 0
HcmV?d00001
diff --git a/x-pack/test/cloud_security_posture_functional/es_archives/security_alerts/mappings.json b/x-pack/test/cloud_security_posture_functional/es_archives/security_alerts/mappings.json
new file mode 100644
index 0000000000000..d13b6edbd768f
--- /dev/null
+++ b/x-pack/test/cloud_security_posture_functional/es_archives/security_alerts/mappings.json
@@ -0,0 +1,8667 @@
+{
+ "type": "index",
+ "value": {
+ "aliases": {
+ ".alerts-security.alerts-default": {
+ "is_write_index": true
+ },
+ ".siem-signals-default": {
+ "is_write_index": false
+ }
+ },
+ "index": ".internal.alerts-security.alerts-default-000001",
+ "mappings": {
+ "_meta": {
+ "kibana": {
+ "version": "9.0.0"
+ },
+ "managed": true,
+ "namespace": "default"
+ },
+ "dynamic": "false",
+ "properties": {
+ "@timestamp": {
+ "ignore_malformed": false,
+ "type": "date"
+ },
+ "agent": {
+ "properties": {
+ "build": {
+ "properties": {
+ "original": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "ephemeral_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "client": {
+ "properties": {
+ "address": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "as": {
+ "properties": {
+ "number": {
+ "type": "long"
+ },
+ "organization": {
+ "properties": {
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "bytes": {
+ "type": "long"
+ },
+ "domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "geo": {
+ "properties": {
+ "city_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "continent_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "continent_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country_iso_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "location": {
+ "type": "geo_point"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "postal_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "region_iso_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "region_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "timezone": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "ip": {
+ "type": "ip"
+ },
+ "mac": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "nat": {
+ "properties": {
+ "ip": {
+ "type": "ip"
+ },
+ "port": {
+ "type": "long"
+ }
+ }
+ },
+ "packets": {
+ "type": "long"
+ },
+ "port": {
+ "type": "long"
+ },
+ "registered_domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "subdomain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "top_level_domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "user": {
+ "properties": {
+ "domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "email": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "full_name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "group": {
+ "properties": {
+ "domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "roles": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "cloud": {
+ "properties": {
+ "account": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "availability_zone": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "instance": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "machine": {
+ "properties": {
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "origin": {
+ "properties": {
+ "account": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "availability_zone": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "instance": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "machine": {
+ "properties": {
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "project": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "provider": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "region": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "service": {
+ "properties": {
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "project": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "provider": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "region": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "service": {
+ "properties": {
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "target": {
+ "properties": {
+ "account": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "availability_zone": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "instance": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "machine": {
+ "properties": {
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "project": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "provider": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "region": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "service": {
+ "properties": {
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "container": {
+ "properties": {
+ "cpu": {
+ "properties": {
+ "usage": {
+ "scaling_factor": 1000,
+ "type": "scaled_float"
+ }
+ }
+ },
+ "disk": {
+ "properties": {
+ "read": {
+ "properties": {
+ "bytes": {
+ "type": "long"
+ }
+ }
+ },
+ "write": {
+ "properties": {
+ "bytes": {
+ "type": "long"
+ }
+ }
+ }
+ }
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "image": {
+ "properties": {
+ "hash": {
+ "properties": {
+ "all": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "tag": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "labels": {
+ "type": "object"
+ },
+ "memory": {
+ "properties": {
+ "usage": {
+ "scaling_factor": 1000,
+ "type": "scaled_float"
+ }
+ }
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "network": {
+ "properties": {
+ "egress": {
+ "properties": {
+ "bytes": {
+ "type": "long"
+ }
+ }
+ },
+ "ingress": {
+ "properties": {
+ "bytes": {
+ "type": "long"
+ }
+ }
+ }
+ }
+ },
+ "runtime": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "security_context": {
+ "properties": {
+ "privileged": {
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ },
+ "destination": {
+ "properties": {
+ "address": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "as": {
+ "properties": {
+ "number": {
+ "type": "long"
+ },
+ "organization": {
+ "properties": {
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "bytes": {
+ "type": "long"
+ },
+ "domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "geo": {
+ "properties": {
+ "city_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "continent_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "continent_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country_iso_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "location": {
+ "type": "geo_point"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "postal_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "region_iso_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "region_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "timezone": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "ip": {
+ "type": "ip"
+ },
+ "mac": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "nat": {
+ "properties": {
+ "ip": {
+ "type": "ip"
+ },
+ "port": {
+ "type": "long"
+ }
+ }
+ },
+ "packets": {
+ "type": "long"
+ },
+ "port": {
+ "type": "long"
+ },
+ "registered_domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "subdomain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "top_level_domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "user": {
+ "properties": {
+ "domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "email": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "full_name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "group": {
+ "properties": {
+ "domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "roles": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "device": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "manufacturer": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "model": {
+ "properties": {
+ "identifier": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "dll": {
+ "properties": {
+ "code_signature": {
+ "properties": {
+ "digest_algorithm": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "exists": {
+ "type": "boolean"
+ },
+ "signing_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "status": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "subject_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "team_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "timestamp": {
+ "type": "date"
+ },
+ "trusted": {
+ "type": "boolean"
+ },
+ "valid": {
+ "type": "boolean"
+ }
+ }
+ },
+ "hash": {
+ "properties": {
+ "md5": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha1": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha256": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha384": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha512": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "ssdeep": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "tlsh": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "path": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "pe": {
+ "properties": {
+ "architecture": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "company": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "description": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "file_version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "go_import_hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "go_imports": {
+ "type": "flattened"
+ },
+ "go_imports_names_entropy": {
+ "type": "long"
+ },
+ "go_imports_names_var_entropy": {
+ "type": "long"
+ },
+ "go_stripped": {
+ "type": "boolean"
+ },
+ "imphash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "import_hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "imports": {
+ "type": "flattened"
+ },
+ "imports_names_entropy": {
+ "type": "long"
+ },
+ "imports_names_var_entropy": {
+ "type": "long"
+ },
+ "original_file_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "pehash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "product": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sections": {
+ "properties": {
+ "entropy": {
+ "type": "long"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "physical_size": {
+ "type": "long"
+ },
+ "var_entropy": {
+ "type": "long"
+ },
+ "virtual_size": {
+ "type": "long"
+ }
+ },
+ "type": "nested"
+ }
+ }
+ }
+ }
+ },
+ "dns": {
+ "properties": {
+ "answers": {
+ "properties": {
+ "class": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "data": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "ttl": {
+ "type": "long"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "header_flags": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "op_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "question": {
+ "properties": {
+ "class": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "registered_domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "subdomain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "top_level_domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "resolved_ip": {
+ "type": "ip"
+ },
+ "response_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "ecs": {
+ "properties": {
+ "version": {
+ "type": "keyword"
+ }
+ }
+ },
+ "email": {
+ "properties": {
+ "attachments": {
+ "properties": {
+ "file": {
+ "properties": {
+ "extension": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "hash": {
+ "properties": {
+ "md5": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha1": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha256": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha384": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha512": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "ssdeep": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "tlsh": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "mime_type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "size": {
+ "type": "long"
+ }
+ }
+ }
+ },
+ "type": "nested"
+ },
+ "bcc": {
+ "properties": {
+ "address": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "cc": {
+ "properties": {
+ "address": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "content_type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "delivery_timestamp": {
+ "type": "date"
+ },
+ "direction": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "from": {
+ "properties": {
+ "address": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "local_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "message_id": {
+ "type": "wildcard"
+ },
+ "origination_timestamp": {
+ "type": "date"
+ },
+ "reply_to": {
+ "properties": {
+ "address": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "sender": {
+ "properties": {
+ "address": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "subject": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "to": {
+ "properties": {
+ "address": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "x_mailer": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "error": {
+ "properties": {
+ "code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "message": {
+ "type": "match_only_text"
+ },
+ "stack_trace": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "type": "wildcard"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "event": {
+ "properties": {
+ "action": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "agent_id_status": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "category": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "created": {
+ "type": "date"
+ },
+ "dataset": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "duration": {
+ "type": "long"
+ },
+ "end": {
+ "type": "date"
+ },
+ "hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "ingested": {
+ "type": "date"
+ },
+ "kind": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "module": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "original": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "outcome": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "provider": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "reason": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "reference": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "risk_score": {
+ "type": "float"
+ },
+ "risk_score_norm": {
+ "type": "float"
+ },
+ "sequence": {
+ "type": "long"
+ },
+ "severity": {
+ "type": "long"
+ },
+ "start": {
+ "type": "date"
+ },
+ "timezone": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "url": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "faas": {
+ "properties": {
+ "coldstart": {
+ "type": "boolean"
+ },
+ "execution": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "file": {
+ "properties": {
+ "accessed": {
+ "type": "date"
+ },
+ "attributes": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "code_signature": {
+ "properties": {
+ "digest_algorithm": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "exists": {
+ "type": "boolean"
+ },
+ "signing_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "status": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "subject_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "team_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "timestamp": {
+ "type": "date"
+ },
+ "trusted": {
+ "type": "boolean"
+ },
+ "valid": {
+ "type": "boolean"
+ }
+ }
+ },
+ "created": {
+ "type": "date"
+ },
+ "ctime": {
+ "type": "date"
+ },
+ "device": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "directory": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "drive_letter": {
+ "ignore_above": 1,
+ "type": "keyword"
+ },
+ "elf": {
+ "properties": {
+ "architecture": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "byte_order": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "cpu_type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "creation_date": {
+ "type": "date"
+ },
+ "exports": {
+ "type": "flattened"
+ },
+ "go_import_hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "go_imports": {
+ "type": "flattened"
+ },
+ "go_imports_names_entropy": {
+ "type": "long"
+ },
+ "go_imports_names_var_entropy": {
+ "type": "long"
+ },
+ "go_stripped": {
+ "type": "boolean"
+ },
+ "header": {
+ "properties": {
+ "abi_version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "class": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "data": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "entrypoint": {
+ "type": "long"
+ },
+ "object_version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "os_abi": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "import_hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "imports": {
+ "type": "flattened"
+ },
+ "imports_names_entropy": {
+ "type": "long"
+ },
+ "imports_names_var_entropy": {
+ "type": "long"
+ },
+ "sections": {
+ "properties": {
+ "chi2": {
+ "type": "long"
+ },
+ "entropy": {
+ "type": "long"
+ },
+ "flags": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "physical_offset": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "physical_size": {
+ "type": "long"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "var_entropy": {
+ "type": "long"
+ },
+ "virtual_address": {
+ "type": "long"
+ },
+ "virtual_size": {
+ "type": "long"
+ }
+ },
+ "type": "nested"
+ },
+ "segments": {
+ "properties": {
+ "sections": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ },
+ "type": "nested"
+ },
+ "shared_libraries": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "telfhash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "extension": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "fork_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "gid": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "group": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "hash": {
+ "properties": {
+ "md5": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha1": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha256": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha384": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha512": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "ssdeep": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "tlsh": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "inode": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "macho": {
+ "properties": {
+ "go_import_hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "go_imports": {
+ "type": "flattened"
+ },
+ "go_imports_names_entropy": {
+ "type": "long"
+ },
+ "go_imports_names_var_entropy": {
+ "type": "long"
+ },
+ "go_stripped": {
+ "type": "boolean"
+ },
+ "import_hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "imports": {
+ "type": "flattened"
+ },
+ "imports_names_entropy": {
+ "type": "long"
+ },
+ "imports_names_var_entropy": {
+ "type": "long"
+ },
+ "sections": {
+ "properties": {
+ "entropy": {
+ "type": "long"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "physical_size": {
+ "type": "long"
+ },
+ "var_entropy": {
+ "type": "long"
+ },
+ "virtual_size": {
+ "type": "long"
+ }
+ },
+ "type": "nested"
+ },
+ "symhash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "mime_type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "mode": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "mtime": {
+ "type": "date"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "owner": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "path": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "pe": {
+ "properties": {
+ "architecture": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "company": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "description": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "file_version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "go_import_hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "go_imports": {
+ "type": "flattened"
+ },
+ "go_imports_names_entropy": {
+ "type": "long"
+ },
+ "go_imports_names_var_entropy": {
+ "type": "long"
+ },
+ "go_stripped": {
+ "type": "boolean"
+ },
+ "imphash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "import_hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "imports": {
+ "type": "flattened"
+ },
+ "imports_names_entropy": {
+ "type": "long"
+ },
+ "imports_names_var_entropy": {
+ "type": "long"
+ },
+ "original_file_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "pehash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "product": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sections": {
+ "properties": {
+ "entropy": {
+ "type": "long"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "physical_size": {
+ "type": "long"
+ },
+ "var_entropy": {
+ "type": "long"
+ },
+ "virtual_size": {
+ "type": "long"
+ }
+ },
+ "type": "nested"
+ }
+ }
+ },
+ "size": {
+ "type": "long"
+ },
+ "target_path": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "uid": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "x509": {
+ "properties": {
+ "alternative_names": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "issuer": {
+ "properties": {
+ "common_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "distinguished_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "locality": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "organization": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "organizational_unit": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "state_or_province": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "not_after": {
+ "type": "date"
+ },
+ "not_before": {
+ "type": "date"
+ },
+ "public_key_algorithm": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "public_key_curve": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "public_key_exponent": {
+ "type": "long"
+ },
+ "public_key_size": {
+ "type": "long"
+ },
+ "serial_number": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "signature_algorithm": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "subject": {
+ "properties": {
+ "common_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "distinguished_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "locality": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "organization": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "organizational_unit": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "state_or_province": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "version_number": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "group": {
+ "properties": {
+ "domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "host": {
+ "properties": {
+ "architecture": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "asset": {
+ "properties": {
+ "criticality": {
+ "type": "keyword"
+ }
+ }
+ },
+ "boot": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "cpu": {
+ "properties": {
+ "usage": {
+ "scaling_factor": 1000,
+ "type": "scaled_float"
+ }
+ }
+ },
+ "disk": {
+ "properties": {
+ "read": {
+ "properties": {
+ "bytes": {
+ "type": "long"
+ }
+ }
+ },
+ "write": {
+ "properties": {
+ "bytes": {
+ "type": "long"
+ }
+ }
+ }
+ }
+ },
+ "domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "geo": {
+ "properties": {
+ "city_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "continent_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "continent_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country_iso_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "location": {
+ "type": "geo_point"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "postal_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "region_iso_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "region_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "timezone": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "hostname": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "ip": {
+ "type": "ip"
+ },
+ "mac": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "network": {
+ "properties": {
+ "egress": {
+ "properties": {
+ "bytes": {
+ "type": "long"
+ },
+ "packets": {
+ "type": "long"
+ }
+ }
+ },
+ "ingress": {
+ "properties": {
+ "bytes": {
+ "type": "long"
+ },
+ "packets": {
+ "type": "long"
+ }
+ }
+ }
+ }
+ },
+ "os": {
+ "properties": {
+ "family": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "full": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "kernel": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "platform": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "pid_ns_ino": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "risk": {
+ "properties": {
+ "calculated_level": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "calculated_score": {
+ "type": "float"
+ },
+ "calculated_score_norm": {
+ "type": "float"
+ },
+ "static_level": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "static_score": {
+ "type": "float"
+ },
+ "static_score_norm": {
+ "type": "float"
+ }
+ }
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "uptime": {
+ "type": "long"
+ }
+ }
+ },
+ "http": {
+ "properties": {
+ "request": {
+ "properties": {
+ "body": {
+ "properties": {
+ "bytes": {
+ "type": "long"
+ },
+ "content": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "type": "wildcard"
+ }
+ }
+ },
+ "bytes": {
+ "type": "long"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "method": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "mime_type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "referrer": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "response": {
+ "properties": {
+ "body": {
+ "properties": {
+ "bytes": {
+ "type": "long"
+ },
+ "content": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "type": "wildcard"
+ }
+ }
+ },
+ "bytes": {
+ "type": "long"
+ },
+ "mime_type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "status_code": {
+ "type": "long"
+ }
+ }
+ },
+ "version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "kibana": {
+ "properties": {
+ "alert": {
+ "properties": {
+ "action_group": {
+ "type": "keyword"
+ },
+ "ancestors": {
+ "properties": {
+ "depth": {
+ "type": "long"
+ },
+ "id": {
+ "type": "keyword"
+ },
+ "index": {
+ "type": "keyword"
+ },
+ "rule": {
+ "type": "keyword"
+ },
+ "type": {
+ "type": "keyword"
+ }
+ }
+ },
+ "building_block_type": {
+ "type": "keyword"
+ },
+ "case_ids": {
+ "type": "keyword"
+ },
+ "consecutive_matches": {
+ "type": "long"
+ },
+ "depth": {
+ "type": "long"
+ },
+ "duration": {
+ "properties": {
+ "us": {
+ "type": "long"
+ }
+ }
+ },
+ "end": {
+ "type": "date"
+ },
+ "flapping": {
+ "type": "boolean"
+ },
+ "flapping_history": {
+ "type": "boolean"
+ },
+ "group": {
+ "properties": {
+ "id": {
+ "type": "keyword"
+ },
+ "index": {
+ "type": "integer"
+ }
+ }
+ },
+ "host": {
+ "properties": {
+ "criticality_level": {
+ "type": "keyword"
+ }
+ }
+ },
+ "instance": {
+ "properties": {
+ "id": {
+ "type": "keyword"
+ }
+ }
+ },
+ "intended_timestamp": {
+ "type": "date"
+ },
+ "last_detected": {
+ "type": "date"
+ },
+ "maintenance_window_ids": {
+ "type": "keyword"
+ },
+ "new_terms": {
+ "type": "keyword"
+ },
+ "original_event": {
+ "properties": {
+ "action": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "agent_id_status": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "category": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "created": {
+ "type": "date"
+ },
+ "dataset": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "duration": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "end": {
+ "type": "date"
+ },
+ "hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "ingested": {
+ "type": "date"
+ },
+ "kind": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "module": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "original": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "outcome": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "provider": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "reason": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "reference": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "risk_score": {
+ "type": "float"
+ },
+ "risk_score_norm": {
+ "type": "float"
+ },
+ "sequence": {
+ "type": "long"
+ },
+ "severity": {
+ "type": "long"
+ },
+ "start": {
+ "type": "date"
+ },
+ "timezone": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "url": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "original_time": {
+ "type": "date"
+ },
+ "previous_action_group": {
+ "type": "keyword"
+ },
+ "reason": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "type": "keyword"
+ },
+ "risk_score": {
+ "type": "float"
+ },
+ "rule": {
+ "properties": {
+ "author": {
+ "type": "keyword"
+ },
+ "building_block_type": {
+ "type": "keyword"
+ },
+ "category": {
+ "type": "keyword"
+ },
+ "consumer": {
+ "type": "keyword"
+ },
+ "created_at": {
+ "type": "date"
+ },
+ "created_by": {
+ "type": "keyword"
+ },
+ "description": {
+ "type": "keyword"
+ },
+ "enabled": {
+ "type": "keyword"
+ },
+ "exceptions_list": {
+ "type": "object"
+ },
+ "execution": {
+ "properties": {
+ "timestamp": {
+ "type": "date"
+ },
+ "uuid": {
+ "type": "keyword"
+ }
+ }
+ },
+ "false_positives": {
+ "type": "keyword"
+ },
+ "from": {
+ "type": "keyword"
+ },
+ "immutable": {
+ "type": "keyword"
+ },
+ "interval": {
+ "type": "keyword"
+ },
+ "license": {
+ "type": "keyword"
+ },
+ "max_signals": {
+ "type": "long"
+ },
+ "name": {
+ "type": "keyword"
+ },
+ "note": {
+ "type": "keyword"
+ },
+ "parameters": {
+ "ignore_above": 4096,
+ "type": "flattened"
+ },
+ "producer": {
+ "type": "keyword"
+ },
+ "references": {
+ "type": "keyword"
+ },
+ "revision": {
+ "type": "long"
+ },
+ "rule_id": {
+ "type": "keyword"
+ },
+ "rule_name_override": {
+ "type": "keyword"
+ },
+ "rule_type_id": {
+ "type": "keyword"
+ },
+ "tags": {
+ "type": "keyword"
+ },
+ "threat": {
+ "properties": {
+ "framework": {
+ "type": "keyword"
+ },
+ "tactic": {
+ "properties": {
+ "id": {
+ "type": "keyword"
+ },
+ "name": {
+ "type": "keyword"
+ },
+ "reference": {
+ "type": "keyword"
+ }
+ }
+ },
+ "technique": {
+ "properties": {
+ "id": {
+ "type": "keyword"
+ },
+ "name": {
+ "type": "keyword"
+ },
+ "reference": {
+ "type": "keyword"
+ },
+ "subtechnique": {
+ "properties": {
+ "id": {
+ "type": "keyword"
+ },
+ "name": {
+ "type": "keyword"
+ },
+ "reference": {
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "timeline_id": {
+ "type": "keyword"
+ },
+ "timeline_title": {
+ "type": "keyword"
+ },
+ "timestamp_override": {
+ "type": "keyword"
+ },
+ "to": {
+ "type": "keyword"
+ },
+ "type": {
+ "type": "keyword"
+ },
+ "updated_at": {
+ "type": "date"
+ },
+ "updated_by": {
+ "type": "keyword"
+ },
+ "uuid": {
+ "type": "keyword"
+ },
+ "version": {
+ "type": "keyword"
+ }
+ }
+ },
+ "severity": {
+ "type": "keyword"
+ },
+ "severity_improving": {
+ "type": "boolean"
+ },
+ "start": {
+ "type": "date"
+ },
+ "status": {
+ "type": "keyword"
+ },
+ "suppression": {
+ "properties": {
+ "docs_count": {
+ "type": "long"
+ },
+ "end": {
+ "type": "date"
+ },
+ "start": {
+ "type": "date"
+ },
+ "terms": {
+ "properties": {
+ "field": {
+ "type": "keyword"
+ },
+ "value": {
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "system_status": {
+ "type": "keyword"
+ },
+ "threshold_result": {
+ "properties": {
+ "cardinality": {
+ "properties": {
+ "field": {
+ "type": "keyword"
+ },
+ "value": {
+ "type": "long"
+ }
+ }
+ },
+ "count": {
+ "type": "long"
+ },
+ "from": {
+ "type": "date"
+ },
+ "terms": {
+ "properties": {
+ "field": {
+ "type": "keyword"
+ },
+ "value": {
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "time_range": {
+ "format": "epoch_millis||strict_date_optional_time",
+ "type": "date_range"
+ },
+ "url": {
+ "ignore_above": 2048,
+ "index": false,
+ "type": "keyword"
+ },
+ "user": {
+ "properties": {
+ "criticality_level": {
+ "type": "keyword"
+ }
+ }
+ },
+ "uuid": {
+ "type": "keyword"
+ },
+ "workflow_assignee_ids": {
+ "type": "keyword"
+ },
+ "workflow_reason": {
+ "type": "keyword"
+ },
+ "workflow_status": {
+ "type": "keyword"
+ },
+ "workflow_status_updated_at": {
+ "type": "date"
+ },
+ "workflow_tags": {
+ "type": "keyword"
+ },
+ "workflow_user": {
+ "type": "keyword"
+ }
+ }
+ },
+ "space_ids": {
+ "type": "keyword"
+ },
+ "version": {
+ "type": "version"
+ }
+ }
+ },
+ "labels": {
+ "type": "object"
+ },
+ "log": {
+ "properties": {
+ "file": {
+ "properties": {
+ "path": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "level": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "logger": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "origin": {
+ "properties": {
+ "file": {
+ "properties": {
+ "line": {
+ "type": "long"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "function": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "syslog": {
+ "properties": {
+ "appname": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "facility": {
+ "properties": {
+ "code": {
+ "type": "long"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "hostname": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "msgid": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "priority": {
+ "type": "long"
+ },
+ "procid": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "severity": {
+ "properties": {
+ "code": {
+ "type": "long"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "structured_data": {
+ "type": "flattened"
+ },
+ "version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "message": {
+ "type": "match_only_text"
+ },
+ "network": {
+ "properties": {
+ "application": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "bytes": {
+ "type": "long"
+ },
+ "community_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "direction": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "forwarded_ip": {
+ "type": "ip"
+ },
+ "iana_number": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "inner": {
+ "properties": {
+ "vlan": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "packets": {
+ "type": "long"
+ },
+ "protocol": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "transport": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "vlan": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "observer": {
+ "properties": {
+ "egress": {
+ "properties": {
+ "interface": {
+ "properties": {
+ "alias": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "vlan": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "zone": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "geo": {
+ "properties": {
+ "city_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "continent_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "continent_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country_iso_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "location": {
+ "type": "geo_point"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "postal_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "region_iso_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "region_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "timezone": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "hostname": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "ingress": {
+ "properties": {
+ "interface": {
+ "properties": {
+ "alias": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "vlan": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "zone": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "ip": {
+ "type": "ip"
+ },
+ "mac": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "os": {
+ "properties": {
+ "family": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "full": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "kernel": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "platform": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "product": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "serial_number": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "vendor": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "orchestrator": {
+ "properties": {
+ "api_version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "cluster": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "url": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "namespace": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "organization": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "resource": {
+ "properties": {
+ "annotation": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "ip": {
+ "type": "ip"
+ },
+ "label": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "parent": {
+ "properties": {
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "organization": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "package": {
+ "properties": {
+ "architecture": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "build_version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "checksum": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "description": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "install_scope": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "installed": {
+ "type": "date"
+ },
+ "license": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "path": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "reference": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "size": {
+ "type": "long"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "process": {
+ "properties": {
+ "args": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "args_count": {
+ "type": "long"
+ },
+ "code_signature": {
+ "properties": {
+ "digest_algorithm": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "exists": {
+ "type": "boolean"
+ },
+ "signing_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "status": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "subject_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "team_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "timestamp": {
+ "type": "date"
+ },
+ "trusted": {
+ "type": "boolean"
+ },
+ "valid": {
+ "type": "boolean"
+ }
+ }
+ },
+ "command_line": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "type": "wildcard"
+ },
+ "elf": {
+ "properties": {
+ "architecture": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "byte_order": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "cpu_type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "creation_date": {
+ "type": "date"
+ },
+ "exports": {
+ "type": "flattened"
+ },
+ "go_import_hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "go_imports": {
+ "type": "flattened"
+ },
+ "go_imports_names_entropy": {
+ "type": "long"
+ },
+ "go_imports_names_var_entropy": {
+ "type": "long"
+ },
+ "go_stripped": {
+ "type": "boolean"
+ },
+ "header": {
+ "properties": {
+ "abi_version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "class": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "data": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "entrypoint": {
+ "type": "long"
+ },
+ "object_version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "os_abi": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "import_hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "imports": {
+ "type": "flattened"
+ },
+ "imports_names_entropy": {
+ "type": "long"
+ },
+ "imports_names_var_entropy": {
+ "type": "long"
+ },
+ "sections": {
+ "properties": {
+ "chi2": {
+ "type": "long"
+ },
+ "entropy": {
+ "type": "long"
+ },
+ "flags": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "physical_offset": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "physical_size": {
+ "type": "long"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "var_entropy": {
+ "type": "long"
+ },
+ "virtual_address": {
+ "type": "long"
+ },
+ "virtual_size": {
+ "type": "long"
+ }
+ },
+ "type": "nested"
+ },
+ "segments": {
+ "properties": {
+ "sections": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ },
+ "type": "nested"
+ },
+ "shared_libraries": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "telfhash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "end": {
+ "type": "date"
+ },
+ "entity_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "entry_leader": {
+ "properties": {
+ "args": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "args_count": {
+ "type": "long"
+ },
+ "attested_groups": {
+ "properties": {
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "attested_user": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "command_line": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "type": "wildcard"
+ },
+ "entity_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "entry_meta": {
+ "properties": {
+ "source": {
+ "properties": {
+ "ip": {
+ "type": "ip"
+ }
+ }
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "executable": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "group": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "interactive": {
+ "type": "boolean"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "parent": {
+ "properties": {
+ "entity_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "pid": {
+ "type": "long"
+ },
+ "session_leader": {
+ "properties": {
+ "entity_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "pid": {
+ "type": "long"
+ },
+ "start": {
+ "type": "date"
+ },
+ "vpid": {
+ "type": "long"
+ }
+ }
+ },
+ "start": {
+ "type": "date"
+ },
+ "vpid": {
+ "type": "long"
+ }
+ }
+ },
+ "pid": {
+ "type": "long"
+ },
+ "real_group": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "real_user": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "same_as_process": {
+ "type": "boolean"
+ },
+ "saved_group": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "saved_user": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "start": {
+ "type": "date"
+ },
+ "supplemental_groups": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "tty": {
+ "properties": {
+ "char_device": {
+ "properties": {
+ "major": {
+ "type": "long"
+ },
+ "minor": {
+ "type": "long"
+ }
+ }
+ }
+ }
+ },
+ "user": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "vpid": {
+ "type": "long"
+ },
+ "working_directory": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "env_vars": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "executable": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "exit_code": {
+ "type": "long"
+ },
+ "group_leader": {
+ "properties": {
+ "args": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "args_count": {
+ "type": "long"
+ },
+ "command_line": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "type": "wildcard"
+ },
+ "entity_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "executable": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "group": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "interactive": {
+ "type": "boolean"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "pid": {
+ "type": "long"
+ },
+ "real_group": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "real_user": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "same_as_process": {
+ "type": "boolean"
+ },
+ "saved_group": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "saved_user": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "start": {
+ "type": "date"
+ },
+ "supplemental_groups": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "tty": {
+ "properties": {
+ "char_device": {
+ "properties": {
+ "major": {
+ "type": "long"
+ },
+ "minor": {
+ "type": "long"
+ }
+ }
+ }
+ }
+ },
+ "user": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "vpid": {
+ "type": "long"
+ },
+ "working_directory": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "hash": {
+ "properties": {
+ "md5": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha1": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha256": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha384": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha512": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "ssdeep": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "tlsh": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "interactive": {
+ "type": "boolean"
+ },
+ "io": {
+ "properties": {
+ "bytes_skipped": {
+ "properties": {
+ "length": {
+ "type": "long"
+ },
+ "offset": {
+ "type": "long"
+ }
+ }
+ },
+ "max_bytes_per_process_exceeded": {
+ "type": "boolean"
+ },
+ "text": {
+ "type": "wildcard"
+ },
+ "total_bytes_captured": {
+ "type": "long"
+ },
+ "total_bytes_skipped": {
+ "type": "long"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "macho": {
+ "properties": {
+ "go_import_hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "go_imports": {
+ "type": "flattened"
+ },
+ "go_imports_names_entropy": {
+ "type": "long"
+ },
+ "go_imports_names_var_entropy": {
+ "type": "long"
+ },
+ "go_stripped": {
+ "type": "boolean"
+ },
+ "import_hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "imports": {
+ "type": "flattened"
+ },
+ "imports_names_entropy": {
+ "type": "long"
+ },
+ "imports_names_var_entropy": {
+ "type": "long"
+ },
+ "sections": {
+ "properties": {
+ "entropy": {
+ "type": "long"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "physical_size": {
+ "type": "long"
+ },
+ "var_entropy": {
+ "type": "long"
+ },
+ "virtual_size": {
+ "type": "long"
+ }
+ },
+ "type": "nested"
+ },
+ "symhash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "parent": {
+ "properties": {
+ "args": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "args_count": {
+ "type": "long"
+ },
+ "code_signature": {
+ "properties": {
+ "digest_algorithm": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "exists": {
+ "type": "boolean"
+ },
+ "signing_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "status": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "subject_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "team_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "timestamp": {
+ "type": "date"
+ },
+ "trusted": {
+ "type": "boolean"
+ },
+ "valid": {
+ "type": "boolean"
+ }
+ }
+ },
+ "command_line": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "type": "wildcard"
+ },
+ "elf": {
+ "properties": {
+ "architecture": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "byte_order": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "cpu_type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "creation_date": {
+ "type": "date"
+ },
+ "exports": {
+ "type": "flattened"
+ },
+ "go_import_hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "go_imports": {
+ "type": "flattened"
+ },
+ "go_imports_names_entropy": {
+ "type": "long"
+ },
+ "go_imports_names_var_entropy": {
+ "type": "long"
+ },
+ "go_stripped": {
+ "type": "boolean"
+ },
+ "header": {
+ "properties": {
+ "abi_version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "class": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "data": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "entrypoint": {
+ "type": "long"
+ },
+ "object_version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "os_abi": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "import_hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "imports": {
+ "type": "flattened"
+ },
+ "imports_names_entropy": {
+ "type": "long"
+ },
+ "imports_names_var_entropy": {
+ "type": "long"
+ },
+ "sections": {
+ "properties": {
+ "chi2": {
+ "type": "long"
+ },
+ "entropy": {
+ "type": "long"
+ },
+ "flags": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "physical_offset": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "physical_size": {
+ "type": "long"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "var_entropy": {
+ "type": "long"
+ },
+ "virtual_address": {
+ "type": "long"
+ },
+ "virtual_size": {
+ "type": "long"
+ }
+ },
+ "type": "nested"
+ },
+ "segments": {
+ "properties": {
+ "sections": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ },
+ "type": "nested"
+ },
+ "shared_libraries": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "telfhash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "end": {
+ "type": "date"
+ },
+ "entity_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "executable": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "exit_code": {
+ "type": "long"
+ },
+ "group": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "group_leader": {
+ "properties": {
+ "entity_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "pid": {
+ "type": "long"
+ },
+ "start": {
+ "type": "date"
+ },
+ "vpid": {
+ "type": "long"
+ }
+ }
+ },
+ "hash": {
+ "properties": {
+ "md5": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha1": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha256": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha384": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha512": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "ssdeep": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "tlsh": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "interactive": {
+ "type": "boolean"
+ },
+ "macho": {
+ "properties": {
+ "go_import_hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "go_imports": {
+ "type": "flattened"
+ },
+ "go_imports_names_entropy": {
+ "type": "long"
+ },
+ "go_imports_names_var_entropy": {
+ "type": "long"
+ },
+ "go_stripped": {
+ "type": "boolean"
+ },
+ "import_hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "imports": {
+ "type": "flattened"
+ },
+ "imports_names_entropy": {
+ "type": "long"
+ },
+ "imports_names_var_entropy": {
+ "type": "long"
+ },
+ "sections": {
+ "properties": {
+ "entropy": {
+ "type": "long"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "physical_size": {
+ "type": "long"
+ },
+ "var_entropy": {
+ "type": "long"
+ },
+ "virtual_size": {
+ "type": "long"
+ }
+ },
+ "type": "nested"
+ },
+ "symhash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "pe": {
+ "properties": {
+ "architecture": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "company": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "description": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "file_version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "go_import_hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "go_imports": {
+ "type": "flattened"
+ },
+ "go_imports_names_entropy": {
+ "type": "long"
+ },
+ "go_imports_names_var_entropy": {
+ "type": "long"
+ },
+ "go_stripped": {
+ "type": "boolean"
+ },
+ "imphash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "import_hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "imports": {
+ "type": "flattened"
+ },
+ "imports_names_entropy": {
+ "type": "long"
+ },
+ "imports_names_var_entropy": {
+ "type": "long"
+ },
+ "original_file_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "pehash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "product": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sections": {
+ "properties": {
+ "entropy": {
+ "type": "long"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "physical_size": {
+ "type": "long"
+ },
+ "var_entropy": {
+ "type": "long"
+ },
+ "virtual_size": {
+ "type": "long"
+ }
+ },
+ "type": "nested"
+ }
+ }
+ },
+ "pgid": {
+ "type": "long"
+ },
+ "pid": {
+ "type": "long"
+ },
+ "real_group": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "real_user": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "saved_group": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "saved_user": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "start": {
+ "type": "date"
+ },
+ "supplemental_groups": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "thread": {
+ "properties": {
+ "capabilities": {
+ "properties": {
+ "effective": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "permitted": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "id": {
+ "type": "long"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "title": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "tty": {
+ "properties": {
+ "char_device": {
+ "properties": {
+ "major": {
+ "type": "long"
+ },
+ "minor": {
+ "type": "long"
+ }
+ }
+ }
+ }
+ },
+ "uptime": {
+ "type": "long"
+ },
+ "user": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "vpid": {
+ "type": "long"
+ },
+ "working_directory": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "pe": {
+ "properties": {
+ "architecture": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "company": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "description": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "file_version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "go_import_hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "go_imports": {
+ "type": "flattened"
+ },
+ "go_imports_names_entropy": {
+ "type": "long"
+ },
+ "go_imports_names_var_entropy": {
+ "type": "long"
+ },
+ "go_stripped": {
+ "type": "boolean"
+ },
+ "imphash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "import_hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "imports": {
+ "type": "flattened"
+ },
+ "imports_names_entropy": {
+ "type": "long"
+ },
+ "imports_names_var_entropy": {
+ "type": "long"
+ },
+ "original_file_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "pehash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "product": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sections": {
+ "properties": {
+ "entropy": {
+ "type": "long"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "physical_size": {
+ "type": "long"
+ },
+ "var_entropy": {
+ "type": "long"
+ },
+ "virtual_size": {
+ "type": "long"
+ }
+ },
+ "type": "nested"
+ }
+ }
+ },
+ "pgid": {
+ "type": "long"
+ },
+ "pid": {
+ "type": "long"
+ },
+ "previous": {
+ "properties": {
+ "args": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "args_count": {
+ "type": "long"
+ },
+ "executable": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "real_group": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "real_user": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "saved_group": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "saved_user": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "session_leader": {
+ "properties": {
+ "args": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "args_count": {
+ "type": "long"
+ },
+ "command_line": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "type": "wildcard"
+ },
+ "entity_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "executable": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "group": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "interactive": {
+ "type": "boolean"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "parent": {
+ "properties": {
+ "entity_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "pid": {
+ "type": "long"
+ },
+ "session_leader": {
+ "properties": {
+ "entity_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "pid": {
+ "type": "long"
+ },
+ "start": {
+ "type": "date"
+ },
+ "vpid": {
+ "type": "long"
+ }
+ }
+ },
+ "start": {
+ "type": "date"
+ },
+ "vpid": {
+ "type": "long"
+ }
+ }
+ },
+ "pid": {
+ "type": "long"
+ },
+ "real_group": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "real_user": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "same_as_process": {
+ "type": "boolean"
+ },
+ "saved_group": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "saved_user": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "start": {
+ "type": "date"
+ },
+ "supplemental_groups": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "tty": {
+ "properties": {
+ "char_device": {
+ "properties": {
+ "major": {
+ "type": "long"
+ },
+ "minor": {
+ "type": "long"
+ }
+ }
+ }
+ }
+ },
+ "user": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "vpid": {
+ "type": "long"
+ },
+ "working_directory": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "start": {
+ "type": "date"
+ },
+ "supplemental_groups": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "thread": {
+ "properties": {
+ "capabilities": {
+ "properties": {
+ "effective": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "permitted": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "id": {
+ "type": "long"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "title": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "tty": {
+ "properties": {
+ "char_device": {
+ "properties": {
+ "major": {
+ "type": "long"
+ },
+ "minor": {
+ "type": "long"
+ }
+ }
+ },
+ "columns": {
+ "type": "long"
+ },
+ "rows": {
+ "type": "long"
+ }
+ }
+ },
+ "uptime": {
+ "type": "long"
+ },
+ "user": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "vpid": {
+ "type": "long"
+ },
+ "working_directory": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "registry": {
+ "properties": {
+ "data": {
+ "properties": {
+ "bytes": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "strings": {
+ "type": "wildcard"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "hive": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "key": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "path": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "value": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "related": {
+ "properties": {
+ "hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "hosts": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "ip": {
+ "type": "ip"
+ },
+ "user": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "rule": {
+ "properties": {
+ "author": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "category": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "description": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "license": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "reference": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "ruleset": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "uuid": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "server": {
+ "properties": {
+ "address": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "as": {
+ "properties": {
+ "number": {
+ "type": "long"
+ },
+ "organization": {
+ "properties": {
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "bytes": {
+ "type": "long"
+ },
+ "domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "geo": {
+ "properties": {
+ "city_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "continent_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "continent_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country_iso_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "location": {
+ "type": "geo_point"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "postal_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "region_iso_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "region_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "timezone": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "ip": {
+ "type": "ip"
+ },
+ "mac": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "nat": {
+ "properties": {
+ "ip": {
+ "type": "ip"
+ },
+ "port": {
+ "type": "long"
+ }
+ }
+ },
+ "packets": {
+ "type": "long"
+ },
+ "port": {
+ "type": "long"
+ },
+ "registered_domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "subdomain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "top_level_domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "user": {
+ "properties": {
+ "domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "email": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "full_name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "group": {
+ "properties": {
+ "domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "roles": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "service": {
+ "properties": {
+ "address": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "environment": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "ephemeral_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "node": {
+ "properties": {
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "role": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "roles": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "origin": {
+ "properties": {
+ "address": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "environment": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "ephemeral_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "node": {
+ "properties": {
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "role": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "roles": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "state": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "state": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "target": {
+ "properties": {
+ "address": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "environment": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "ephemeral_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "node": {
+ "properties": {
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "role": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "roles": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "state": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "signal": {
+ "properties": {
+ "ancestors": {
+ "properties": {
+ "depth": {
+ "path": "kibana.alert.ancestors.depth",
+ "type": "alias"
+ },
+ "id": {
+ "path": "kibana.alert.ancestors.id",
+ "type": "alias"
+ },
+ "index": {
+ "path": "kibana.alert.ancestors.index",
+ "type": "alias"
+ },
+ "type": {
+ "path": "kibana.alert.ancestors.type",
+ "type": "alias"
+ }
+ }
+ },
+ "depth": {
+ "path": "kibana.alert.depth",
+ "type": "alias"
+ },
+ "group": {
+ "properties": {
+ "id": {
+ "path": "kibana.alert.group.id",
+ "type": "alias"
+ },
+ "index": {
+ "path": "kibana.alert.group.index",
+ "type": "alias"
+ }
+ }
+ },
+ "original_event": {
+ "properties": {
+ "action": {
+ "path": "kibana.alert.original_event.action",
+ "type": "alias"
+ },
+ "category": {
+ "path": "kibana.alert.original_event.category",
+ "type": "alias"
+ },
+ "code": {
+ "path": "kibana.alert.original_event.code",
+ "type": "alias"
+ },
+ "created": {
+ "path": "kibana.alert.original_event.created",
+ "type": "alias"
+ },
+ "dataset": {
+ "path": "kibana.alert.original_event.dataset",
+ "type": "alias"
+ },
+ "duration": {
+ "path": "kibana.alert.original_event.duration",
+ "type": "alias"
+ },
+ "end": {
+ "path": "kibana.alert.original_event.end",
+ "type": "alias"
+ },
+ "hash": {
+ "path": "kibana.alert.original_event.hash",
+ "type": "alias"
+ },
+ "id": {
+ "path": "kibana.alert.original_event.id",
+ "type": "alias"
+ },
+ "kind": {
+ "path": "kibana.alert.original_event.kind",
+ "type": "alias"
+ },
+ "module": {
+ "path": "kibana.alert.original_event.module",
+ "type": "alias"
+ },
+ "outcome": {
+ "path": "kibana.alert.original_event.outcome",
+ "type": "alias"
+ },
+ "provider": {
+ "path": "kibana.alert.original_event.provider",
+ "type": "alias"
+ },
+ "reason": {
+ "path": "kibana.alert.original_event.reason",
+ "type": "alias"
+ },
+ "risk_score": {
+ "path": "kibana.alert.original_event.risk_score",
+ "type": "alias"
+ },
+ "risk_score_norm": {
+ "path": "kibana.alert.original_event.risk_score_norm",
+ "type": "alias"
+ },
+ "sequence": {
+ "path": "kibana.alert.original_event.sequence",
+ "type": "alias"
+ },
+ "severity": {
+ "path": "kibana.alert.original_event.severity",
+ "type": "alias"
+ },
+ "start": {
+ "path": "kibana.alert.original_event.start",
+ "type": "alias"
+ },
+ "timezone": {
+ "path": "kibana.alert.original_event.timezone",
+ "type": "alias"
+ },
+ "type": {
+ "path": "kibana.alert.original_event.type",
+ "type": "alias"
+ }
+ }
+ },
+ "original_time": {
+ "path": "kibana.alert.original_time",
+ "type": "alias"
+ },
+ "reason": {
+ "path": "kibana.alert.reason",
+ "type": "alias"
+ },
+ "rule": {
+ "properties": {
+ "author": {
+ "path": "kibana.alert.rule.author",
+ "type": "alias"
+ },
+ "building_block_type": {
+ "path": "kibana.alert.building_block_type",
+ "type": "alias"
+ },
+ "created_at": {
+ "path": "kibana.alert.rule.created_at",
+ "type": "alias"
+ },
+ "created_by": {
+ "path": "kibana.alert.rule.created_by",
+ "type": "alias"
+ },
+ "description": {
+ "path": "kibana.alert.rule.description",
+ "type": "alias"
+ },
+ "enabled": {
+ "path": "kibana.alert.rule.enabled",
+ "type": "alias"
+ },
+ "false_positives": {
+ "path": "kibana.alert.rule.false_positives",
+ "type": "alias"
+ },
+ "from": {
+ "path": "kibana.alert.rule.from",
+ "type": "alias"
+ },
+ "id": {
+ "path": "kibana.alert.rule.uuid",
+ "type": "alias"
+ },
+ "immutable": {
+ "path": "kibana.alert.rule.immutable",
+ "type": "alias"
+ },
+ "interval": {
+ "path": "kibana.alert.rule.interval",
+ "type": "alias"
+ },
+ "license": {
+ "path": "kibana.alert.rule.license",
+ "type": "alias"
+ },
+ "max_signals": {
+ "path": "kibana.alert.rule.max_signals",
+ "type": "alias"
+ },
+ "name": {
+ "path": "kibana.alert.rule.name",
+ "type": "alias"
+ },
+ "note": {
+ "path": "kibana.alert.rule.note",
+ "type": "alias"
+ },
+ "references": {
+ "path": "kibana.alert.rule.references",
+ "type": "alias"
+ },
+ "risk_score": {
+ "path": "kibana.alert.risk_score",
+ "type": "alias"
+ },
+ "rule_id": {
+ "path": "kibana.alert.rule.rule_id",
+ "type": "alias"
+ },
+ "rule_name_override": {
+ "path": "kibana.alert.rule.rule_name_override",
+ "type": "alias"
+ },
+ "severity": {
+ "path": "kibana.alert.severity",
+ "type": "alias"
+ },
+ "tags": {
+ "path": "kibana.alert.rule.tags",
+ "type": "alias"
+ },
+ "threat": {
+ "properties": {
+ "framework": {
+ "path": "kibana.alert.rule.threat.framework",
+ "type": "alias"
+ },
+ "tactic": {
+ "properties": {
+ "id": {
+ "path": "kibana.alert.rule.threat.tactic.id",
+ "type": "alias"
+ },
+ "name": {
+ "path": "kibana.alert.rule.threat.tactic.name",
+ "type": "alias"
+ },
+ "reference": {
+ "path": "kibana.alert.rule.threat.tactic.reference",
+ "type": "alias"
+ }
+ }
+ },
+ "technique": {
+ "properties": {
+ "id": {
+ "path": "kibana.alert.rule.threat.technique.id",
+ "type": "alias"
+ },
+ "name": {
+ "path": "kibana.alert.rule.threat.technique.name",
+ "type": "alias"
+ },
+ "reference": {
+ "path": "kibana.alert.rule.threat.technique.reference",
+ "type": "alias"
+ },
+ "subtechnique": {
+ "properties": {
+ "id": {
+ "path": "kibana.alert.rule.threat.technique.subtechnique.id",
+ "type": "alias"
+ },
+ "name": {
+ "path": "kibana.alert.rule.threat.technique.subtechnique.name",
+ "type": "alias"
+ },
+ "reference": {
+ "path": "kibana.alert.rule.threat.technique.subtechnique.reference",
+ "type": "alias"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "timeline_id": {
+ "path": "kibana.alert.rule.timeline_id",
+ "type": "alias"
+ },
+ "timeline_title": {
+ "path": "kibana.alert.rule.timeline_title",
+ "type": "alias"
+ },
+ "timestamp_override": {
+ "path": "kibana.alert.rule.timestamp_override",
+ "type": "alias"
+ },
+ "to": {
+ "path": "kibana.alert.rule.to",
+ "type": "alias"
+ },
+ "type": {
+ "path": "kibana.alert.rule.type",
+ "type": "alias"
+ },
+ "updated_at": {
+ "path": "kibana.alert.rule.updated_at",
+ "type": "alias"
+ },
+ "updated_by": {
+ "path": "kibana.alert.rule.updated_by",
+ "type": "alias"
+ },
+ "version": {
+ "path": "kibana.alert.rule.version",
+ "type": "alias"
+ }
+ }
+ },
+ "status": {
+ "path": "kibana.alert.workflow_status",
+ "type": "alias"
+ },
+ "threshold_result": {
+ "properties": {
+ "cardinality": {
+ "properties": {
+ "field": {
+ "path": "kibana.alert.threshold_result.cardinality.field",
+ "type": "alias"
+ },
+ "value": {
+ "path": "kibana.alert.threshold_result.cardinality.value",
+ "type": "alias"
+ }
+ }
+ },
+ "count": {
+ "path": "kibana.alert.threshold_result.count",
+ "type": "alias"
+ },
+ "from": {
+ "path": "kibana.alert.threshold_result.from",
+ "type": "alias"
+ },
+ "terms": {
+ "properties": {
+ "field": {
+ "path": "kibana.alert.threshold_result.terms.field",
+ "type": "alias"
+ },
+ "value": {
+ "path": "kibana.alert.threshold_result.terms.value",
+ "type": "alias"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "source": {
+ "properties": {
+ "address": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "as": {
+ "properties": {
+ "number": {
+ "type": "long"
+ },
+ "organization": {
+ "properties": {
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "bytes": {
+ "type": "long"
+ },
+ "domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "geo": {
+ "properties": {
+ "city_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "continent_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "continent_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country_iso_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "location": {
+ "type": "geo_point"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "postal_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "region_iso_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "region_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "timezone": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "ip": {
+ "type": "ip"
+ },
+ "mac": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "nat": {
+ "properties": {
+ "ip": {
+ "type": "ip"
+ },
+ "port": {
+ "type": "long"
+ }
+ }
+ },
+ "packets": {
+ "type": "long"
+ },
+ "port": {
+ "type": "long"
+ },
+ "registered_domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "subdomain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "top_level_domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "user": {
+ "properties": {
+ "domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "email": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "full_name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "group": {
+ "properties": {
+ "domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "roles": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "span": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "tags": {
+ "type": "keyword"
+ },
+ "threat": {
+ "properties": {
+ "enrichments": {
+ "properties": {
+ "indicator": {
+ "properties": {
+ "as": {
+ "properties": {
+ "number": {
+ "type": "long"
+ },
+ "organization": {
+ "properties": {
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "confidence": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "description": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "email": {
+ "properties": {
+ "address": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "file": {
+ "properties": {
+ "accessed": {
+ "type": "date"
+ },
+ "attributes": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "code_signature": {
+ "properties": {
+ "digest_algorithm": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "exists": {
+ "type": "boolean"
+ },
+ "signing_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "status": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "subject_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "team_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "timestamp": {
+ "type": "date"
+ },
+ "trusted": {
+ "type": "boolean"
+ },
+ "valid": {
+ "type": "boolean"
+ }
+ }
+ },
+ "created": {
+ "type": "date"
+ },
+ "ctime": {
+ "type": "date"
+ },
+ "device": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "directory": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "drive_letter": {
+ "ignore_above": 1,
+ "type": "keyword"
+ },
+ "elf": {
+ "properties": {
+ "architecture": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "byte_order": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "cpu_type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "creation_date": {
+ "type": "date"
+ },
+ "exports": {
+ "type": "flattened"
+ },
+ "go_import_hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "go_imports": {
+ "type": "flattened"
+ },
+ "go_imports_names_entropy": {
+ "type": "long"
+ },
+ "go_imports_names_var_entropy": {
+ "type": "long"
+ },
+ "go_stripped": {
+ "type": "boolean"
+ },
+ "header": {
+ "properties": {
+ "abi_version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "class": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "data": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "entrypoint": {
+ "type": "long"
+ },
+ "object_version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "os_abi": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "import_hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "imports": {
+ "type": "flattened"
+ },
+ "imports_names_entropy": {
+ "type": "long"
+ },
+ "imports_names_var_entropy": {
+ "type": "long"
+ },
+ "sections": {
+ "properties": {
+ "chi2": {
+ "type": "long"
+ },
+ "entropy": {
+ "type": "long"
+ },
+ "flags": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "physical_offset": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "physical_size": {
+ "type": "long"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "var_entropy": {
+ "type": "long"
+ },
+ "virtual_address": {
+ "type": "long"
+ },
+ "virtual_size": {
+ "type": "long"
+ }
+ },
+ "type": "nested"
+ },
+ "segments": {
+ "properties": {
+ "sections": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ },
+ "type": "nested"
+ },
+ "shared_libraries": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "telfhash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "extension": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "fork_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "gid": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "group": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "hash": {
+ "properties": {
+ "md5": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha1": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha256": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha384": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha512": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "ssdeep": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "tlsh": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "inode": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "mime_type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "mode": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "mtime": {
+ "type": "date"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "owner": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "path": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "pe": {
+ "properties": {
+ "architecture": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "company": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "description": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "file_version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "go_import_hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "go_imports": {
+ "type": "flattened"
+ },
+ "go_imports_names_entropy": {
+ "type": "long"
+ },
+ "go_imports_names_var_entropy": {
+ "type": "long"
+ },
+ "go_stripped": {
+ "type": "boolean"
+ },
+ "imphash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "import_hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "imports": {
+ "type": "flattened"
+ },
+ "imports_names_entropy": {
+ "type": "long"
+ },
+ "imports_names_var_entropy": {
+ "type": "long"
+ },
+ "original_file_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "pehash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "product": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sections": {
+ "properties": {
+ "entropy": {
+ "type": "long"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "physical_size": {
+ "type": "long"
+ },
+ "var_entropy": {
+ "type": "long"
+ },
+ "virtual_size": {
+ "type": "long"
+ }
+ },
+ "type": "nested"
+ }
+ }
+ },
+ "size": {
+ "type": "long"
+ },
+ "target_path": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "uid": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "x509": {
+ "properties": {
+ "alternative_names": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "issuer": {
+ "properties": {
+ "common_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "distinguished_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "locality": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "organization": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "organizational_unit": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "state_or_province": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "not_after": {
+ "type": "date"
+ },
+ "not_before": {
+ "type": "date"
+ },
+ "public_key_algorithm": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "public_key_curve": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "public_key_exponent": {
+ "type": "long"
+ },
+ "public_key_size": {
+ "type": "long"
+ },
+ "serial_number": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "signature_algorithm": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "subject": {
+ "properties": {
+ "common_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "distinguished_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "locality": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "organization": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "organizational_unit": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "state_or_province": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "version_number": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "first_seen": {
+ "type": "date"
+ },
+ "geo": {
+ "properties": {
+ "city_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "continent_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "continent_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country_iso_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "location": {
+ "type": "geo_point"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "postal_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "region_iso_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "region_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "timezone": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "ip": {
+ "type": "ip"
+ },
+ "last_seen": {
+ "type": "date"
+ },
+ "marking": {
+ "properties": {
+ "tlp": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "tlp_version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "modified_at": {
+ "type": "date"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "port": {
+ "type": "long"
+ },
+ "provider": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "reference": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "registry": {
+ "properties": {
+ "data": {
+ "properties": {
+ "bytes": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "strings": {
+ "type": "wildcard"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "hive": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "key": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "path": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "value": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "scanner_stats": {
+ "type": "long"
+ },
+ "sightings": {
+ "type": "long"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "url": {
+ "properties": {
+ "domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "extension": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "fragment": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "full": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "type": "wildcard"
+ },
+ "original": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "type": "wildcard"
+ },
+ "password": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "path": {
+ "type": "wildcard"
+ },
+ "port": {
+ "type": "long"
+ },
+ "query": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "registered_domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "scheme": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "subdomain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "top_level_domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "username": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "x509": {
+ "properties": {
+ "alternative_names": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "issuer": {
+ "properties": {
+ "common_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "distinguished_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "locality": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "organization": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "organizational_unit": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "state_or_province": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "not_after": {
+ "type": "date"
+ },
+ "not_before": {
+ "type": "date"
+ },
+ "public_key_algorithm": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "public_key_curve": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "public_key_exponent": {
+ "type": "long"
+ },
+ "public_key_size": {
+ "type": "long"
+ },
+ "serial_number": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "signature_algorithm": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "subject": {
+ "properties": {
+ "common_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "distinguished_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "locality": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "organization": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "organizational_unit": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "state_or_province": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "version_number": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "matched": {
+ "properties": {
+ "atomic": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "field": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "index": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "occurred": {
+ "type": "date"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ },
+ "type": "nested"
+ },
+ "feed": {
+ "properties": {
+ "dashboard_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "description": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "reference": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "framework": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "group": {
+ "properties": {
+ "alias": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "reference": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "indicator": {
+ "properties": {
+ "as": {
+ "properties": {
+ "number": {
+ "type": "long"
+ },
+ "organization": {
+ "properties": {
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "confidence": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "description": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "email": {
+ "properties": {
+ "address": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "file": {
+ "properties": {
+ "accessed": {
+ "type": "date"
+ },
+ "attributes": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "code_signature": {
+ "properties": {
+ "digest_algorithm": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "exists": {
+ "type": "boolean"
+ },
+ "signing_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "status": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "subject_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "team_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "timestamp": {
+ "type": "date"
+ },
+ "trusted": {
+ "type": "boolean"
+ },
+ "valid": {
+ "type": "boolean"
+ }
+ }
+ },
+ "created": {
+ "type": "date"
+ },
+ "ctime": {
+ "type": "date"
+ },
+ "device": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "directory": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "drive_letter": {
+ "ignore_above": 1,
+ "type": "keyword"
+ },
+ "elf": {
+ "properties": {
+ "architecture": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "byte_order": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "cpu_type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "creation_date": {
+ "type": "date"
+ },
+ "exports": {
+ "type": "flattened"
+ },
+ "go_import_hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "go_imports": {
+ "type": "flattened"
+ },
+ "go_imports_names_entropy": {
+ "type": "long"
+ },
+ "go_imports_names_var_entropy": {
+ "type": "long"
+ },
+ "go_stripped": {
+ "type": "boolean"
+ },
+ "header": {
+ "properties": {
+ "abi_version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "class": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "data": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "entrypoint": {
+ "type": "long"
+ },
+ "object_version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "os_abi": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "import_hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "imports": {
+ "type": "flattened"
+ },
+ "imports_names_entropy": {
+ "type": "long"
+ },
+ "imports_names_var_entropy": {
+ "type": "long"
+ },
+ "sections": {
+ "properties": {
+ "chi2": {
+ "type": "long"
+ },
+ "entropy": {
+ "type": "long"
+ },
+ "flags": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "physical_offset": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "physical_size": {
+ "type": "long"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "var_entropy": {
+ "type": "long"
+ },
+ "virtual_address": {
+ "type": "long"
+ },
+ "virtual_size": {
+ "type": "long"
+ }
+ },
+ "type": "nested"
+ },
+ "segments": {
+ "properties": {
+ "sections": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ },
+ "type": "nested"
+ },
+ "shared_libraries": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "telfhash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "extension": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "fork_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "gid": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "group": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "hash": {
+ "properties": {
+ "md5": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha1": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha256": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha384": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha512": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "ssdeep": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "tlsh": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "inode": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "mime_type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "mode": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "mtime": {
+ "type": "date"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "owner": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "path": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "pe": {
+ "properties": {
+ "architecture": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "company": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "description": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "file_version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "go_import_hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "go_imports": {
+ "type": "flattened"
+ },
+ "go_imports_names_entropy": {
+ "type": "long"
+ },
+ "go_imports_names_var_entropy": {
+ "type": "long"
+ },
+ "go_stripped": {
+ "type": "boolean"
+ },
+ "imphash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "import_hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "imports": {
+ "type": "flattened"
+ },
+ "imports_names_entropy": {
+ "type": "long"
+ },
+ "imports_names_var_entropy": {
+ "type": "long"
+ },
+ "original_file_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "pehash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "product": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sections": {
+ "properties": {
+ "entropy": {
+ "type": "long"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "physical_size": {
+ "type": "long"
+ },
+ "var_entropy": {
+ "type": "long"
+ },
+ "virtual_size": {
+ "type": "long"
+ }
+ },
+ "type": "nested"
+ }
+ }
+ },
+ "size": {
+ "type": "long"
+ },
+ "target_path": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "uid": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "x509": {
+ "properties": {
+ "alternative_names": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "issuer": {
+ "properties": {
+ "common_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "distinguished_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "locality": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "organization": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "organizational_unit": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "state_or_province": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "not_after": {
+ "type": "date"
+ },
+ "not_before": {
+ "type": "date"
+ },
+ "public_key_algorithm": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "public_key_curve": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "public_key_exponent": {
+ "type": "long"
+ },
+ "public_key_size": {
+ "type": "long"
+ },
+ "serial_number": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "signature_algorithm": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "subject": {
+ "properties": {
+ "common_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "distinguished_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "locality": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "organization": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "organizational_unit": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "state_or_province": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "version_number": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "first_seen": {
+ "type": "date"
+ },
+ "geo": {
+ "properties": {
+ "city_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "continent_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "continent_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country_iso_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "location": {
+ "type": "geo_point"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "postal_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "region_iso_code": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "region_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "timezone": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "ip": {
+ "type": "ip"
+ },
+ "last_seen": {
+ "type": "date"
+ },
+ "marking": {
+ "properties": {
+ "tlp": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "tlp_version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "modified_at": {
+ "type": "date"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "port": {
+ "type": "long"
+ },
+ "provider": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "reference": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "registry": {
+ "properties": {
+ "data": {
+ "properties": {
+ "bytes": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "strings": {
+ "type": "wildcard"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "hive": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "key": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "path": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "value": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "scanner_stats": {
+ "type": "long"
+ },
+ "sightings": {
+ "type": "long"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "url": {
+ "properties": {
+ "domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "extension": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "fragment": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "full": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "type": "wildcard"
+ },
+ "original": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "type": "wildcard"
+ },
+ "password": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "path": {
+ "type": "wildcard"
+ },
+ "port": {
+ "type": "long"
+ },
+ "query": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "registered_domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "scheme": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "subdomain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "top_level_domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "username": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "x509": {
+ "properties": {
+ "alternative_names": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "issuer": {
+ "properties": {
+ "common_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "distinguished_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "locality": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "organization": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "organizational_unit": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "state_or_province": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "not_after": {
+ "type": "date"
+ },
+ "not_before": {
+ "type": "date"
+ },
+ "public_key_algorithm": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "public_key_curve": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "public_key_exponent": {
+ "type": "long"
+ },
+ "public_key_size": {
+ "type": "long"
+ },
+ "serial_number": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "signature_algorithm": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "subject": {
+ "properties": {
+ "common_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "distinguished_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "locality": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "organization": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "organizational_unit": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "state_or_province": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "version_number": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "software": {
+ "properties": {
+ "alias": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "platforms": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "reference": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "tactic": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "reference": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "technique": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "reference": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "subtechnique": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "reference": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "tls": {
+ "properties": {
+ "cipher": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "client": {
+ "properties": {
+ "certificate": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "certificate_chain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "hash": {
+ "properties": {
+ "md5": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha1": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha256": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "issuer": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "ja3": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "not_after": {
+ "type": "date"
+ },
+ "not_before": {
+ "type": "date"
+ },
+ "server_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "subject": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "supported_ciphers": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "x509": {
+ "properties": {
+ "alternative_names": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "issuer": {
+ "properties": {
+ "common_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "distinguished_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "locality": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "organization": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "organizational_unit": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "state_or_province": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "not_after": {
+ "type": "date"
+ },
+ "not_before": {
+ "type": "date"
+ },
+ "public_key_algorithm": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "public_key_curve": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "public_key_exponent": {
+ "type": "long"
+ },
+ "public_key_size": {
+ "type": "long"
+ },
+ "serial_number": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "signature_algorithm": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "subject": {
+ "properties": {
+ "common_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "distinguished_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "locality": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "organization": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "organizational_unit": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "state_or_province": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "version_number": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "curve": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "established": {
+ "type": "boolean"
+ },
+ "next_protocol": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "resumed": {
+ "type": "boolean"
+ },
+ "server": {
+ "properties": {
+ "certificate": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "certificate_chain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "hash": {
+ "properties": {
+ "md5": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha1": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "sha256": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "issuer": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "ja3s": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "not_after": {
+ "type": "date"
+ },
+ "not_before": {
+ "type": "date"
+ },
+ "subject": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "x509": {
+ "properties": {
+ "alternative_names": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "issuer": {
+ "properties": {
+ "common_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "distinguished_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "locality": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "organization": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "organizational_unit": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "state_or_province": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "not_after": {
+ "type": "date"
+ },
+ "not_before": {
+ "type": "date"
+ },
+ "public_key_algorithm": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "public_key_curve": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "public_key_exponent": {
+ "type": "long"
+ },
+ "public_key_size": {
+ "type": "long"
+ },
+ "serial_number": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "signature_algorithm": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "subject": {
+ "properties": {
+ "common_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "country": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "distinguished_name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "locality": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "organization": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "organizational_unit": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "state_or_province": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "version_number": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "version_protocol": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "trace": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "transaction": {
+ "properties": {
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "url": {
+ "properties": {
+ "domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "extension": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "fragment": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "full": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "type": "wildcard"
+ },
+ "original": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "type": "wildcard"
+ },
+ "password": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "path": {
+ "type": "wildcard"
+ },
+ "port": {
+ "type": "long"
+ },
+ "query": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "registered_domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "scheme": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "subdomain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "top_level_domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "username": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "user": {
+ "properties": {
+ "asset": {
+ "properties": {
+ "criticality": {
+ "type": "keyword"
+ }
+ }
+ },
+ "changes": {
+ "properties": {
+ "domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "email": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "full_name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "group": {
+ "properties": {
+ "domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "roles": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "effective": {
+ "properties": {
+ "domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "email": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "full_name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "group": {
+ "properties": {
+ "domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "roles": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "email": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "full_name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "group": {
+ "properties": {
+ "domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "risk": {
+ "properties": {
+ "calculated_level": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "calculated_score": {
+ "type": "float"
+ },
+ "calculated_score_norm": {
+ "type": "float"
+ },
+ "static_level": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "static_score": {
+ "type": "float"
+ },
+ "static_score_norm": {
+ "type": "float"
+ }
+ }
+ },
+ "roles": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "target": {
+ "properties": {
+ "domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "email": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "full_name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "group": {
+ "properties": {
+ "domain": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "hash": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "roles": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "user_agent": {
+ "properties": {
+ "device": {
+ "properties": {
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "name": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "original": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "os": {
+ "properties": {
+ "family": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "full": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "kernel": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "name": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "platform": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "type": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "vulnerability": {
+ "properties": {
+ "category": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "classification": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "description": {
+ "fields": {
+ "text": {
+ "type": "match_only_text"
+ }
+ },
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "enumeration": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "reference": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "report_id": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ },
+ "scanner": {
+ "properties": {
+ "vendor": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "score": {
+ "properties": {
+ "base": {
+ "type": "float"
+ },
+ "environmental": {
+ "type": "float"
+ },
+ "temporal": {
+ "type": "float"
+ },
+ "version": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ },
+ "severity": {
+ "ignore_above": 1024,
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ },
+ "settings": {
+ "index": {
+ "auto_expand_replicas": "0-1",
+ "hidden": "true",
+ "lifecycle": {
+ "name": ".alerts-ilm-policy",
+ "rollover_alias": ".alerts-security.alerts-default"
+ },
+ "mapping": {
+ "ignore_malformed": "true",
+ "total_fields": {
+ "limit": "2500"
+ }
+ },
+ "number_of_replicas": "0",
+ "number_of_shards": "1"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/x-pack/test/cloud_security_posture_functional/page_objects/alerts_page.ts b/x-pack/test/cloud_security_posture_functional/page_objects/alerts_page.ts
new file mode 100644
index 0000000000000..f3a9f7b1448a8
--- /dev/null
+++ b/x-pack/test/cloud_security_posture_functional/page_objects/alerts_page.ts
@@ -0,0 +1,107 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import expect from '@kbn/expect';
+import { FtrService } from '../../functional/ftr_provider_context';
+
+const ALERT_TABLE_ROW_CSS_SELECTOR = '[data-test-subj="alertsTable"] .euiDataGridRow';
+const VISUALIZATIONS_SECTION_HEADER_TEST_ID = 'securitySolutionFlyoutVisualizationsHeader';
+const GRAPH_PREVIEW_TEST_ID = 'securitySolutionFlyoutGraphPreview';
+const GRAPH_PREVIEW_LOADING_TEST_ID = 'securitySolutionFlyoutGraphPreviewLoading';
+
+export class AlertsPageObject extends FtrService {
+ private readonly retry = this.ctx.getService('retry');
+ private readonly pageObjects = this.ctx.getPageObjects(['common', 'header']);
+ private readonly testSubjects = this.ctx.getService('testSubjects');
+ private readonly defaultTimeoutMs = this.ctx.getService('config').get('timeouts.waitFor');
+
+ async navigateToAlertsPage(urlQueryParams: string = ''): Promise {
+ await this.pageObjects.common.navigateToUrlWithBrowserHistory(
+ 'securitySolution',
+ '/alerts',
+ `${urlQueryParams && `?${urlQueryParams}`}`,
+ {
+ ensureCurrentUrl: false,
+ }
+ );
+ await this.pageObjects.header.waitUntilLoadingHasFinished();
+ }
+
+ getAbsoluteTimerangeFilter(from: string, to: string) {
+ return `timerange=(global:(linkTo:!(),timerange:(from:%27${from}%27,kind:absolute,to:%27${to}%27)))`;
+ }
+
+ getFlyoutFilter(alertId: string) {
+ return `flyout=(preview:!(),right:(id:document-details-right,params:(id:%27${alertId}%27,indexName:.internal.alerts-security.alerts-default-000001,scopeId:alerts-page)))`;
+ }
+
+ /**
+ * Clicks the refresh button on the Alerts page and waits for it to complete
+ */
+ async clickRefresh(): Promise {
+ await this.ensureOnAlertsPage();
+ await this.testSubjects.click('querySubmitButton');
+
+ // wait for refresh to complete
+ await this.retry.waitFor(
+ 'Alerts pages refresh button to be enabled',
+ async (): Promise => {
+ const refreshButton = await this.testSubjects.find('querySubmitButton');
+
+ return (await refreshButton.isDisplayed()) && (await refreshButton.isEnabled());
+ }
+ );
+ }
+
+ async ensureOnAlertsPage(): Promise {
+ await this.testSubjects.existOrFail('detectionsAlertsPage');
+ }
+
+ async waitForListToHaveAlerts(timeoutMs?: number): Promise {
+ const allEventRows = await this.testSubjects.findService.allByCssSelector(
+ ALERT_TABLE_ROW_CSS_SELECTOR
+ );
+
+ if (!Boolean(allEventRows.length)) {
+ await this.retry.waitForWithTimeout(
+ 'waiting for alerts to show up on alerts page',
+ timeoutMs ?? this.defaultTimeoutMs,
+ async (): Promise => {
+ await this.clickRefresh();
+
+ const allEventRowsInner = await this.testSubjects.findService.allByCssSelector(
+ ALERT_TABLE_ROW_CSS_SELECTOR
+ );
+
+ return Boolean(allEventRowsInner.length);
+ }
+ );
+ }
+ }
+
+ flyout = {
+ expandVisualizations: async (): Promise => {
+ await this.testSubjects.click(VISUALIZATIONS_SECTION_HEADER_TEST_ID);
+ },
+
+ assertGraphPreviewVisible: async () => {
+ return await this.testSubjects.existOrFail(GRAPH_PREVIEW_TEST_ID);
+ },
+
+ assertGraphNodesNumber: async (expected: number) => {
+ await this.flyout.waitGraphIsLoaded();
+ const graph = await this.testSubjects.find(GRAPH_PREVIEW_TEST_ID);
+ await graph.scrollIntoView();
+ const nodes = await graph.findAllByCssSelector('.react-flow__nodes .react-flow__node');
+ expect(nodes.length).to.be(expected);
+ },
+
+ waitGraphIsLoaded: async () => {
+ await this.testSubjects.missingOrFail(GRAPH_PREVIEW_LOADING_TEST_ID, { timeout: 10000 });
+ },
+ };
+}
diff --git a/x-pack/test/cloud_security_posture_functional/page_objects/index.ts b/x-pack/test/cloud_security_posture_functional/page_objects/index.ts
index 704f6310cdbb2..b7c20632e82f5 100644
--- a/x-pack/test/cloud_security_posture_functional/page_objects/index.ts
+++ b/x-pack/test/cloud_security_posture_functional/page_objects/index.ts
@@ -13,8 +13,10 @@ import { VulnerabilityDashboardPageProvider } from './vulnerability_dashboard_pa
import { BenchmarkPagePageProvider } from './benchmark_page';
import { CspSecurityCommonProvider } from './security_common';
import { RulePagePageProvider } from './rule_page';
+import { AlertsPageObject } from './alerts_page';
export const cloudSecurityPosturePageObjects = {
+ alerts: AlertsPageObject,
findings: FindingsPageProvider,
cloudPostureDashboard: CspDashboardPageProvider,
cisAddIntegration: AddCisIntegrationFormPageProvider,
diff --git a/x-pack/test/cloud_security_posture_functional/pages/alerts_flyout.ts b/x-pack/test/cloud_security_posture_functional/pages/alerts_flyout.ts
new file mode 100644
index 0000000000000..3095f6a663968
--- /dev/null
+++ b/x-pack/test/cloud_security_posture_functional/pages/alerts_flyout.ts
@@ -0,0 +1,62 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { waitForPluginInitialized } from '../../cloud_security_posture_api/utils';
+import type { FtrProviderContext } from '../ftr_provider_context';
+
+// eslint-disable-next-line import/no-default-export
+export default function ({ getPageObjects, getService }: FtrProviderContext) {
+ const retry = getService('retry');
+ const logger = getService('log');
+ const supertest = getService('supertest');
+ const esArchiver = getService('esArchiver');
+ const pageObjects = getPageObjects(['common', 'header', 'alerts']);
+ const alertsPage = pageObjects.alerts;
+
+ describe('Security Alerts Page - Graph visualization', function () {
+ this.tags(['cloud_security_posture_graph_viz']);
+
+ before(async () => {
+ await esArchiver.load(
+ 'x-pack/test/cloud_security_posture_functional/es_archives/security_alerts'
+ );
+ await esArchiver.load(
+ 'x-pack/test/cloud_security_posture_functional/es_archives/logs_gcp_audit'
+ );
+
+ await waitForPluginInitialized({ retry, supertest, logger });
+
+ // Setting the timerange to fit the data and open the flyout for a specific alert
+ await alertsPage.navigateToAlertsPage(
+ `${alertsPage.getAbsoluteTimerangeFilter(
+ '2024-10-13T00:00:00.000Z',
+ '2024-10-14T00:00:00.000Z'
+ )}&${alertsPage.getFlyoutFilter(
+ '589e086d7ceec7d4b353340578bd607e96fbac7eab9e2926f110990be15122f1'
+ )}`
+ );
+
+ await alertsPage.waitForListToHaveAlerts();
+
+ await alertsPage.flyout.expandVisualizations();
+ });
+
+ after(async () => {
+ await esArchiver.unload(
+ 'x-pack/test/cloud_security_posture_functional/es_archives/security_alerts'
+ );
+ await esArchiver.unload(
+ 'x-pack/test/cloud_security_posture_functional/es_archives/logs_gcp_audit'
+ );
+ });
+
+ it('should render graph visualization', async () => {
+ await alertsPage.flyout.assertGraphPreviewVisible();
+ await alertsPage.flyout.assertGraphNodesNumber(3);
+ });
+ });
+}
diff --git a/x-pack/test/cloud_security_posture_functional/pages/index.ts b/x-pack/test/cloud_security_posture_functional/pages/index.ts
index 1edf38dc41ec9..0114b6a8ce4dc 100644
--- a/x-pack/test/cloud_security_posture_functional/pages/index.ts
+++ b/x-pack/test/cloud_security_posture_functional/pages/index.ts
@@ -36,5 +36,6 @@ export default function ({ getPageObjects, loadTestFile }: FtrProviderContext) {
loadTestFile(require.resolve('./vulnerabilities'));
loadTestFile(require.resolve('./vulnerabilities_grouping'));
loadTestFile(require.resolve('./benchmark'));
+ loadTestFile(require.resolve('./alerts_flyout'));
});
}