From c223a56ce3df0100cc36029cb065fda94ed1b63a Mon Sep 17 00:00:00 2001
From: Janvi Solanki <123942854+janvi-elastic@users.noreply.github.com>
Date: Thu, 29 Aug 2024 18:55:09 +0530
Subject: [PATCH] [sublime_security] Initial release of the sublime security
(#10805)
Create New integration package sublime_security.
Added data stream.
Added data collection logic for all data streams.
Added the ingest pipeline for all data streams.
Mapped fields according to the ECS schema and added Fields metadata in the appropriate yml files.
Added dashboards and visualizations.
Added test for pipeline for all data streams.
Added system test cases for all data streams.
---
.github/CODEOWNERS | 1 +
.../sublime_security/_dev/build/build.yml | 3 +
.../_dev/build/docs/README.md | 120 +
packages/sublime_security/changelog.yml | 6 +
.../_dev/deploy/docker/docker-compose.yml | 15 +
.../audit/_dev/deploy/docker/files/config.yml | 128 +
.../audit/_dev/test/pipeline/test-audit.log | 1 +
.../pipeline/test-audit.log-expected.json | 112 +
.../_dev/test/pipeline/test-common-config.yml | 3 +
.../_dev/test/system/test-cel-config.yml | 13 +
.../audit/agent/stream/aws-s3.yml.hbs | 97 +
.../audit/agent/stream/cel.yml.hbs | 79 +
.../elasticsearch/ingest_pipeline/default.yml | 414 +++
.../data_stream/audit/fields/base-fields.yml | 20 +
.../data_stream/audit/fields/beats.yml | 6 +
.../data_stream/audit/fields/fields.yml | 102 +
.../data_stream/audit/manifest.yml | 188 ++
.../data_stream/audit/sample_event.json | 121 +
.../email_message/_dev/deploy/tf/env.yml | 9 +
.../deploy/tf/files/test-email-message.log | 1 +
.../email_message/_dev/deploy/tf/main.tf | 57 +
.../email_message/_dev/deploy/tf/variables.tf | 26 +
.../_dev/test/pipeline/test-common-config.yml | 3 +
.../_dev/test/pipeline/test-email-message.log | 3 +
.../test-email-message.log-expected.json | 1419 ++++++++++
.../_dev/test/system/test-aws-s3-config.yml | 14 +
.../email_message/agent/stream/aws-s3.yml.hbs | 94 +
.../elasticsearch/ingest_pipeline/default.yml | 2165 +++++++++++++++
.../email_message/fields/base-fields.yml | 20 +
.../email_message/fields/beats.yml | 24 +
.../email_message/fields/fields.yml | 1222 +++++++++
.../data_stream/email_message/manifest.yml | 117 +
.../email_message/sample_event.json | 762 ++++++
.../_dev/deploy/docker/docker-compose.yml | 15 +
.../_dev/deploy/docker/files/config.yml | 160 ++
.../_dev/test/pipeline/test-common-config.yml | 3 +
.../_dev/test/pipeline/test-message-event.log | 2 +
.../test-message-event.log-expected.json | 182 ++
.../_dev/test/system/test-cel-config.yml | 14 +
.../message_event/agent/stream/aws-s3.yml.hbs | 97 +
.../message_event/agent/stream/cel.yml.hbs | 148 ++
.../elasticsearch/ingest_pipeline/default.yml | 362 +++
.../message_event/fields/base-fields.yml | 20 +
.../message_event/fields/beats.yml | 6 +
.../message_event/fields/fields.yml | 95 +
.../data_stream/message_event/manifest.yml | 196 ++
.../message_event/sample_event.json | 114 +
packages/sublime_security/docs/README.md | 1537 +++++++++++
.../img/sublime_security-audit.png | Bin 0 -> 382287 bytes
.../img/sublime_security-dark.svg | 18 +
.../img/sublime_security-email_message.png | Bin 0 -> 759167 bytes
.../img/sublime_security-message_event.png | Bin 0 -> 475471 bytes
.../sublime_security/img/sublime_security.svg | 18 +
...-779aade2-fbb2-425d-8647-79c2bdf2d6e0.json | 2328 +++++++++++++++++
...-7b4299fc-2465-46c6-bc55-dba692bb2745.json | 1152 ++++++++
...-f4f4e3ca-1993-4a55-9d87-a7029ee0f869.json | 777 ++++++
...-c1e2d194-7f19-46fe-bcdf-d6886edf9d3d.json | 83 +
...-ce2a4b74-76ca-4cdd-b3da-73530ee043c4.json | 101 +
...-eb590f03-79df-4189-aa74-3b5bfe20e8ca.json | 84 +
...me_security-security-solution-default.json | 14 +
packages/sublime_security/kibana/tags.yml | 4 +
packages/sublime_security/manifest.yml | 225 ++
packages/sublime_security/validation.yml | 3 +
63 files changed, 15123 insertions(+)
create mode 100644 packages/sublime_security/_dev/build/build.yml
create mode 100644 packages/sublime_security/_dev/build/docs/README.md
create mode 100644 packages/sublime_security/changelog.yml
create mode 100644 packages/sublime_security/data_stream/audit/_dev/deploy/docker/docker-compose.yml
create mode 100644 packages/sublime_security/data_stream/audit/_dev/deploy/docker/files/config.yml
create mode 100644 packages/sublime_security/data_stream/audit/_dev/test/pipeline/test-audit.log
create mode 100644 packages/sublime_security/data_stream/audit/_dev/test/pipeline/test-audit.log-expected.json
create mode 100644 packages/sublime_security/data_stream/audit/_dev/test/pipeline/test-common-config.yml
create mode 100644 packages/sublime_security/data_stream/audit/_dev/test/system/test-cel-config.yml
create mode 100644 packages/sublime_security/data_stream/audit/agent/stream/aws-s3.yml.hbs
create mode 100644 packages/sublime_security/data_stream/audit/agent/stream/cel.yml.hbs
create mode 100644 packages/sublime_security/data_stream/audit/elasticsearch/ingest_pipeline/default.yml
create mode 100644 packages/sublime_security/data_stream/audit/fields/base-fields.yml
create mode 100644 packages/sublime_security/data_stream/audit/fields/beats.yml
create mode 100644 packages/sublime_security/data_stream/audit/fields/fields.yml
create mode 100644 packages/sublime_security/data_stream/audit/manifest.yml
create mode 100644 packages/sublime_security/data_stream/audit/sample_event.json
create mode 100644 packages/sublime_security/data_stream/email_message/_dev/deploy/tf/env.yml
create mode 100644 packages/sublime_security/data_stream/email_message/_dev/deploy/tf/files/test-email-message.log
create mode 100644 packages/sublime_security/data_stream/email_message/_dev/deploy/tf/main.tf
create mode 100644 packages/sublime_security/data_stream/email_message/_dev/deploy/tf/variables.tf
create mode 100644 packages/sublime_security/data_stream/email_message/_dev/test/pipeline/test-common-config.yml
create mode 100644 packages/sublime_security/data_stream/email_message/_dev/test/pipeline/test-email-message.log
create mode 100644 packages/sublime_security/data_stream/email_message/_dev/test/pipeline/test-email-message.log-expected.json
create mode 100644 packages/sublime_security/data_stream/email_message/_dev/test/system/test-aws-s3-config.yml
create mode 100644 packages/sublime_security/data_stream/email_message/agent/stream/aws-s3.yml.hbs
create mode 100644 packages/sublime_security/data_stream/email_message/elasticsearch/ingest_pipeline/default.yml
create mode 100644 packages/sublime_security/data_stream/email_message/fields/base-fields.yml
create mode 100644 packages/sublime_security/data_stream/email_message/fields/beats.yml
create mode 100644 packages/sublime_security/data_stream/email_message/fields/fields.yml
create mode 100644 packages/sublime_security/data_stream/email_message/manifest.yml
create mode 100644 packages/sublime_security/data_stream/email_message/sample_event.json
create mode 100644 packages/sublime_security/data_stream/message_event/_dev/deploy/docker/docker-compose.yml
create mode 100644 packages/sublime_security/data_stream/message_event/_dev/deploy/docker/files/config.yml
create mode 100644 packages/sublime_security/data_stream/message_event/_dev/test/pipeline/test-common-config.yml
create mode 100644 packages/sublime_security/data_stream/message_event/_dev/test/pipeline/test-message-event.log
create mode 100644 packages/sublime_security/data_stream/message_event/_dev/test/pipeline/test-message-event.log-expected.json
create mode 100644 packages/sublime_security/data_stream/message_event/_dev/test/system/test-cel-config.yml
create mode 100644 packages/sublime_security/data_stream/message_event/agent/stream/aws-s3.yml.hbs
create mode 100644 packages/sublime_security/data_stream/message_event/agent/stream/cel.yml.hbs
create mode 100644 packages/sublime_security/data_stream/message_event/elasticsearch/ingest_pipeline/default.yml
create mode 100644 packages/sublime_security/data_stream/message_event/fields/base-fields.yml
create mode 100644 packages/sublime_security/data_stream/message_event/fields/beats.yml
create mode 100644 packages/sublime_security/data_stream/message_event/fields/fields.yml
create mode 100644 packages/sublime_security/data_stream/message_event/manifest.yml
create mode 100644 packages/sublime_security/data_stream/message_event/sample_event.json
create mode 100644 packages/sublime_security/docs/README.md
create mode 100644 packages/sublime_security/img/sublime_security-audit.png
create mode 100644 packages/sublime_security/img/sublime_security-dark.svg
create mode 100644 packages/sublime_security/img/sublime_security-email_message.png
create mode 100644 packages/sublime_security/img/sublime_security-message_event.png
create mode 100644 packages/sublime_security/img/sublime_security.svg
create mode 100644 packages/sublime_security/kibana/dashboard/sublime_security-779aade2-fbb2-425d-8647-79c2bdf2d6e0.json
create mode 100644 packages/sublime_security/kibana/dashboard/sublime_security-7b4299fc-2465-46c6-bc55-dba692bb2745.json
create mode 100644 packages/sublime_security/kibana/dashboard/sublime_security-f4f4e3ca-1993-4a55-9d87-a7029ee0f869.json
create mode 100644 packages/sublime_security/kibana/search/sublime_security-c1e2d194-7f19-46fe-bcdf-d6886edf9d3d.json
create mode 100644 packages/sublime_security/kibana/search/sublime_security-ce2a4b74-76ca-4cdd-b3da-73530ee043c4.json
create mode 100644 packages/sublime_security/kibana/search/sublime_security-eb590f03-79df-4189-aa74-3b5bfe20e8ca.json
create mode 100644 packages/sublime_security/kibana/tag/sublime_security-security-solution-default.json
create mode 100644 packages/sublime_security/kibana/tags.yml
create mode 100644 packages/sublime_security/manifest.yml
create mode 100644 packages/sublime_security/validation.yml
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 75ede3f363c..60f44451053 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -326,6 +326,7 @@
/packages/stan @elastic/obs-infraobs-integrations
/packages/statsd_input @elastic/obs-infraobs-integrations
/packages/stormshield @elastic/sec-deployment-and-devices
+/packages/sublime_security @elastic/security-service-integrations
/packages/suricata @elastic/sec-deployment-and-devices
/packages/symantec_edr_cloud @elastic/security-service-integrations
/packages/symantec_endpoint @elastic/security-service-integrations
diff --git a/packages/sublime_security/_dev/build/build.yml b/packages/sublime_security/_dev/build/build.yml
new file mode 100644
index 00000000000..e2b012548e0
--- /dev/null
+++ b/packages/sublime_security/_dev/build/build.yml
@@ -0,0 +1,3 @@
+dependencies:
+ ecs:
+ reference: git@v8.11.0
diff --git a/packages/sublime_security/_dev/build/docs/README.md b/packages/sublime_security/_dev/build/docs/README.md
new file mode 100644
index 00000000000..09611cd549a
--- /dev/null
+++ b/packages/sublime_security/_dev/build/docs/README.md
@@ -0,0 +1,120 @@
+# Sublime Security
+
+Sublime Security is a programmable, AI-powered, cloud email security platform for Microsoft 365 and Google Workspace environments. It is used to block email attacks such as phishing, BEC, malware, threat hunt, and auto-triage user reports.
+
+The Sublime Security integration collects data for Audit, Email Message(MDM Schema) and Message Event logs using REST API and AWS-S3 or AWS-SQS:
+
+- REST API mode - Sublime Security integration collects and parses data from the Sublime Security REST APIs.
+- AWS S3 polling mode - Sublime Security writes data to S3 and Elastic Agent polls the S3 bucket by listing its contents and reading new files.
+- AWS S3 SQS mode - Sublime Security writes data to S3, S3 pushes a new object notification to SQS, Elastic Agent receives the notification from SQS, and then reads the S3 object. Multiple Agents can be used in this mode.
+
+## Data streams
+
+The Sublime Security integration collects three types of logs:
+
+**[Audit](https://docs.sublime.security/reference/listeventsinauditlog)** - Captures detailed records of all significant actions and changes within the platform, including changes to email security policies, user access to email data, and modifications to email configurations, ensuring traceability and compliance for all operations.
+
+**[Email Message](https://docs.sublime.security/docs/export-message-mdms)** - Represents the flow of individual emails through the platform, including sender and recipient details, spam filtering outcomes, and overall email disposition, helping to secure and analyze email communication.
+
+**[Message Event](https://docs.sublime.security/reference/getmessage-1)** - Represents document specific actions taken on emails, like spam detection or rule applications, providing detailed insights into how the platform processes and protects email communications.
+
+## Requirements
+
+Elastic Agent must be installed. For more information, refer to the link [here](https://www.elastic.co/guide/en/fleet/current/elastic-agent-installation.html).
+
+### Installing and managing an Elastic Agent:
+
+You have a few options for installing and managing an Elastic Agent:
+
+### Install a Fleet-managed Elastic Agent (recommended):
+
+With this approach, you install Elastic Agent and use Fleet in Kibana to define, configure, and manage your agents in a central location. We recommend using Fleet management because it makes the management and upgrade of your agents considerably easier.
+
+### Install Elastic Agent in standalone mode (advanced users):
+
+With this approach, you install Elastic Agent and manually configure the agent locally on the system where it’s installed. You are responsible for managing and upgrading the agents. This approach is reserved for advanced users only.
+
+### Install Elastic Agent in a containerized environment:
+
+You can run Elastic Agent inside a container, either with Fleet Server or standalone. Docker images for all versions of Elastic Agent are available from the Elastic Docker registry, and we provide deployment manifests for running on Kubernetes.
+
+There are some minimum requirements for running Elastic Agent and for more information, refer to the link [here](https://www.elastic.co/guide/en/fleet/current/elastic-agent-installation.html#_minimum_requirements).
+
+## Setup
+
+### To collect data from the Sublime Security API:
+
+#### Step 1: Go to Platform
+- Visit the [Sublime Security Platform](https://platform.sublime.security/) and select `API` in Developers section.
+
+#### Step 2: Generating the API Key
+- Retrieve your `API Key`. This key will be used further in the Elastic integration setup to authenticate and access different Sublime Security Logs.
+- `Base URL` of Sublime Security is also required for configuring integration.
+
+**Note**: Users with the `Admin` role are allowed to access `Audit` logs. For more information, refer [here](https://docs.sublime.security/docs/role-based-access-control-rbac).
+
+### To collect data from AWS S3 Bucket or AWS SQS:
+
+#### For AWS S3 Bucket, follow the below steps:
+- Create an Amazon S3 bucket. Refer to the link [here](https://docs.aws.amazon.com/AmazonS3/latest/userguide/create-bucket-overview.html).
+- User can set the parameter "Bucket List Prefix" according to the requirement.
+
+#### For AWS SQS, follow the below steps:
+1. If data forwarding to an AWS S3 Bucket hasn't been configured, then first set up an AWS S3 Bucket as mentioned in the above documentation.
+2. To set up an SQS queue, follow "Step 1: Create an Amazon SQS queue" mentioned in the [Documentation](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ways-to-add-notification-config-to-bucket.html).
+ - While creating an SQS Queue, please provide the same bucket ARN that has been generated after creating an AWS S3 Bucket.
+3. Set up event notifications for a S3 bucket. Follow this [link](https://docs.aws.amazon.com/AmazonS3/latest/userguide/enable-event-notifications.html).
+ - Users have to set the prefix parameter the same as the S3 Bucket List Prefix as created earlier. (for example, `exports/sublime_platform_audit_log/` for a audit data stream).
+ - Select the event type as s3:ObjectCreated:*, select the destination type SQS Queue, and select the queue that has been created in Step 2.
+
+**Note**:
+ - Credentials for the above AWS S3 and SQS input types should be configured using the [link](https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-input-aws-s3.html#aws-credentials-config).
+ - Data collection via AWS S3 Bucket and AWS SQS are mutually exclusive in this case.
+ - You can configure a global SQS queue for all data streams or a local SQS queue for each data stream. Configuring data stream specific SQS queues will enable better performance and scalability. Data stream specific SQS queues will always override any global queue definitions for that specific data stream.
+
+### Enabling the integration in Elastic:
+
+1. In Kibana go to Management > Integrations.
+2. In "Search for integrations" search bar, type Sublime Security.
+3. Click on the "Sublime Security" integration from the search results.
+4. Click on the "Add Sublime Security" button to add the integration.
+5. Enable the Integration to collect logs via AWS S3 or API input.
+6. Under the AWS S3 input, there are two types of inputs: using AWS S3 Bucket or using SQS.
+7. Add all the required integration configuration parameters, including API Key, Interval, Initial Interval and Page Size for API input and Access Key, Secret Key and Session Token for AWS input type to enable data collection.
+8. Click on "Save and continue" to save the integration.
+
+**Note**:
+- The Base URL for Sublime Security cloud customers is `https://api.platform.sublimesecurity.com`. Depending on your type of deployment, yours may be different.
+- For SSO users, in addition to access key ID and secret access key, the session token is required to configure integration. For IAM users, the session token is optional and not required.
+
+## Logs reference
+
+### Audit
+
+This is the `audit` dataset.
+
+#### Example
+
+{{event "audit"}}
+
+{{fields "audit"}}
+
+### Email Message
+
+This is the `email_message` dataset.
+
+#### Example
+
+{{event "email_message"}}
+
+{{fields "email_message"}}
+
+### Message Event
+
+This is the `message_event` dataset.
+
+#### Example
+
+{{event "message_event"}}
+
+{{fields "message_event"}}
diff --git a/packages/sublime_security/changelog.yml b/packages/sublime_security/changelog.yml
new file mode 100644
index 00000000000..6b875ef8f08
--- /dev/null
+++ b/packages/sublime_security/changelog.yml
@@ -0,0 +1,6 @@
+# newer versions go on top
+- version: 0.1.0
+ changes:
+ - description: Initial release.
+ type: enhancement
+ link: https://github.com/elastic/integrations/pull/10805
diff --git a/packages/sublime_security/data_stream/audit/_dev/deploy/docker/docker-compose.yml b/packages/sublime_security/data_stream/audit/_dev/deploy/docker/docker-compose.yml
new file mode 100644
index 00000000000..979573f79b3
--- /dev/null
+++ b/packages/sublime_security/data_stream/audit/_dev/deploy/docker/docker-compose.yml
@@ -0,0 +1,15 @@
+version: '2.3'
+services:
+ sublime_security:
+ image: docker.elastic.co/observability/stream:v0.15.0
+ hostname: sublime_security
+ ports:
+ - 8090
+ volumes:
+ - ./files:/files:ro
+ environment:
+ PORT: '8090'
+ command:
+ - http-server
+ - --addr=:8090
+ - --config=/files/config.yml
diff --git a/packages/sublime_security/data_stream/audit/_dev/deploy/docker/files/config.yml b/packages/sublime_security/data_stream/audit/_dev/deploy/docker/files/config.yml
new file mode 100644
index 00000000000..819414b3ab6
--- /dev/null
+++ b/packages/sublime_security/data_stream/audit/_dev/deploy/docker/files/config.yml
@@ -0,0 +1,128 @@
+rules:
+ - path: /v0/audit-log/events
+ methods: ['GET']
+ query_params:
+ limit: 1
+ offset: 0
+ request_headers:
+ Authorization:
+ - 'Bearer xxxx'
+ responses:
+ - status_code: 200
+ headers:
+ Content-Type:
+ - 'application/json'
+ body: |-
+ {{ minify_json `
+ {
+ "events": [
+ {
+ "id": "bd49af79-0cfb-4184-bd18-b0401d69ac61",
+ "type": "message_group.search",
+ "created_at": "2024-08-12T06:04:03.714126Z",
+ "data": {
+ "request": {
+ "id": "6ad202de-0def-423d-a0f2-549402e1a9c9",
+ "path": "/v0/message-groups",
+ "method": "GET",
+ "body": "",
+ "authentication_method": "api_key",
+ "ip": "1.128.0.0",
+ "user_agent": "Go-http-client/1.1",
+ "api_key_name": "demo mode local"
+ }
+ },
+ "created_by": {
+ "id": "6e6eca05-4fea-406b-86d4-b40177e25474",
+ "active": true,
+ "first_name": "Demo",
+ "last_name": "User",
+ "email_address": "demo@example.com",
+ "phone_number": null,
+ "created_at": "2024-07-12T05:13:47.879426Z",
+ "updated_at": "2024-07-12T05:13:47.879426Z",
+ "role": "admin",
+ "is_enrolled": true,
+ "google_oauth_user_id": "d83rb8et4-refe-fe7t4f8efe",
+ "microsoft_oauth_user_id": "fhe7t4bgf8-freu-ebfur94ref"
+ }
+ }
+ ],
+ "count": 1,
+ "total": 2
+ }
+ `}}
+ - path: /v0/audit-log/events
+ methods: ['GET']
+ query_params:
+ limit: 1
+ offset: 1
+ request_headers:
+ Authorization:
+ - "Bearer xxxx"
+ responses:
+ - status_code: 200
+ headers:
+ Content-Type:
+ - 'application/json'
+ body: |-
+ {{ minify_json `
+ {
+ "events": [
+ {
+ "id": "bd49af79-0cfj-4184-bd18-b0401d69ac61",
+ "type": "message_group.search",
+ "created_at": "2024-08-12T06:04:03.714126Z",
+ "data": {
+ "request": {
+ "id": "6ad202de-0def-423d-a0f2-549402e1a9c9",
+ "path": "/v0/message-groups",
+ "method": "GET",
+ "body": "",
+ "authentication_method": "api_key",
+ "ip": "175.16.199.0",
+ "user_agent": "Go-http-client/1.1",
+ "api_key_name": "demo mode local-2"
+ }
+ },
+ "created_by": {
+ "id": "6e6eca05-4fea-406b-86d4-b40177e25474",
+ "active": true,
+ "first_name": "User",
+ "last_name": "Doe",
+ "email_address": "user@example.com",
+ "phone_number": null,
+ "created_at": "2024-07-12T05:13:47.879426Z",
+ "updated_at": "2024-07-12T05:13:47.879426Z",
+ "role": "admin",
+ "is_enrolled": true,
+ "google_oauth_user_id": "",
+ "microsoft_oauth_user_id": ""
+ }
+ }
+ ],
+ "count": 1,
+ "total": 2
+ }
+ `}}
+ - path: /v0/audit-log/events
+ methods: ['GET']
+ query_params:
+ limit: 1
+ offset: 2
+ request_headers:
+ Authorization:
+ - "Bearer xxxx"
+ responses:
+ - status_code: 200
+ headers:
+ Content-Type:
+ - 'application/json'
+ body: |-
+ {{ minify_json `
+ {
+ "events": [],
+ "count": 0,
+ "total": 2
+ }
+ `}}
\ No newline at end of file
diff --git a/packages/sublime_security/data_stream/audit/_dev/test/pipeline/test-audit.log b/packages/sublime_security/data_stream/audit/_dev/test/pipeline/test-audit.log
new file mode 100644
index 00000000000..309a4b8b364
--- /dev/null
+++ b/packages/sublime_security/data_stream/audit/_dev/test/pipeline/test-audit.log
@@ -0,0 +1 @@
+{"id":"26704b44-d1b0-4362-8221-579e604f40cb","type":"message_group.search","created_at":"2024-07-30T05:33:47.725649Z","data":{"request":{"id":"ca817b01-cfaa-40ea-ab80-30b6a8e6ef08","path":"/v1/messages/groups/search","method":"GET","query":{},"body":"","api_key_name":"demo mode key","authentication_method":"api_key","ip":"81.2.69.142","user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36"}},"created_by":{"id":"6e6eca05-4fea-406b-86d4-b40177e25474","active":true,"first_name":"Bob","last_name":"User","email_address":"bob@example.com","phone_number":null,"created_at":"2024-07-12T05:13:47.879426Z","updated_at":"2024-07-12T05:13:47.879426Z","role":"admin","is_enrolled":true,"google_oauth_user_id":"","microsoft_oauth_user_id":""}}
diff --git a/packages/sublime_security/data_stream/audit/_dev/test/pipeline/test-audit.log-expected.json b/packages/sublime_security/data_stream/audit/_dev/test/pipeline/test-audit.log-expected.json
new file mode 100644
index 00000000000..413b0446385
--- /dev/null
+++ b/packages/sublime_security/data_stream/audit/_dev/test/pipeline/test-audit.log-expected.json
@@ -0,0 +1,112 @@
+{
+ "expected": [
+ {
+ "@timestamp": "2024-07-30T05:33:47.725Z",
+ "ecs": {
+ "version": "8.11.0"
+ },
+ "event": {
+ "action": "search",
+ "id": "26704b44-d1b0-4362-8221-579e604f40cb",
+ "kind": "event",
+ "original": "{\"id\":\"26704b44-d1b0-4362-8221-579e604f40cb\",\"type\":\"message_group.search\",\"created_at\":\"2024-07-30T05:33:47.725649Z\",\"data\":{\"request\":{\"id\":\"ca817b01-cfaa-40ea-ab80-30b6a8e6ef08\",\"path\":\"/v1/messages/groups/search\",\"method\":\"GET\",\"query\":{},\"body\":\"\",\"api_key_name\":\"demo mode key\",\"authentication_method\":\"api_key\",\"ip\":\"81.2.69.142\",\"user_agent\":\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36\"}},\"created_by\":{\"id\":\"6e6eca05-4fea-406b-86d4-b40177e25474\",\"active\":true,\"first_name\":\"Bob\",\"last_name\":\"User\",\"email_address\":\"bob@example.com\",\"phone_number\":null,\"created_at\":\"2024-07-12T05:13:47.879426Z\",\"updated_at\":\"2024-07-12T05:13:47.879426Z\",\"role\":\"admin\",\"is_enrolled\":true,\"google_oauth_user_id\":\"\",\"microsoft_oauth_user_id\":\"\"}}",
+ "type": [
+ "info"
+ ]
+ },
+ "http": {
+ "request": {
+ "id": "ca817b01-cfaa-40ea-ab80-30b6a8e6ef08",
+ "method": "GET"
+ }
+ },
+ "observer": {
+ "product": "Sublime Security",
+ "vendor": "Sublime Security"
+ },
+ "related": {
+ "ip": [
+ "81.2.69.142"
+ ],
+ "user": [
+ "bob@example.com",
+ "Bob",
+ "6e6eca05-4fea-406b-86d4-b40177e25474"
+ ]
+ },
+ "source": {
+ "geo": {
+ "city_name": "London",
+ "continent_name": "Europe",
+ "country_iso_code": "GB",
+ "country_name": "United Kingdom",
+ "location": {
+ "lat": 51.5142,
+ "lon": -0.0931
+ },
+ "region_iso_code": "GB-ENG",
+ "region_name": "England"
+ },
+ "ip": "81.2.69.142"
+ },
+ "sublime_security": {
+ "audit": {
+ "created_at": "2024-07-30T05:33:47.725Z",
+ "created_by": {
+ "active": true,
+ "created_at": "2024-07-12T05:13:47.879Z",
+ "email_address": "bob@example.com",
+ "first_name": "Bob",
+ "id": "6e6eca05-4fea-406b-86d4-b40177e25474",
+ "is_enrolled": true,
+ "last_name": "User",
+ "role": "admin",
+ "updated_at": "2024-07-12T05:13:47.879Z"
+ },
+ "data": {
+ "request": {
+ "api_key_name": "demo mode key",
+ "authentication_method": "api_key",
+ "id": "ca817b01-cfaa-40ea-ab80-30b6a8e6ef08",
+ "ip": "81.2.69.142",
+ "method": "GET",
+ "path": "/v1/messages/groups/search",
+ "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36"
+ }
+ },
+ "id": "26704b44-d1b0-4362-8221-579e604f40cb",
+ "type": "message_group.search"
+ }
+ },
+ "tags": [
+ "preserve_duplicate_custom_fields"
+ ],
+ "url": {
+ "path": "/v1/messages/groups/search"
+ },
+ "user": {
+ "domain": "example.com",
+ "email": "bob@example.com",
+ "full_name": "Bob User",
+ "id": "6e6eca05-4fea-406b-86d4-b40177e25474",
+ "name": "bob",
+ "roles": [
+ "admin"
+ ]
+ },
+ "user_agent": {
+ "device": {
+ "name": "Other"
+ },
+ "name": "Chrome",
+ "original": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",
+ "os": {
+ "full": "Windows 10",
+ "name": "Windows",
+ "version": "10"
+ },
+ "version": "126.0.0.0"
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/packages/sublime_security/data_stream/audit/_dev/test/pipeline/test-common-config.yml b/packages/sublime_security/data_stream/audit/_dev/test/pipeline/test-common-config.yml
new file mode 100644
index 00000000000..37e8fa225fd
--- /dev/null
+++ b/packages/sublime_security/data_stream/audit/_dev/test/pipeline/test-common-config.yml
@@ -0,0 +1,3 @@
+fields:
+ tags:
+ - preserve_duplicate_custom_fields
diff --git a/packages/sublime_security/data_stream/audit/_dev/test/system/test-cel-config.yml b/packages/sublime_security/data_stream/audit/_dev/test/system/test-cel-config.yml
new file mode 100644
index 00000000000..0203226c2de
--- /dev/null
+++ b/packages/sublime_security/data_stream/audit/_dev/test/system/test-cel-config.yml
@@ -0,0 +1,13 @@
+input: cel
+service: sublime_security
+vars:
+ url: http://{{Hostname}}:{{Port}}
+ api_key: xxxx
+data_stream:
+ vars:
+ interval: 5m
+ page_size: 1
+ preserve_original_event: true
+ preserve_duplicate_custom_fields: true
+assert:
+ hit_count: 2
diff --git a/packages/sublime_security/data_stream/audit/agent/stream/aws-s3.yml.hbs b/packages/sublime_security/data_stream/audit/agent/stream/aws-s3.yml.hbs
new file mode 100644
index 00000000000..7bf0e86682e
--- /dev/null
+++ b/packages/sublime_security/data_stream/audit/agent/stream/aws-s3.yml.hbs
@@ -0,0 +1,97 @@
+{{#if collect_s3_logs}}
+
+{{#if bucket_arn}}
+bucket_arn: {{bucket_arn}}
+{{/if}}
+{{#if number_of_workers}}
+number_of_workers: {{number_of_workers}}
+{{/if}}
+{{#if interval}}
+bucket_list_interval: {{interval}}
+{{/if}}
+{{#if bucket_list_prefix}}
+bucket_list_prefix: {{bucket_list_prefix}}
+{{/if}}
+
+{{else}}
+
+{{#if queue_url}}
+queue_url: {{queue_url}}
+{{/if}}
+{{#if region}}
+region: {{region}}
+{{/if}}
+{{#if visibility_timeout}}
+visibility_timeout: {{visibility_timeout}}
+{{/if}}
+{{#if api_timeout}}
+api_timeout: {{api_timeout}}
+{{/if}}
+{{#if max_number_of_messages}}
+max_number_of_messages: {{max_number_of_messages}}
+{{/if}}
+{{#if file_selectors}}
+file_selectors:
+{{file_selectors}}
+{{/if}}
+
+{{/if}}
+
+expand_event_list_from_field: events
+content_type: application/json
+{{#if access_key_id}}
+access_key_id: {{access_key_id}}
+{{/if}}
+{{#if secret_access_key}}
+secret_access_key: {{secret_access_key}}
+{{/if}}
+{{#if session_token}}
+session_token: {{session_token}}
+{{/if}}
+{{#if shared_credential_file}}
+shared_credential_file: {{shared_credential_file}}
+{{/if}}
+{{#if credential_profile_name}}
+credential_profile_name: {{credential_profile_name}}
+{{/if}}
+{{#if role_arn}}
+role_arn: {{role_arn}}
+{{/if}}
+{{#if external_id}}
+external_id: {{external_id}}
+{{/if}}
+{{#if default_region}}
+default_region: {{default_region}}
+{{/if}}
+
+{{#if fips_enabled}}
+fips_enabled: {{fips_enabled}}
+{{/if}}
+{{#if proxy_url}}
+proxy_url: {{proxy_url}}
+{{/if}}
+{{#if ssl}}
+ssl: {{ssl}}
+{{/if}}
+tags:
+{{#if collect_s3_logs}}
+ - collect_s3_logs
+{{else}}
+ - collect_sqs_logs
+{{/if}}
+{{#if preserve_original_event}}
+ - preserve_original_event
+{{/if}}
+{{#if preserve_duplicate_custom_fields}}
+ - preserve_duplicate_custom_fields
+{{/if}}
+{{#each tags as |tag|}}
+ - {{tag}}
+{{/each}}
+{{#contains "forwarded" tags}}
+publisher_pipeline.disable_host: true
+{{/contains}}
+{{#if processors}}
+processors:
+{{processors}}
+{{/if}}
diff --git a/packages/sublime_security/data_stream/audit/agent/stream/cel.yml.hbs b/packages/sublime_security/data_stream/audit/agent/stream/cel.yml.hbs
new file mode 100644
index 00000000000..09176ba2488
--- /dev/null
+++ b/packages/sublime_security/data_stream/audit/agent/stream/cel.yml.hbs
@@ -0,0 +1,79 @@
+config_version: 2
+interval: {{interval}}
+{{#if enable_request_tracer}}
+resource.tracer.filename: "../../logs/cel/http-request-trace-*.ndjson"
+resource.tracer.maxbackups: 5
+{{/if}}
+{{#if proxy_url}}
+resource.proxy_url: {{proxy_url}}
+{{/if}}
+{{#if ssl}}
+resource.ssl: {{ssl}}
+{{/if}}
+{{#if http_client_timeout}}
+resource.timeout: {{http_client_timeout}}
+{{/if}}
+resource.url: {{url}}
+state:
+ page_size: {{page_size}}
+ offset: 0
+ api_key: {{api_key}}
+redact:
+ fields:
+ - api_key
+program: |
+ state.with(
+ request(
+ "GET",
+ state.url.trim_right("/") + "/v0/audit-log/events?" + {
+ "limit": [string(state.page_size)],
+ "offset": [string(state.offset)]
+ }.format_query()
+ ).with({
+ "Header": {
+ "Authorization": ["Bearer " + state.api_key],
+ },
+ }).do_request().as(resp, resp.StatusCode == 200 ?
+ bytes(resp.Body).decode_json().as(body,{
+ "events": body.events.map(e,{
+ "message": e.encode_json()
+ }),
+ "offset": size(body.events) > 0 ? int(state.offset) + int(state.page_size) : 0,
+ "want_more": size(body.events) > 0,
+ })
+ :
+ {
+ "events": {
+ "error": {
+ "code": string(resp.StatusCode),
+ "id": string(resp.Status),
+ "message": "GET:"+(
+ size(resp.Body) != 0 ?
+ string(resp.Body)
+ :
+ string(resp.Status) + ' (' + string(resp.StatusCode) + ')'
+ ),
+ },
+ },
+ "want_more": false,
+ "offset": 0,
+ }
+ )
+ )
+tags:
+{{#if preserve_original_event}}
+ - preserve_original_event
+{{/if}}
+{{#if preserve_duplicate_custom_fields}}
+ - preserve_duplicate_custom_fields
+{{/if}}
+{{#each tags as |tag|}}
+ - {{tag}}
+{{/each}}
+{{#contains "forwarded" tags}}
+publisher_pipeline.disable_host: true
+{{/contains}}
+{{#if processors}}
+processors:
+{{processors}}
+{{/if}}
diff --git a/packages/sublime_security/data_stream/audit/elasticsearch/ingest_pipeline/default.yml b/packages/sublime_security/data_stream/audit/elasticsearch/ingest_pipeline/default.yml
new file mode 100644
index 00000000000..1be49745477
--- /dev/null
+++ b/packages/sublime_security/data_stream/audit/elasticsearch/ingest_pipeline/default.yml
@@ -0,0 +1,414 @@
+---
+description: Pipeline for processing audit logs.
+processors:
+ - set:
+ field: ecs.version
+ tag: set_ecs_version
+ value: 8.11.0
+ - fail:
+ tag: data_collection_error
+ if: ctx.error?.message != null && ctx.message == null && ctx.event?.original == null
+ message: error message set and no data to process.
+ - rename:
+ field: message
+ tag: rename_message_to_event_original
+ target_field: event.original
+ ignore_missing: true
+ description: Renames the original `message` field to `event.original` to store a copy of the original message. The `event.original` field is not touched if the document already has one; it may happen when Logstash sends the document.
+ if: ctx.event?.original == null
+ - remove:
+ field: message
+ tag: remove_message
+ ignore_missing: true
+ description: The `message` field is no longer required if the document has an `event.original` field.
+ if: ctx.event?.original != null
+ - json:
+ field: event.original
+ tag: json_event_original
+ target_field: json
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - fingerprint:
+ fields:
+ - json.created_at
+ - json.id
+ tag: fingerprint_audit_event
+ target_field: _id
+ ignore_missing: true
+ - set:
+ field: event.kind
+ tag: set_event_kind_to_event
+ value: event
+ - append:
+ field: event.type
+ tag: append_info_into_event_type
+ value: info
+ allow_duplicates: false
+ - set:
+ field: observer.vendor
+ tag: set_observer_vendor
+ value: Sublime Security
+ - set:
+ field: observer.product
+ tag: set_observer_product
+ value: Sublime Security
+ - date:
+ field: json.created_at
+ tag: date_created_at
+ target_field: sublime_security.audit.created_at
+ formats:
+ - ISO8601
+ if: ctx.json?.created_at != null && ctx.json.created_at != ''
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - set:
+ field: '@timestamp'
+ tag: set_@timestamp_from_audit_created_at
+ copy_from: sublime_security.audit.created_at
+ ignore_empty_value: true
+ - convert:
+ field: json.created_by.active
+ tag: convert_created_by_active_to_boolean
+ target_field: sublime_security.audit.created_by.active
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - date:
+ field: json.created_by.created_at
+ tag: date_created_by_created_at
+ target_field: sublime_security.audit.created_by.created_at
+ formats:
+ - ISO8601
+ if: ctx.json?.created_by?.created_at != null && ctx.json.created_by.created_at != ''
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - date:
+ field: json.created_by.deleted_at
+ tag: date_created_by_deleted_at
+ target_field: sublime_security.audit.created_by.deleted_at
+ formats:
+ - ISO8601
+ if: ctx.json?.created_by?.deleted_at != null && ctx.json.created_by.deleted_at != ''
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - rename:
+ field: json.created_by.email_address
+ tag: rename_created_by_email_address
+ target_field: sublime_security.audit.created_by.email_address
+ ignore_missing: true
+ - dissect:
+ field: sublime_security.audit.created_by.email_address
+ tag: dissect_created_by_email_address
+ description: Extract username and domain from email address.
+ pattern: '%{user.name}@%{user.domain}'
+ if: ctx.sublime_security?.audit?.created_by?.email_address != null
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag fail-{{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - set:
+ field: user.email
+ tag: set_user_email_from_audit_created_by_email_address
+ copy_from: sublime_security.audit.created_by.email_address
+ ignore_empty_value: true
+ - append:
+ field: related.user
+ tag: append_audit_created_by_email_address_into_related_user
+ value: '{{{sublime_security.audit.created_by.email_address}}}'
+ allow_duplicates: false
+ if: ctx.sublime_security?.audit?.created_by?.email_address != null
+ - rename:
+ field: json.created_by.first_name
+ tag: rename_created_by_first_name
+ target_field: sublime_security.audit.created_by.first_name
+ ignore_missing: true
+ - append:
+ field: related.user
+ tag: append_audit_created_by_first_name_into_related_user
+ value: '{{{sublime_security.audit.created_by.first_name}}}'
+ allow_duplicates: false
+ if: ctx.sublime_security?.audit?.created_by?.email_address != null
+ - rename:
+ field: json.created_by.last_name
+ tag: rename_created_by_last_name
+ target_field: sublime_security.audit.created_by.last_name
+ ignore_missing: true
+ - set:
+ field: user.full_name
+ tag: set_user_name_from_audit_created_by_first_name_and_last_name
+ value: '{{{sublime_security.audit.created_by.first_name}}} {{{sublime_security.audit.created_by.last_name}}}'
+ if: ctx.sublime_security?.audit?.created_by?.first_name != null && ctx.sublime_security.audit.created_by?.last_name != null
+ ignore_empty_value: true
+ - rename:
+ field: json.created_by.google_oauth_user_id
+ tag: rename_created_by_google_oauth_user_id
+ target_field: sublime_security.audit.created_by.google_oauth_user_id
+ ignore_missing: true
+ - append:
+ field: related.user
+ tag: append_audit_created_by_google_oauth_user_id_into_related_user
+ value: '{{{sublime_security.audit.created_by.google_oauth_user_id}}}'
+ allow_duplicates: false
+ if: ctx.sublime_security?.audit?.created_by?.google_oauth_user_id != null
+ - rename:
+ field: json.created_by.id
+ tag: rename_created_by_id
+ target_field: sublime_security.audit.created_by.id
+ ignore_missing: true
+ - set:
+ field: user.id
+ tag: set_user_id_from_audit_created_by_id
+ copy_from: sublime_security.audit.created_by.id
+ ignore_empty_value: true
+ - append:
+ field: related.user
+ tag: append_audit_created_by_id_into_related_user
+ value: '{{{sublime_security.audit.created_by.id}}}'
+ allow_duplicates: false
+ if: ctx.sublime_security?.audit?.created_by?.id != null
+ - convert:
+ field: json.created_by.is_enrolled
+ tag: convert_created_by_is_enrolled_to_boolean
+ target_field: sublime_security.audit.created_by.is_enrolled
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - rename:
+ field: json.created_by.microsoft_oauth_user_id
+ tag: rename_created_by_microsoft_oauth_user_id
+ target_field: sublime_security.audit.created_by.microsoft_oauth_user_id
+ ignore_missing: true
+ - append:
+ field: related.user
+ tag: append_audit_created_by_microsoft_oauth_user_id_into_related_user
+ value: '{{{sublime_security.audit.created_by.microsoft_oauth_user_id}}}'
+ allow_duplicates: false
+ if: ctx.sublime_security?.audit?.created_by?.microsoft_oauth_user_id != null
+ - rename:
+ field: json.created_by.phone_number
+ tag: rename_created_by_phone_number
+ target_field: sublime_security.audit.created_by.phone_number
+ ignore_missing: true
+ - rename:
+ field: json.created_by.role
+ tag: rename_created_by_role
+ target_field: sublime_security.audit.created_by.role
+ ignore_missing: true
+ - append:
+ field: user.roles
+ tag: append_sublime_security_audit_created_by_role_into_user_roles
+ value: '{{{sublime_security.audit.created_by.role}}}'
+ allow_duplicates: false
+ if: ctx.sublime_security?.audit?.created_by?.role != null
+ - date:
+ field: json.created_by.updated_at
+ tag: date_created_by_updated_at
+ target_field: sublime_security.audit.created_by.updated_at
+ formats:
+ - ISO8601
+ if: ctx.json?.created_by?.updated_at != null && ctx.json.created_by.updated_at != ''
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - rename:
+ field: json.data.message.id
+ tag: rename_data_message_id
+ target_field: sublime_security.audit.data.message.id
+ ignore_missing: true
+ - rename:
+ field: json.data.message_group.id
+ tag: rename_data_message_group_id
+ target_field: sublime_security.audit.data.message_group.id
+ ignore_missing: true
+ - rename:
+ field: json.data.request.api_key_name
+ tag: rename_data_request_api_key_name
+ target_field: sublime_security.audit.data.request.api_key_name
+ ignore_missing: true
+ - rename:
+ field: json.data.request.authentication_method
+ tag: rename_data_request_authentication_method
+ target_field: sublime_security.audit.data.request.authentication_method
+ ignore_missing: true
+ - rename:
+ field: json.data.request.body
+ tag: rename_data_request_body
+ target_field: sublime_security.audit.data.request.body
+ ignore_missing: true
+ - set:
+ field: http.request.body.content
+ tag: set_http_request_body_content_from_audit_data_request_body
+ copy_from: sublime_security.audit.data.request.body
+ ignore_empty_value: true
+ - rename:
+ field: json.data.request.id
+ tag: rename_data_request_id
+ target_field: sublime_security.audit.data.request.id
+ ignore_missing: true
+ - set:
+ field: http.request.id
+ tag: set_http_request_id_from_audit_data_request_id
+ copy_from: sublime_security.audit.data.request.id
+ ignore_empty_value: true
+ - convert:
+ field: json.data.request.ip
+ tag: convert_data_request_ip_to_ip
+ target_field: sublime_security.audit.data.request.ip
+ type: ip
+ ignore_missing: true
+ if: ctx.json?.data?.request?.ip != null && ctx.json.data.request.ip != ''
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - set:
+ field: source.ip
+ tag: set_source_ip_from_audit_data_request_ip
+ copy_from: sublime_security.audit.data.request.ip
+ ignore_empty_value: true
+ - geoip:
+ field: source.ip
+ target_field: source.geo
+ tag: geoip_source_ip
+ ignore_missing: true
+ - append:
+ field: related.ip
+ tag: append_source_ip_into_related_ip
+ value: '{{{source.ip}}}'
+ allow_duplicates: false
+ if: ctx.source?.ip != null
+ - rename:
+ field: json.data.request.method
+ tag: rename_data_request_method
+ target_field: sublime_security.audit.data.request.method
+ ignore_missing: true
+ - set:
+ field: http.request.method
+ tag: set_http_request_method_from_audit_data_request_method
+ copy_from: sublime_security.audit.data.request.method
+ ignore_empty_value: true
+ - rename:
+ field: json.data.request.path
+ tag: rename_data_request_path
+ target_field: sublime_security.audit.data.request.path
+ ignore_missing: true
+ - set:
+ field: url.path
+ tag: set_url_path_from_audit_data_request_path
+ copy_from: sublime_security.audit.data.request.path
+ ignore_empty_value: true
+ - rename:
+ field: json.data.request.query
+ tag: rename_data_request_query
+ target_field: sublime_security.audit.data.request.query
+ ignore_missing: true
+ - script:
+ lang: painless
+ description: Painless script to set url_query.
+ tag: painless_set_url_query
+ if: ctx.sublime_security?.audit?.data?.request?.query != null
+ source: |-
+ StringBuilder sb = new StringBuilder();
+ Map attributes = ctx.sublime_security.audit.data.request.query;
+ for (entry in attributes.entrySet()) {
+ sb.append(entry.getKey()).append('=').append(entry.getValue()).append('&');
+ }
+ if(ctx.url == null) {
+ ctx.put("url", new HashMap());
+ }
+ ctx.url.query = sb.length() > 0 ? sb.substring(0, sb.length() - 1) : null;
+ - rename:
+ field: json.data.request.user_agent
+ tag: rename_data_request_user_agent
+ target_field: sublime_security.audit.data.request.user_agent
+ ignore_missing: true
+ - user_agent:
+ field: sublime_security.audit.data.request.user_agent
+ ignore_missing: true
+ - rename:
+ field: json.id
+ tag: rename_id
+ target_field: sublime_security.audit.id
+ ignore_missing: true
+ - set:
+ field: event.id
+ tag: set_event_id_from_audit_id
+ copy_from: sublime_security.audit.id
+ ignore_empty_value: true
+ - rename:
+ field: json.type
+ tag: rename_type
+ target_field: sublime_security.audit.type
+ ignore_missing: true
+ - grok:
+ field: sublime_security.audit.type
+ tag: grok_event_action_from_audit_type
+ patterns:
+ - '.*.%{WORD:event.action}'
+ ignore_missing: true
+ - remove:
+ field:
+ - sublime_security.audit.created_at
+ - sublime_security.audit.created_by.email_address
+ - sublime_security.audit.created_by.id
+ - sublime_security.audit.created_by.role
+ - sublime_security.audit.data.request.body
+ - sublime_security.audit.data.request.id
+ - sublime_security.audit.data.request.ip
+ - sublime_security.audit.data.request.method
+ - sublime_security.audit.data.request.path
+ - sublime_security.audit.data.request.user_agent
+ - sublime_security.audit.id
+ tag: remove_custom_duplicate_fields
+ ignore_missing: true
+ if: ctx.tags == null || !(ctx.tags.contains('preserve_duplicate_custom_fields'))
+ - remove:
+ field: json
+ tag: remove_json
+ ignore_missing: true
+ - script:
+ lang: painless
+ description: Drops null/empty values recursively.
+ tag: painless_remove_null
+ source: |-
+ boolean drop(Object object) {
+ if (object == null || object == '') {
+ return true;
+ } else if (object instanceof Map) {
+ ((Map) object).values().removeIf(v -> drop(v));
+ return (((Map) object).size() == 0);
+ } else if (object instanceof List) {
+ ((List) object).removeIf(v -> drop(v));
+ return (((List) object).length == 0);
+ }
+ return false;
+ }
+ drop(ctx);
+ - set:
+ field: event.kind
+ value: pipeline_error
+ tag: set_pipeline_error_into_event_kind
+ if: ctx.error?.message != null
+on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - set:
+ field: event.kind
+ tag: set_pipeline_error_to_event_kind
+ value: pipeline_error
diff --git a/packages/sublime_security/data_stream/audit/fields/base-fields.yml b/packages/sublime_security/data_stream/audit/fields/base-fields.yml
new file mode 100644
index 00000000000..f9c75ce55dd
--- /dev/null
+++ b/packages/sublime_security/data_stream/audit/fields/base-fields.yml
@@ -0,0 +1,20 @@
+- name: data_stream.type
+ type: constant_keyword
+ description: Data stream type.
+- name: data_stream.dataset
+ type: constant_keyword
+ description: Data stream dataset.
+- name: data_stream.namespace
+ type: constant_keyword
+ description: Data stream namespace.
+- name: event.module
+ type: constant_keyword
+ description: Event module.
+ value: sublime_security
+- name: event.dataset
+ type: constant_keyword
+ description: Event dataset.
+ value: sublime_security.audit
+- name: '@timestamp'
+ type: date
+ description: Event timestamp.
diff --git a/packages/sublime_security/data_stream/audit/fields/beats.yml b/packages/sublime_security/data_stream/audit/fields/beats.yml
new file mode 100644
index 00000000000..4084f1dc7f5
--- /dev/null
+++ b/packages/sublime_security/data_stream/audit/fields/beats.yml
@@ -0,0 +1,6 @@
+- name: input.type
+ type: keyword
+ description: Type of filebeat input.
+- name: log.offset
+ type: long
+ description: Log offset.
diff --git a/packages/sublime_security/data_stream/audit/fields/fields.yml b/packages/sublime_security/data_stream/audit/fields/fields.yml
new file mode 100644
index 00000000000..6cef6ed7808
--- /dev/null
+++ b/packages/sublime_security/data_stream/audit/fields/fields.yml
@@ -0,0 +1,102 @@
+- name: sublime_security
+ type: group
+ fields:
+ - name: audit
+ type: group
+ fields:
+ - name: created_at
+ type: date
+ description: Event creation time.
+ - name: created_by
+ type: group
+ fields:
+ - name: active
+ type: boolean
+ - name: created_at
+ type: date
+ description: User creation time.
+ - name: deleted_at
+ type: date
+ description: User deletion time.
+ - name: email_address
+ type: keyword
+ description: Email address.
+ - name: first_name
+ type: keyword
+ description: First name.
+ - name: google_oauth_user_id
+ type: keyword
+ description: The user's Google user ID, if it exists.
+ - name: id
+ type: keyword
+ description: User ID.
+ - name: is_enrolled
+ type: boolean
+ description: Whether the user has begun using the system (e.g. accepted an invitation or logged in at least once).
+ - name: last_name
+ type: keyword
+ description: Last name.
+ - name: microsoft_oauth_user_id
+ type: keyword
+ description: The user's Microsoft user ID, if it exists.
+ - name: phone_number
+ type: keyword
+ description: Phone number.
+ - name: role
+ type: keyword
+ description: Role assumed by the user.
+ - name: updated_at
+ type: date
+ description: User last updated time.
+ - name: data
+ type: group
+ fields:
+ - name: message
+ type: group
+ fields:
+ - name: id
+ type: keyword
+ description: Message ID.
+ - name: message_group
+ type: group
+ fields:
+ - name: id
+ type: keyword
+ description: Message Group ID.
+ - name: request
+ type: group
+ fields:
+ - name: api_key_name
+ type: keyword
+ description: Name of API key if an API key was used.
+ - name: authentication_method
+ type: keyword
+ description: Description of how request was authenticated.
+ - name: body
+ type: keyword
+ description: Request body.
+ - name: id
+ type: keyword
+ description: API request ID.
+ - name: ip
+ type: ip
+ description: IP address of requester, if available.
+ - name: method
+ type: keyword
+ description: HTTP method.
+ - name: path
+ type: keyword
+ description: URL path.
+ - name: query
+ type: object
+ object_type: keyword
+ description: Query parameters.
+ - name: user_agent
+ type: keyword
+ description: User agent of requester, if available.
+ - name: id
+ type: keyword
+ description: Event ID.
+ - name: type
+ type: keyword
+ description: Event type.
diff --git a/packages/sublime_security/data_stream/audit/manifest.yml b/packages/sublime_security/data_stream/audit/manifest.yml
new file mode 100644
index 00000000000..6d2fd8a8c0e
--- /dev/null
+++ b/packages/sublime_security/data_stream/audit/manifest.yml
@@ -0,0 +1,188 @@
+title: Sublime Security Audit logs
+type: logs
+streams:
+ - input: cel
+ title: Sublime Security Audit logs
+ description: Collecting Sublime Security Audit logs via API.
+ enabled: false
+ template_path: cel.yml.hbs
+ vars:
+ - name: interval
+ type: text
+ title: Interval
+ description: Duration between requests to the Sublime Security API. Supported units for this parameter are h/m/s.
+ default: 1h
+ multi: false
+ required: true
+ show_user: true
+ - name: page_size
+ type: text
+ title: Page Size
+ multi: false
+ required: true
+ show_user: false
+ description: 'Page size for the response of the Sublime Security API. Note: The maximum limit is 500.'
+ default: 500
+ - name: http_client_timeout
+ type: text
+ title: HTTP Client Timeout
+ description: Duration before declaring that the HTTP client connection has timed out. Supported time units are ns, us, ms, s, m, h.
+ multi: false
+ required: true
+ show_user: false
+ default: 30s
+ - name: enable_request_tracer
+ type: bool
+ title: Enable request tracing
+ multi: false
+ required: false
+ show_user: false
+ description: >-
+ The request tracer logs requests and responses to the agent's local file-system for debugging configurations. Enabling this request tracing compromises security and should only be used for debugging. See [documentation](https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-input-cel.html#_resource_tracer_filename) for details.
+ - name: tags
+ type: text
+ title: Tags
+ multi: true
+ required: true
+ show_user: false
+ default:
+ - forwarded
+ - sublime_security-audit
+ - name: preserve_original_event
+ required: false
+ show_user: true
+ title: Preserve original event
+ description: Preserves a raw copy of the original event, added to the field `event.original`.
+ type: bool
+ multi: false
+ default: false
+ - name: preserve_duplicate_custom_fields
+ required: false
+ show_user: false
+ title: Preserve duplicate custom fields
+ description: Preserve sublime_security.audit fields that were copied to Elastic Common Schema (ECS) fields.
+ type: bool
+ multi: false
+ default: false
+ - name: processors
+ type: yaml
+ title: Processors
+ multi: false
+ required: false
+ show_user: false
+ description: >-
+ Processors are used to reduce the number of fields in the exported event or to enhance the event with metadata. This executes in the agent before the logs are parsed.
+ - input: aws-s3
+ template_path: aws-s3.yml.hbs
+ title: Sublime Security Audit logs via AWS S3 or SQS
+ description: Collecting Sublime Security Audit logs via AWS S3 or SQS input.
+ enabled: false
+ vars:
+ - name: bucket_arn
+ type: text
+ title: '[S3] Bucket ARN'
+ multi: false
+ required: false
+ show_user: true
+ description: ARN of the AWS S3 bucket that will be polled for list operation. It is a required parameter for collecting logs via the AWS S3.
+ - name: bucket_list_prefix
+ type: text
+ title: '[S3] Bucket Prefix'
+ multi: false
+ required: false
+ show_user: true
+ description: Prefix to apply for the list request to the S3 bucket.
+ - name: interval
+ type: text
+ title: '[S3] Interval'
+ multi: false
+ required: false
+ show_user: true
+ default: 120s
+ description: Listing of the S3 bucket will be polled according to the time interval defined by bucket_list_interval config. Default value is 120 secs. Supported units for this parameter are h/m/s.
+ - name: number_of_workers
+ type: integer
+ title: '[S3] Number of Workers'
+ multi: false
+ required: false
+ show_user: true
+ default: 5
+ description: Number of workers that will process the S3 objects listed.
+ - name: queue_url
+ type: text
+ title: '[SQS] Queue URL'
+ multi: false
+ required: false
+ show_user: true
+ description: URL of the AWS SQS queue that messages will be received from. It is a required parameter for collecting logs via the AWS SQS.
+ - name: visibility_timeout
+ type: text
+ title: '[SQS] Visibility Timeout'
+ multi: false
+ required: false
+ show_user: true
+ default: 300s
+ description: The duration that the received messages are hidden from subsequent retrieve requests after being retrieved by a ReceiveMessage request. The maximum is 12 hours. Supported units for this parameter are h/m/s.
+ - name: api_timeout
+ type: text
+ title: '[SQS] API Timeout'
+ multi: false
+ required: false
+ show_user: true
+ default: 120s
+ description: The maximum duration of AWS API can take. The maximum is half of the visibility timeout value. Supported units for this parameter are h/m/s.
+ - name: max_number_of_messages
+ type: integer
+ title: '[SQS] Maximum Concurrent SQS Messages'
+ required: false
+ show_user: true
+ default: 5
+ description: The maximum number of SQS messages that can be inflight at any time.
+ - name: file_selectors
+ type: yaml
+ title: '[SQS] File Selectors'
+ multi: false
+ required: false
+ show_user: false
+ description: >-
+ If the SQS queue will have events that correspond to files that this integration shouldn’t process, file_selectors can be used to limit the files that are downloaded. This is a list of selectors which are made up of regex and expand_event_list_from_field options. The regex should match the S3 object key in the SQS message, and the optional expand_event_list_from_field is the same as the global setting. If file_selectors is given, then any global expand_event_list_from_field value is ignored in favor of the ones specified in the file_selectors. Regexes use [RE2 syntax](https://pkg.go.dev/regexp/syntax). Files that do not match one of the regexes will not be processed.
+ - name: external_id
+ type: text
+ title: External ID
+ multi: false
+ required: false
+ show_user: false
+ description: External ID to use when assuming a role in another account.
+ - name: tags
+ type: text
+ title: Tags
+ multi: true
+ required: true
+ show_user: false
+ default:
+ - forwarded
+ - sublime_security-audit
+ - name: preserve_original_event
+ required: false
+ show_user: true
+ title: Preserve original event
+ description: Preserves a raw copy of the original event, added to the field `event.original`.
+ type: bool
+ multi: false
+ default: false
+ - name: preserve_duplicate_custom_fields
+ required: true
+ show_user: false
+ title: Preserve duplicate custom fields
+ description: Preserve sublime_security.audit fields that were mapped to Elastic Common Schema (ECS) fields.
+ type: bool
+ multi: false
+ default: false
+ - name: processors
+ type: yaml
+ title: Processors
+ multi: false
+ required: false
+ show_user: false
+ description: >-
+ Processors are used to reduce the number of fields in the exported event or to enhance the event with metadata. This executes in the agent before the logs are parsed. See [Processors](https://www.elastic.co/guide/en/beats/filebeat/current/filtering-and-enhancing-data.html) for details.
diff --git a/packages/sublime_security/data_stream/audit/sample_event.json b/packages/sublime_security/data_stream/audit/sample_event.json
new file mode 100644
index 00000000000..a45b1a79bd2
--- /dev/null
+++ b/packages/sublime_security/data_stream/audit/sample_event.json
@@ -0,0 +1,121 @@
+{
+ "@timestamp": "2024-08-12T06:04:03.714Z",
+ "agent": {
+ "ephemeral_id": "390c3f2d-c9eb-4229-9992-0f4fc2436f51",
+ "id": "5f3fcbb9-1a97-4ff3-857f-167af6664464",
+ "name": "docker-fleet-agent",
+ "type": "filebeat",
+ "version": "8.13.0"
+ },
+ "data_stream": {
+ "dataset": "sublime_security.audit",
+ "namespace": "99243",
+ "type": "logs"
+ },
+ "ecs": {
+ "version": "8.11.0"
+ },
+ "elastic_agent": {
+ "id": "5f3fcbb9-1a97-4ff3-857f-167af6664464",
+ "snapshot": false,
+ "version": "8.13.0"
+ },
+ "event": {
+ "action": "search",
+ "agent_id_status": "verified",
+ "dataset": "sublime_security.audit",
+ "id": "bd49af79-0cfb-4184-bd18-b0401d69ac61",
+ "ingested": "2024-08-28T10:35:52Z",
+ "kind": "event",
+ "original": "{\"created_at\":\"2024-08-12T06:04:03.714126Z\",\"created_by\":{\"active\":true,\"created_at\":\"2024-07-12T05:13:47.879426Z\",\"email_address\":\"demo@example.com\",\"first_name\":\"Demo\",\"google_oauth_user_id\":\"d83rb8et4-refe-fe7t4f8efe\",\"id\":\"6e6eca05-4fea-406b-86d4-b40177e25474\",\"is_enrolled\":true,\"last_name\":\"User\",\"microsoft_oauth_user_id\":\"fhe7t4bgf8-freu-ebfur94ref\",\"phone_number\":null,\"role\":\"admin\",\"updated_at\":\"2024-07-12T05:13:47.879426Z\"},\"data\":{\"request\":{\"api_key_name\":\"demo mode local\",\"authentication_method\":\"api_key\",\"body\":\"\",\"id\":\"6ad202de-0def-423d-a0f2-549402e1a9c9\",\"ip\":\"1.128.0.0\",\"method\":\"GET\",\"path\":\"/v0/message-groups\",\"user_agent\":\"Go-http-client/1.1\"}},\"id\":\"bd49af79-0cfb-4184-bd18-b0401d69ac61\",\"type\":\"message_group.search\"}",
+ "type": [
+ "info"
+ ]
+ },
+ "http": {
+ "request": {
+ "id": "6ad202de-0def-423d-a0f2-549402e1a9c9",
+ "method": "GET"
+ }
+ },
+ "input": {
+ "type": "cel"
+ },
+ "observer": {
+ "product": "Sublime Security",
+ "vendor": "Sublime Security"
+ },
+ "related": {
+ "ip": [
+ "1.128.0.0"
+ ],
+ "user": [
+ "demo@example.com",
+ "Demo",
+ "d83rb8et4-refe-fe7t4f8efe",
+ "6e6eca05-4fea-406b-86d4-b40177e25474",
+ "fhe7t4bgf8-freu-ebfur94ref"
+ ]
+ },
+ "source": {
+ "ip": "1.128.0.0"
+ },
+ "sublime_security": {
+ "audit": {
+ "created_at": "2024-08-12T06:04:03.714Z",
+ "created_by": {
+ "active": true,
+ "created_at": "2024-07-12T05:13:47.879Z",
+ "email_address": "demo@example.com",
+ "first_name": "Demo",
+ "google_oauth_user_id": "d83rb8et4-refe-fe7t4f8efe",
+ "id": "6e6eca05-4fea-406b-86d4-b40177e25474",
+ "is_enrolled": true,
+ "last_name": "User",
+ "microsoft_oauth_user_id": "fhe7t4bgf8-freu-ebfur94ref",
+ "role": "admin",
+ "updated_at": "2024-07-12T05:13:47.879Z"
+ },
+ "data": {
+ "request": {
+ "api_key_name": "demo mode local",
+ "authentication_method": "api_key",
+ "id": "6ad202de-0def-423d-a0f2-549402e1a9c9",
+ "ip": "1.128.0.0",
+ "method": "GET",
+ "path": "/v0/message-groups",
+ "user_agent": "Go-http-client/1.1"
+ }
+ },
+ "id": "bd49af79-0cfb-4184-bd18-b0401d69ac61",
+ "type": "message_group.search"
+ }
+ },
+ "tags": [
+ "preserve_original_event",
+ "preserve_duplicate_custom_fields",
+ "forwarded",
+ "sublime_security-audit"
+ ],
+ "url": {
+ "path": "/v0/message-groups"
+ },
+ "user": {
+ "domain": "example.com",
+ "email": "demo@example.com",
+ "full_name": "Demo User",
+ "id": "6e6eca05-4fea-406b-86d4-b40177e25474",
+ "name": "demo",
+ "roles": [
+ "admin"
+ ]
+ },
+ "user_agent": {
+ "device": {
+ "name": "Other"
+ },
+ "name": "Go-http-client",
+ "original": "Go-http-client/1.1",
+ "version": "1.1"
+ }
+}
\ No newline at end of file
diff --git a/packages/sublime_security/data_stream/email_message/_dev/deploy/tf/env.yml b/packages/sublime_security/data_stream/email_message/_dev/deploy/tf/env.yml
new file mode 100644
index 00000000000..aee5f1c5900
--- /dev/null
+++ b/packages/sublime_security/data_stream/email_message/_dev/deploy/tf/env.yml
@@ -0,0 +1,9 @@
+version: '2.3'
+services:
+ terraform:
+ environment:
+ - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
+ - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
+ - AWS_SESSION_TOKEN=${AWS_SESSION_TOKEN}
+ - AWS_DEFAULT_PROFILE=${AWS_DEFAULT_PROFILE}
+ - AWS_REGION=${AWS_REGION:-us-east-1}
diff --git a/packages/sublime_security/data_stream/email_message/_dev/deploy/tf/files/test-email-message.log b/packages/sublime_security/data_stream/email_message/_dev/deploy/tf/files/test-email-message.log
new file mode 100644
index 00000000000..4019e8bf48a
--- /dev/null
+++ b/packages/sublime_security/data_stream/email_message/_dev/deploy/tf/files/test-email-message.log
@@ -0,0 +1 @@
+{"body":{"plain":{"raw":"Sublime Security test message.\n","charset":"utf-8","content_transfer_encoding":"base64"},"current_thread":{"text":"Sublime Security test message."},"html":{"charset":"utf-8","content_transfer_encoding":"base64","display_text":"Sublime Security test message.","raw":"
Sublime Security test message.
","inner_text":"Sublime Security test message.
"},"ips":[{"ip":"1.128.0.0"}],"links":[{"display_text":"Click here!","mismatched":true,"display_url":{"fragment":"search","password":"pass123","path":"/test","port":80,"query_params":"q=elasticsearch","rewrite":{"encoders":["base64"],"original":"demo"},"scheme":"https","url":"https://example.com/test?q=elasticsearch#search","username":"test","domain":{"domain":"example.com","punycode":"demo","root_domain":"example.com","subdomain":"example","tld":"com","valid":true,"sld":"example"}}},{"href_url":{"fragment":"search","password":"pass123","path":"/test","port":80,"query_params":"q=elasticsearch","rewrite":{"encoders":["base64"],"original":"demo"},"scheme":"https","url":"https://example.com/test?q=elasticsearch#search","username":"test","domain":{"domain":"example.com","punycode":"demo","root_domain":"example.com","subdomain":"example","tld":"com","valid":true,"sld":"example"}}}]},"external":{"created_at":"2024-08-02T07:40:25.135939305Z","message_id":"2fe271830bbad5fe3a70abbe7a8c0bfe7refe3ffe","route_type":"sent","spam":false,"spam_folder":true,"thread_id":"sample_data"},"attachments":[{"content_id":"abc123","content_transfer_encoding":"base64","content_type":"application/pdf","file_extension":".pdf","file_name":"sample_document.pdf","file_type":"document","md5":"1a2b3c","raw":"JVBERi0xLjMKJcfs4AAQSkZjRgABAQE","sha1":"4d5e6f","sha256":"7g8h9i","size":102400},{"content_id":"xyz456","content_transfer_encoding":"7bit","content_type":"image/jpeg","file_extension":".jpg","file_name":"image_photo.jpg","file_type":"image","md5":"7h8i9j","raw":"/9j/4AAQSkZJRgABAQEJVBERi0xLjMKJd","sha1":"1k2l3m","sha256":"4n5o6p","size":204800},{"content_id":"efg789","content_transfer_encoding":"quoted-printable","content_type":"text/plain","file_extension":".txt","file_name":"notes.txt","file_type":"text","md5":"1x2y3z","raw":"SGVsbG8gdVsbG8gd29yb29ybGQhVsbG8gd29yb","sha1":"4a5b6c","sha256":"7d8e9f","size":5120}],"headers":{"x_authenticated_domain":{"domain":"example.com","punycode":"xn--example-d4a.com","root_domain":"example.com","sld":"example","subdomain":"sub","tld":"com","valid":true},"x_authenticated_sender":{"domain":{"domain":"example.com","punycode":"example.com","root_domain":"example.com","sld":"example","subdomain":"sub","tld":"com","valid":true},"email":"user@example.com","local_part":"user"},"x_client_ip":{"ip":"1.128.0.0"},"x_originating_ip":{"ip":"1.128.0.0"},"x_secure_server_account":"account_value","x_sender":{"domain":{"domain":"example.com","punycode":"example.com","root_domain":"example.com","sld":"example","subdomain":"sub","tld":"com","valid":true},"email":"user@example.com","local_part":"user"},"return_path":{"domain":{"domain":"example.com","punycode":"xn--example-d4a.com","root_domain":"example","sld":"example","subdomain":"sub","tld":"com","valid":true},"email":"user@example.com","local_part":"user"},"references":["test1","test2"],"auth_summary":{"dmarc":{"details":{"action":"quarantine","disposition":"quarantine","from":{"domain":"example.com","punycode":"example.com","root_domain":"example.com","sld":"example","subdomain":"example","tld":"com","valid":true},"policy":"reject","sub_policy":"none","verdict":"pass","version":"1.0"},"pass":true,"received_hop":1},"spf":{"details":{"client_ip":{"ip":"1.128.0.0"},"description":"SPF record found","designator":"pass","helo":{"domain":"example.com","punycode":"example.com","root_domain":"example.com","sld":"example","subdomain":"example","tld":"com","valid":true},"server":{"domain":"mail.example.com","punycode":"mail.example.com","root_domain":"example.com","sld":"example","subdomain":"mail","tld":"com","valid":true},"verdict":"pass"},"error":"true","pass":true,"received_hop":2}},"date":"2019-10-21T18:23:24Z","date_original_offset":"-4","hops":[{"index":0,"fields":[{"name":"To","value":"user@example.com","position":0},{"name":"Subject","value":"Sublime-Security-Standard-Test-String","position":1},{"name":"Date","value":"Mon, 21 Oct 2019 14:23:24 -0400","position":2},{"name":"From","value":"Sublime Security Test ","position":3}],"authentication_results":{"compauth":{"verdict":"pass","reason":"reason_value"},"dkim":"pass","dkim_details":{"algorithm":"rsa-sha256","body_hash":"abcdefg","domain":"example.com","headers":"from, to, subject","instance":"example.com","selector":"abcdefg","signature":"abcdefg","type":"dkim","version":"1.0"},"dmarc":"pass","dmarc_details":{"action":"quarantine","disposition":"quarantine","from":{"domain":"example.com","punycode":"example.com","root_domain":"example.com","sld":"example","subdomain":"example","tld":"com","valid":true},"policy":"reject","sub_policy":"none","verdict":"pass","version":"1.0"},"instance":"example.com","server":{"domain":"mail.example.com","punycode":"mail.example.com","root_domain":"example.com","sld":"example","subdomain":"mail","tld":"com","valid":true},"spf":"pass","spf_details":{"client_ip":{"ip":"1.128.0.0"},"description":"SPF record found","designator":"pass","helo":{"domain":"example.com","punycode":"example.com","root_domain":"example.com","sld":"example","subdomain":"example","tld":"com","valid":true},"server":{"domain":"mail.example.com","root_domain":"example.com","sld":"example","subdomain":"mail","tld":"com","valid":true},"verdict":"pass"},"type":"spf"},"received":{"additional":{"raw":"Authentication successful"},"id":{"raw":"msg-12345"},"link":{"raw":"https://mail.example.com/message/12345"},"mailbox":{"raw":"user@example.com"},"protocol":{"raw":"IMAP"},"server":{"raw":"imap.example.com"},"source":{"raw":"81.2.69.144"},"time":"2019-10-21T18:23:24Z","zone_offset":"+00:00"},"received_spf":{"client_ip":{"ip":"1.128.0.0"},"description":"SPF record found","designator":"pass","helo":{"domain":"example.com","punycode":"example.com","root_domain":"example.com","sld":"example","subdomain":"example","tld":"com","valid":true},"server":{"domain":"mail.example.com","punycode":"mail.example.com","root_domain":"example.com","sld":"example","subdomain":"mail","tld":"com","valid":true},"verdict":"pass"},"signature":{"algorithm":"rsa-sha256","body_hash":"b9c4a3f9d93d9a38bdf8c47a8f2d2c79ec1d8b1f","domain":"example.com","headers":"from:to:subject:date","instance":"123456","selector":"default","signature":"d2abf9d6c8f4b8d68d8f3f7b6f9d3b8e6a8c2b3a9f4b8d7b9d3b6a8f9c3b4e5f","type":"spf","version":"1"}}],"in_reply_to":"in_reply_to_value","delivered_to":{"domain":{"domain":"example.com","subdomain":"example","tld":"com","email":"testing@sublimesecurity.com","punycode":"example.com","root_domain":"example.com","sld":"example","valid":true},"email":"testing@sublimesecurity.com","local_part":"testing"},"ips":[{"ip":"1.128.0.0"}],"mailer":"MyCustomMailer","message_id":"2fe271830bbad5fe3a70abbe7a8c0bfe7refe3ffe","domains":[{"domain":"test.com","subdomain":"test","tld":"com","punycode":"test.com","root_domain":"test.com","sld":"test","valid":true},{"domain":"example.com","subdomain":"example","tld":"com","punycode":"example.com","root_domain":"example.com","sld":"example","valid":true}],"reply_to":[{"email":{"email":"user@example.com","local_part":"user","domain":{"domain":"example.com","root_domain":"example.com","sld":"example","tld":"com","valid":true}}},{"display_name":"Example Display Name","email":{"domain":{"punycode":"example.com","subdomain":"sub.example"}}},{"display_name":"Another Display Name","email":{"domain":{"punycode":"anotherexample.com","subdomain":"sub.anotherexample"}}}]},"type":{"outbound":true},"mailbox":{"email":{"email":"user@example.com","local_part":"user","domain":{"domain":"example.com","root_domain":"example.com","sld":"example","tld":"com","valid":true,"punycode":"xn--example-d4a.com","subdomain":"sub"}}},"recipients":{"to":[{"display_name":"Alice Johnson","email":{"email":"user@example.com","local_part":"user","domain":{"domain":"example.com","root_domain":"example.com","sld":"example","tld":"com","valid":true,"punycode":"xn--example-d4a.net","subdomain":"sub"}}}],"bcc":[{"display_name":"John Doe","email":{"domain":{"domain":"example.com","punycode":"xn--example-d4a.com","root_domain":"example","sld":"example","subdomain":"sub","tld":"com","valid":true},"email":"john.doe@example.com","local_part":"john.doe"}}],"cc":[{"display_name":"Jane Smith","email":{"domain":{"domain":"example.org","punycode":"xn--example-d4a.org","root_domain":"example","sld":"example","subdomain":"sub","tld":"org","valid":true},"email":"jane.smith@example.org","local_part":"jane.smith"}}]},"sender":{"display_name":"Sublime Security Test","email":{"email":"testing@sublimesecurity.com","local_part":"testing","domain":{"domain":"sublimesecurity.com","root_domain":"sublimesecurity.com","sld":"sublimesecurity","tld":"com","valid":true,"punycode":"xn--example-d4a.com","subdomain":"sub"}}},"subject":{"subject":"Sublime-Security-Standard-Test-String"},"_meta":{"id":"01911208-633c-7f03-b303-e594d92cf818","canonical_id":"2fe271830bbad5fe3a70abbe7a8c0bfe79eb208a76cde267930d19f0e8cea81c","created_at":"2024-08-02T07:40:25.135939305Z","effective_at":"2024-08-02T07:40:25.135939305Z"},"_errors":[{"field":"Mime-Version","message":"No Mime-Version defined in headers","type":"missing_header_field"}]}
diff --git a/packages/sublime_security/data_stream/email_message/_dev/deploy/tf/main.tf b/packages/sublime_security/data_stream/email_message/_dev/deploy/tf/main.tf
new file mode 100644
index 00000000000..bf824481a06
--- /dev/null
+++ b/packages/sublime_security/data_stream/email_message/_dev/deploy/tf/main.tf
@@ -0,0 +1,57 @@
+provider "aws" {
+ region = "us-east-1"
+ default_tags {
+ tags = {
+ environment = var.ENVIRONMENT
+ repo = var.REPO
+ branch = var.BRANCH
+ build = var.BUILD_ID
+ created_date = var.CREATED_DATE
+ }
+ }
+}
+
+resource "aws_s3_bucket" "bucket" {
+ bucket = "elastic-package-sublime-security-bucket-${var.TEST_RUN_ID}"
+}
+
+resource "aws_sqs_queue" "queue" {
+ name = "elastic-package-sublime-security-queue-${var.TEST_RUN_ID}"
+ policy = <Sublime Security test message.","inner_text":"Sublime Security test message.
"},"ips":[{"ip":"1.128.0.0"}],"links":[{"display_text":"click here!","display_url":{"domain":{"domain":"example.com","punycode":"test","root_domain":"example.com","subdomain":"example","tld":"com","valid":true},"scheme":"https","fragment":"top","password":"pass123","path":"/search","port":80,"query_params":"q=elasticsearch","rewrite":{"encoders":["base64"],"original":"test"},"url":"https://example.com/search?q=elasticsearch#top","username":"user12"},"mismatched":true},{"href_url":{"domain":{"domain":"example.com","punycode":"test","root_domain":"example.com","subdomain":"example","tld":"com","valid":true},"scheme":"https","fragment":"top","password":"pass123","path":"/search","port":80,"query_params":"q=elasticsearch","rewrite":{"encoders":["base64"],"original":"test"},"url":"https://example.com/search?q=elasticsearch#top","username":"user12"}}]},"external":{"created_at":"2024-08-02T07:40:25.135939305Z","message_id":"2fe271830bbad5fe3a70abbe7a8c0bfe7refe3ffe","route_type":"sent","spam":false,"spam_folder":true},"attachments":[{"content_id":"abc123","content_transfer_encoding":"base64","content_type":"application/pdf","file_extension":".pdf","file_name":"sample_document.pdf","file_type":"document","md5":"1a2b3c","raw":"JVBERi0xLjMKJcfs4AAQSkZjRgABAQE","sha1":"4d5e6f","sha256":"7g8h9i","size":102400},{"content_id":"xyz456","content_transfer_encoding":"7bit","content_type":"image/jpeg","file_extension":".jpg","file_name":"image_photo.jpg","file_type":"image","md5":"7h8i9j","raw":"/9j/4AAQSkZJRgABAQEJVBERi0xLjMKJd","sha1":"1k2l3m","sha256":"4n5o6p","size":204800},{"content_id":"efg789","content_transfer_encoding":"quoted-printable","content_type":"text/plain","file_extension":".txt","file_name":"notes.txt","file_type":"text","md5":"1x2y3z","raw":"SGVsbG8gdVsbG8gd29yb29ybGQhVsbG8gd29yb","sha1":"4a5b6c","sha256":"7d8e9f","size":5120}],"headers":{"date":"2019-10-21T18:23:24Z","date_original_offset":"-4","hops":[{"index":0,"fields":[{"name":"To","value":"user@example.com","position":0},{"name":"Subject","value":"Sublime-Security-Standard-Test-String","position":1},{"name":"Date","value":"Mon, 21 Oct 2019 14:23:24 -0400","position":2},{"name":"From","value":"Sublime Security Test ","position":3}]}],"delivered_to":{"domain":{"domain":"example.com","subdomain":"example","tld":"com","email":"testing@sublimesecurity.com"}},"ips":[{"ip":"1.128.0.0"}],"mailer":"MyCustomMailer","message_id":"2fe271830bbad5fe3a70abbe7a8c0bfe7refe3ffe","domains":[{"domain":"test.com","subdomain":"test","tld":"com"},{"domain":"example.com","subdomain":"example","tld":"com"}],"reply_to":[{"email":{"email":"user@example.com","local_part":"user","domain":{"domain":"example.com","root_domain":"example.com","sld":"example","tld":"com","valid":true}}}]},"type":{"outbound":true},"mailbox":{"email":{"email":"user@example.com","local_part":"user","domain":{"domain":"example.com","root_domain":"example.com","sld":"example","tld":"com","valid":true}}},"recipients":{"to":[{"email":{"email":"user@example.com","local_part":"user","domain":{"domain":"example.com","root_domain":"example.com","sld":"example","tld":"com","valid":true}}}]},"sender":{"display_name":"Sublime Security Test","email":{"email":"testing@sublimesecurity.com","local_part":"testing","domain":{"domain":"sublimesecurity.com","root_domain":"sublimesecurity.com","sld":"sublimesecurity","tld":"com","valid":true}}},"subject":{"subject":"Sublime-Security-Standard-Test-String"},"_meta":{"id":"01911208-633c-7f03-b303-e594d92cf818","canonical_id":"2fe271830bbad5fe3a70abbe7a8c0bfe79eb208a76cde267930d19f0e8cea81c","created_at":"2024-08-02T07:40:25.135939305Z","effective_at":"2024-08-02T07:40:25.135939305Z"},"_errors":[{"field":"Mime-Version","message":"No Mime-Version defined in headers","type":"missing_header_field"}]}
+{"body":{"plain":{"raw":"Sublime standard test message.\n"},"current_thread":{"text":"Sublime standard test message."}},"headers":{"date":"2019-10-21T18:23:24Z","date_original_offset":"-4","hops":[{"index":0,"fields":[{"name":"To","value":"user@example.com","position":0},{"name":"Subject","value":"Sublime-Standard-Test-String","position":1},{"name":"Date","value":"Mon, 21 Oct 2019 14:23:24 -0400","position":2},{"name":"From","value":"Sublime Test \u003ctesting@sublimesecurity.com\u003e","position":3}]}]},"type":{"inbound":true},"mailbox":{"email":{"email":"user@example.com","local_part":"user","domain":{"domain":"example.com","root_domain":"example.com","sld":"example","tld":"com","valid":true}}},"recipients":{"to":[{"email":{"email":"user@example.com","local_part":"user","domain":{"domain":"example.com","root_domain":"example.com","sld":"example","tld":"com","valid":true}}}]},"sender":{"display_name":"Sublime Test","email":{"email":"testing@sublimesecurity.com","local_part":"testing","domain":{"domain":"sublimesecurity.com","root_domain":"sublimesecurity.com","sld":"sublimesecurity","tld":"com","valid":true}}},"subject":{"subject":"Sublime-Standard-Test-String"},"_meta":{"id":"01912124-e085-7abc-aa36-5747852f7b42","canonical_id":"2fe271830bbad5fe3a70abbe7a8c0bfe79eb208a76cde267930d19f0e8cea81c","created_at":"2024-08-05T06:05:50.479598876Z","effective_at":"2024-08-05T06:05:50.479598876Z"},"_errors":[{"field":"Mime-Version","message":"No Mime-Version defined in headers","type":"missing_header_field"}]}
+{"body":{"html":{"raw":"\r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n \r\n | \r\n","charset":"utf-8","content_transfer_encoding":"quoted-printable","inner_text":"---------- Forwarded message ---------\nFrom:\nxyz Instructor: Alice \n<\nno-reply@e.example.com\n>\nDate: Wed, 22 Nov, 2023, 3:07 pm\nSubject: How to Achieve Your Career Goals in 2024\nTo: <\nalice123@test.com\n>\nNew Educational Announcement\nHi Alice, an announcement has been made from Alice, instructor of\nLinux Administration: The Complete Linux Bootcamp for 2023\n.\n","display_text":"---------- Forwarded message ---------\nFrom: xyz Instructor: \nDate: Wed, 22 Nov, 2023, 3:07pm\nSubject: How to Achieve Your Career Goals in 2024\nTo: \nNew Educational Announcement\nHi Alice, an announcement has been made from Alice, instructor of Linux Administration: The Complete Linux Bootcamp for 2023."},"plain":{"raw":"---------- Forwarded message ---------\r\nFrom: xyz Instructor: Alice \r\nDate: Wed, 22 Nov, 2023, 3:07 pm\r\nSubject: How to Achieve Your Career Goals in 2024\r\nTo: \r\n\r\n\r\n\r\n\r\n* New Educational Announcement *\r\n\r\n","charset":"utf-8","content_transfer_encoding":"quoted-printable"},"links":[{"display_text":"Linux Administration: The Complete Linux Bootcamp for 2023","href_url":{"url":"https://e2.example.com/ls/click?upn=6n","domain":{"domain":"e2.example.com","root_domain":"example.com","sld":"example","subdomain":"e2","tld":"com","valid":true},"path":"/ls/click","query_params":"upn=Z","scheme":"https"}},{"display_text":"How I Went From Zero Job Offers To Working At xyz In 3 Years","href_url":{"url":"https://e2.example.com/ls/click?upn=6n","domain":{"domain":"e2.example.com","root_domain":"example.com","sld":"example","subdomain":"e2","tld":"com","valid":true},"path":"/ls/click","query_params":"upn=6n","scheme":"https"}},{"display_text":"How to beat Imposter Syndrome!","href_url":{"url":"https://e2.example.com/ls/click?upn=6nwDRRN3APL2A","domain":{"domain":"e2.example.com","root_domain":"example.com","sld":"example","subdomain":"e2","tld":"com","valid":true},"path":"/ls/click","query_params":"upn=6nwDRRN3APL2A","scheme":"https"}},{"display_text":"full state of AI for programmers","href_url":{"url":"https://e2.example.com/ls/click?upn=6nwDR","domain":{"domain":"e2.example.com","root_domain":"example.com","sld":"example","subdomain":"e2","tld":"com","valid":true},"path":"/ls/click","query_params":"upn=6nwDR","scheme":"https"}},{"display_text":"See Announcement","href_url":{"url":"https://e2.example.com/ls/click?upn=ZF3sOyS2SxEPIoSZT6Aoc","domain":{"domain":"e2.example.com","root_domain":"example.com","sld":"example","subdomain":"e2","tld":"com","valid":true},"path":"/ls/click","query_params":"upn=ZF3sOyS2SxEPIoSZT6Aoc","scheme":"https"}},{"display_text":"unsubscribe","href_url":{"url":"https://e2.example.com/ls/click?upn=ZF3sOyS2S","domain":{"domain":"e2.example.com","root_domain":"example.com","sld":"example","subdomain":"e2","tld":"com","valid":true},"path":"/ls/click","query_params":"upn=ZF3sOyS2S","scheme":"https"}},{"display_text":"report abuse","href_url":{"url":"https://e2.example.com/ls/click?upn=ZF3s","domain":{"domain":"e2.example.com","root_domain":"example.com","sld":"example","subdomain":"e2","tld":"com","valid":true},"path":"/ls/click","query_params":"upn=ZF3s","scheme":"https"}},{"display_url":{"url":"e.example.com","domain":{"domain":"e.example.com","root_domain":"example.com","sld":"example","subdomain":"e","tld":"com","valid":true},"scheme":"http"},"href_url":{"url":"e.example.com","domain":{"domain":"e.example.com","root_domain":"example.com","sld":"example","subdomain":"e","tld":"com","valid":true},"scheme":"http"}},{"display_url":{"url":"test.com","domain":{"domain":"test.com","root_domain":"test.com","sld":"test","tld":"com","valid":true},"scheme":"http"},"href_url":{"url":"test.com","domain":{"domain":"test.com","root_domain":"test.com","sld":"test","tld":"com","valid":true},"scheme":"http"}}],"current_thread":{"text":""}},"external":{"created_at":"2024-08-08T06:39:47Z","message_id":"11","route_type":"received","spam":false},"headers":{"auth_summary":{"dmarc":{"pass":true,"received_hop":0,"details":{"version":null,"verdict":"pass","action":null,"policy":"NONE","sub_policy":"QUARANTINE","disposition":"NONE","from":{"domain":"test.com","root_domain":"test.com","sld":"test","tld":"com","valid":true}}},"spf":{"pass":true,"error":false,"received_hop":0,"details":{"verdict":"pass","server":{"domain":"test.com","root_domain":"test.com","sld":"test","tld":"com","valid":true},"client_ip":{"ip":"81.2.69.192"},"designator":"domain of alice123@test.com","description":"test.com: domain of alice123@test.com designates 81.2.69.192 as permitted sender"}}},"date":"2024-08-08T06:39:33Z","date_original_offset":"5","delivered_to":{"email":"john123@test.com","local_part":"john123","domain":{"domain":"test.com","root_domain":"test.com","sld":"test","tld":"com","valid":true}},"domains":[{"domain":"mail-sor-f41.test.com","root_domain":"test.com","sld":"test","subdomain":"mail-sor-f41","tld":"com","valid":true},{"domain":"mx.test.com","root_domain":"test.com","sld":"test","subdomain":"mx","tld":"com","valid":true},{"domain":"test.com","root_domain":"test.com","sld":"test","tld":"com","valid":true}],"hops":[{"index":0,"authentication_results":{"compauth": { "verdict": "pass", "reason": "reason_value" },"type":"standard","dkim":"pass","dkim_details":[{"type":"dkim","instance":"@test.com","selector":"20230601","signature":"elrBA+fb"}],"dmarc":"pass","dmarc_details":{"version":null,"verdict":"pass","action":null,"policy":"NONE","sub_policy":"QUARANTINE","disposition":"NONE","from":{"domain":"test.com","root_domain":"test.com","sld":"test","tld":"com","valid":true}},"spf":"pass","spf_details":{"verdict":"pass","server":{"domain":"test.com","root_domain":"test.com","sld":"test","tld":"com","valid":true},"client_ip":{"ip":"81.2.69.192"},"designator":"alice123@test.com","description":"test.com: domain of alice123@test.com designates 81.2.69.192 as permitted sender"},"server":{"domain":"mx.test.com","root_domain":"test.com","sld":"test","subdomain":"mx","tld":"com","valid":true}},"signature":{"type":"dkim","version":"1","algorithm":"rsa-sha256","selector":"20230601","signature":"elrBA+fbKpLqfjEOj7s4cAR9f8s8Tz0lHFsCjgE4t5dSXKpL6YZRZ44EPNZ1I1ROJx jTmQ/zz41IUs7K4tWqtuJnM98GSCsEvc31Lr3w99k/kjWm0Raei5dWc/4OqxZKmEiV3J r4Un6IlHY5CiUO","body_hash":"taAa59+CAu/Cmad8+7VJw9KpMlCezg5RHDG7X7f91P4=","domain":"test.com","headers":"to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to"},"received_spf":{"verdict":"pass","server":{"domain":"test.com","root_domain":"test.com","sld":"test","tld":"com","valid":true},"client_ip":{"ip":"81.2.69.192"},"designator":"domain of alice123@test.com","description":"test.com: domain of alice123@test.com designates 81.2.69.192 as permitted sender"},"fields":[{"name":"Content-Type","value":"multipart/alternative; boundary=\"000000000000e2ee4a061f264a8a\"","position":0},{"name":"To","value":"john123@test.com","position":1},{"name":"Subject","value":"Fwd: How to Achieve Your Career Goals in 2024","position":2},{"name":"Message-ID","value":"","position":3},{"name":"Date","value":"Thu, 8 Aug 2024 12:09:33 +0530","position":4},{"name":"From","value":"Alice ","position":5},{"name":"In-Reply-To","value":"","position":6},{"name":"References","value":"","position":7},{"name":"MIME-Version","value":"1.0","position":8},{"name":"X-Received","value":"by 2002:a05:6512:12cc:b0:52b:faa1:7c74 with SMTP id 2adb3069b0e04-530e5d21173mr181491e87.5.1723099185866; Wed, 07 Aug 2024 23:39:45 -0700 (PDT)","position":9},{"name":"X-Test-Smtp-Source","value":"AGHT+IEOPD6/KQ1QGxfpqSsNfRVL3tyvz5l2ZkiY/swtxVoJf6PjrsQMELt982FDdWiYdCh6nHFEnpPzh50Rx+gpG+8=","position":10},{"name":"X-Gm-Message-State","value":"AOJu0YyLnr/Zjgr7uXbT4OWJKXOdcruE0DB5eYAxH2GMsUDqfM81HEem KMt/4qXMzEYtzJJ+2fkjA2zpg2e3zN9iqNuiUI86WAOTl07NfeqPMJCIDDz0Q0gfeiOwIK8rlL8 jammp+/G9xCHMayr+inDiqemweFRyvA==","position":11},{"name":"X-Test-DKIM-Signature","value":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723099186; x=1723703986; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=taAa59+CAu/Cmad8+7VJw9KpMlCezg5RHDG7X7f91P4=; b=VcRvW5nfz7WbzaIuyv5g5x/Z2U0qbrDR6qP","position":12},{"name":"DKIM-Signature","value":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=test.com; s=20230601; t=1723099186; x=1723703986; dara=test.com; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to; bh=taAa59+CAu/Cmad8+7VJw9KpMlCezg5RHDG7X7f91P4=","position":13},{"name":"Authentication-Results","value":"mx.test.com; dkim=pass header.i=@test.com header.s=20230601 header.b=elrBA+fb; spf=pass (test.com: domain of alice123@test.com designates 81.2.69.192 as permitted sender) smtp.mailfrom=alice123@test.com; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=test.com; dara=pass header.i=@test.com","position":14},{"name":"Received-SPF","value":"pass (test.com: domain of alice123@test.com designates 81.2.69.192 as permitted sender) client-ip=81.2.69.192;","position":15},{"name":"Received","value":"from mail-sor-f41.test.com (mail-sor-f41.test.com. [81.2.69.192]) by mx.test.com with SMTPS id 2adb3069b0e04-530de79d133sor508979e87.12.2024.08.07.23.39.46 for (Test Transport Security); Wed, 07 Aug 2024 23:39:47 -0700 (PDT)","position":16}],"received":{"source":{"raw":"mail-sor-f41.test.com (mail-sor-f41.test.com. [81.2.69.192])"},"server":{"raw":"mx.test.com"},"mailbox":{"raw":""},"protocol":{"raw":"SMTPS"},"id":{"raw":"2adb3069b1e04-530de79d133sor508979e87.12.2024.08.07.23.39.46"},"additional":{"raw":"(Test Transport Security)"},"time":"2024-08-08T06:39:47Z","zone_offset":"-7"}},{"index":1,"authentication_results":{"type":"arc","instance":"1","dkim":"pass","dkim_details":[{"type":"dkim","instance":"@test.com","selector":"20230601","signature":"elrBA+fb"}],"dmarc":"pass","dmarc_details":{"version":null,"verdict":"pass","action":null,"policy":"NONE","sub_policy":"QUARANTINE","disposition":"NONE","from":{"domain":"test.com","root_domain":"test.com","sld":"test","tld":"com","valid":true}},"spf":"pass","spf_details":{"verdict":"pass","server":{"domain":"test.com","root_domain":"test.com","sld":"test","tld":"com","valid":true},"client_ip":{"ip":"81.2.69.192"},"designator":"alice123@test.com","description":"test.com: domain of alice123@test.com designates 81.2.69.192 as permitted sender"},"server":{"domain":"mx.test.com","root_domain":"test.com","sld":"test","subdomain":"mx","tld":"com","valid":true}},"signature":{"type":"arc-message","instance":"1","algorithm":"rsa-sha256","selector":"arc-20160816","signature":"nKqpy2hvLAXWHwdm39Mg1dL6lziVFqVY7ikY9FaP1w0pDHO6t0zbiMwcwSkS/Crz+ Y38+/FHiPhk65AocA0Yzw9P96RpK60iDaHfXpEBsxJIhJt9GN7","body_hash":"taAa59+CAu/Cmad8+7VJw9KpMlCezg5RHDG7X7f91P4=","domain":"test.com","headers":"to:subject:message-id:date:from:in-reply-to:references:mime-version :dkim-signature"},"fields":[{"name":"Return-Path","value":"","position":17},{"name":"ARC-Authentication-Results","value":"i=1; mx.test.com; dkim=pass header.i=@test.com header.s=20230601 header.b=elrBA+fb; spf=pass (test.com: domain of alice123@test.com designates 81.2.69.192 as permitted sender) smtp.mailfrom=alice123@test.com; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=test.com; dara=pass header.i=@test.com","position":18},{"name":"ARC-Message-Signature","value":"i=1; a=rsa-sha256; c=relaxed/relaxed; d=test.com; s=arc-20160816; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :dkim-signature; bh=taAa59+CAu/Cmad8+7VJw9KpMlCezg5RHDG7X7f91P4=; fh=rEZ8N7lZwF+f2DJz7PZfSiLZqwmiZLvrdguxWR5M0Mw=; b=nKqpy2hvLAXWHw39Mg1dLY6lziVFqVY7ikY9FaP1","position":19},{"name":"ARC-Seal","value":"i=1; a=rsa-sha256; t=1723099187; cv=none; d=test.com; s=arc-20160816; b=s4+J1/60S5sNdJ0Fd56rNghLRYU+m7QHad7No6E0iBi+7WGCuOOd2w07CSfEx++0jx Y0lBuDGDzNrGGHVpfi3ODGvx/aoU2vg8/siNaHAnIR4ADSbV+sr67vFiIEPqYNmQyihC lhOm0gnxDVD7ozZ","position":20},{"name":"X-Received","value":"by 2002:a05:6512:1242:b0:52f:c398:8780 with SMTP id 2adb3069b0e04-530e5d70e42mr184435e87.18.1723099187103; Wed, 07 Aug 2024 23:39:47 -0700 (PDT)","position":21},{"name":"Received","value":"by 2002:a05:6850:988a:b0:5bb:ddaf:ae20 with SMTP id li10csp662340nnb; Wed, 7 Aug 2024 23:39:47 -0700 (PDT)","position":22}],"received":{"server":{"raw":"2002:a05:6850:988a:b0:5bb:ddaf:ae20"},"protocol":{"raw":"SMTP"},"id":{"raw":"li10csp662340nnb"},"time":"2024-08-08T06:39:47Z","zone_offset":"-7"}},{"index":2,"fields":[{"name":"Delivered-To","value":"john123@test.com","position":23}]}],"ips":[{"ip":"81.2.69.192"}],"message_id":"","references":["hpfhx9h8QtSRnWCE_AzviQ@geopod-ismtpd-56"],"in_reply_to":"","return_path":{"email":"alice123@test.com","local_part":"alice123","domain":{"domain":"test.com","root_domain":"test.com","sld":"test","tld":"com","valid":true}}},"type":{"inbound":true},"mailbox":{"email":{"email":"john123@test.com","local_part":"john123","domain":{"domain":"test.com","root_domain":"test.com","sld":"test","tld":"com","valid":true}}},"recipients":{"to":[{"email":{"email":"john123@test.com","local_part":"john123","domain":{"domain":"test.com","root_domain":"test.com","sld":"test","tld":"com","valid":true}}}]},"sender":{"display_name":"Alice","email":{"email":"alice123@test.com","local_part":"alice123","domain":{"domain":"test.com","root_domain":"test.com","sld":"test","tld":"com","valid":true}}},"subject":{"subject":"Fwd: How to Achieve Your Career Goals in 2024"},"_meta":{"id":"019130be-779c-7641-87c7-284e8dcb10e5","canonical_id":"dc767a9c58a14ea5560b5786c644d5cb9ef7cadb11f680231ec09e8fdfeb4d53","created_at":"2024-08-08T06:47:54.460399216Z","effective_at":"2024-08-08T06:39:47Z"}}
diff --git a/packages/sublime_security/data_stream/email_message/_dev/test/pipeline/test-email-message.log-expected.json b/packages/sublime_security/data_stream/email_message/_dev/test/pipeline/test-email-message.log-expected.json
new file mode 100644
index 00000000000..a91ef4594d7
--- /dev/null
+++ b/packages/sublime_security/data_stream/email_message/_dev/test/pipeline/test-email-message.log-expected.json
@@ -0,0 +1,1419 @@
+{
+ "expected": [
+ {
+ "@timestamp": "2024-08-02T07:40:25.135Z",
+ "destination": {
+ "domain": "example.com",
+ "subdomain": "example",
+ "top_level_domain": "com"
+ },
+ "ecs": {
+ "version": "8.11.0"
+ },
+ "email": {
+ "attachments": [
+ {
+ "file": {
+ "extension": "pdf",
+ "hash": {
+ "md5": "1a2b3c",
+ "sha1": "4d5e6f",
+ "sha256": "7g8h9i"
+ },
+ "mime_type": "application/pdf",
+ "name": "sample_document.pdf",
+ "size": 102400
+ }
+ },
+ {
+ "file": {
+ "extension": "jpg",
+ "hash": {
+ "md5": "7h8i9j",
+ "sha1": "1k2l3m",
+ "sha256": "4n5o6p"
+ },
+ "mime_type": "image/jpeg",
+ "name": "image_photo.jpg",
+ "size": 204800
+ }
+ },
+ {
+ "file": {
+ "extension": "txt",
+ "hash": {
+ "md5": "1x2y3z",
+ "sha1": "4a5b6c",
+ "sha256": "7d8e9f"
+ },
+ "mime_type": "text/plain",
+ "name": "notes.txt",
+ "size": 5120
+ }
+ }
+ ],
+ "direction": "outbound",
+ "from": {
+ "address": [
+ "testing@sublimesecurity.com"
+ ]
+ },
+ "message_id": "2fe271830bbad5fe3a70abbe7a8c0bfe7refe3ffe",
+ "origination_timestamp": "2024-08-02T07:40:25.135Z",
+ "reply_to": {
+ "address": [
+ "user@example.com"
+ ]
+ },
+ "subject": "Sublime-Security-Standard-Test-String",
+ "to": {
+ "address": [
+ "user@example.com"
+ ]
+ },
+ "x_mailer": "MyCustomMailer"
+ },
+ "event": {
+ "category": [
+ "email"
+ ],
+ "id": "01911208-633c-7f03-b303-e594d92cf818",
+ "kind": "event",
+ "original": "{\"body\":{\"plain\":{\"raw\":\"Sublime Security test message.\\n\"},\"current_thread\":{\"text\":\"Sublime Security test message.\"},\"html\":{\"charset\":\"utf-8\",\"content_transfer_encoding\":\"base64\",\"display_text\":\"Sublime Security test message.\",\"raw\":\"Sublime Security test message.
\",\"inner_text\":\"Sublime Security test message.
\"},\"ips\":[{\"ip\":\"1.128.0.0\"}],\"links\":[{\"display_text\":\"click here!\",\"display_url\":{\"domain\":{\"domain\":\"example.com\",\"punycode\":\"test\",\"root_domain\":\"example.com\",\"subdomain\":\"example\",\"tld\":\"com\",\"valid\":true},\"scheme\":\"https\",\"fragment\":\"top\",\"password\":\"pass123\",\"path\":\"/search\",\"port\":80,\"query_params\":\"q=elasticsearch\",\"rewrite\":{\"encoders\":[\"base64\"],\"original\":\"test\"},\"url\":\"https://example.com/search?q=elasticsearch#top\",\"username\":\"user12\"},\"mismatched\":true},{\"href_url\":{\"domain\":{\"domain\":\"example.com\",\"punycode\":\"test\",\"root_domain\":\"example.com\",\"subdomain\":\"example\",\"tld\":\"com\",\"valid\":true},\"scheme\":\"https\",\"fragment\":\"top\",\"password\":\"pass123\",\"path\":\"/search\",\"port\":80,\"query_params\":\"q=elasticsearch\",\"rewrite\":{\"encoders\":[\"base64\"],\"original\":\"test\"},\"url\":\"https://example.com/search?q=elasticsearch#top\",\"username\":\"user12\"}}]},\"external\":{\"created_at\":\"2024-08-02T07:40:25.135939305Z\",\"message_id\":\"2fe271830bbad5fe3a70abbe7a8c0bfe7refe3ffe\",\"route_type\":\"sent\",\"spam\":false,\"spam_folder\":true},\"attachments\":[{\"content_id\":\"abc123\",\"content_transfer_encoding\":\"base64\",\"content_type\":\"application/pdf\",\"file_extension\":\".pdf\",\"file_name\":\"sample_document.pdf\",\"file_type\":\"document\",\"md5\":\"1a2b3c\",\"raw\":\"JVBERi0xLjMKJcfs4AAQSkZjRgABAQE\",\"sha1\":\"4d5e6f\",\"sha256\":\"7g8h9i\",\"size\":102400},{\"content_id\":\"xyz456\",\"content_transfer_encoding\":\"7bit\",\"content_type\":\"image/jpeg\",\"file_extension\":\".jpg\",\"file_name\":\"image_photo.jpg\",\"file_type\":\"image\",\"md5\":\"7h8i9j\",\"raw\":\"/9j/4AAQSkZJRgABAQEJVBERi0xLjMKJd\",\"sha1\":\"1k2l3m\",\"sha256\":\"4n5o6p\",\"size\":204800},{\"content_id\":\"efg789\",\"content_transfer_encoding\":\"quoted-printable\",\"content_type\":\"text/plain\",\"file_extension\":\".txt\",\"file_name\":\"notes.txt\",\"file_type\":\"text\",\"md5\":\"1x2y3z\",\"raw\":\"SGVsbG8gdVsbG8gd29yb29ybGQhVsbG8gd29yb\",\"sha1\":\"4a5b6c\",\"sha256\":\"7d8e9f\",\"size\":5120}],\"headers\":{\"date\":\"2019-10-21T18:23:24Z\",\"date_original_offset\":\"-4\",\"hops\":[{\"index\":0,\"fields\":[{\"name\":\"To\",\"value\":\"user@example.com\",\"position\":0},{\"name\":\"Subject\",\"value\":\"Sublime-Security-Standard-Test-String\",\"position\":1},{\"name\":\"Date\",\"value\":\"Mon, 21 Oct 2019 14:23:24 -0400\",\"position\":2},{\"name\":\"From\",\"value\":\"Sublime Security Test \",\"position\":3}]}],\"delivered_to\":{\"domain\":{\"domain\":\"example.com\",\"subdomain\":\"example\",\"tld\":\"com\",\"email\":\"testing@sublimesecurity.com\"}},\"ips\":[{\"ip\":\"1.128.0.0\"}],\"mailer\":\"MyCustomMailer\",\"message_id\":\"2fe271830bbad5fe3a70abbe7a8c0bfe7refe3ffe\",\"domains\":[{\"domain\":\"test.com\",\"subdomain\":\"test\",\"tld\":\"com\"},{\"domain\":\"example.com\",\"subdomain\":\"example\",\"tld\":\"com\"}],\"reply_to\":[{\"email\":{\"email\":\"user@example.com\",\"local_part\":\"user\",\"domain\":{\"domain\":\"example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"tld\":\"com\",\"valid\":true}}}]},\"type\":{\"outbound\":true},\"mailbox\":{\"email\":{\"email\":\"user@example.com\",\"local_part\":\"user\",\"domain\":{\"domain\":\"example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"tld\":\"com\",\"valid\":true}}},\"recipients\":{\"to\":[{\"email\":{\"email\":\"user@example.com\",\"local_part\":\"user\",\"domain\":{\"domain\":\"example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"tld\":\"com\",\"valid\":true}}}]},\"sender\":{\"display_name\":\"Sublime Security Test\",\"email\":{\"email\":\"testing@sublimesecurity.com\",\"local_part\":\"testing\",\"domain\":{\"domain\":\"sublimesecurity.com\",\"root_domain\":\"sublimesecurity.com\",\"sld\":\"sublimesecurity\",\"tld\":\"com\",\"valid\":true}}},\"subject\":{\"subject\":\"Sublime-Security-Standard-Test-String\"},\"_meta\":{\"id\":\"01911208-633c-7f03-b303-e594d92cf818\",\"canonical_id\":\"2fe271830bbad5fe3a70abbe7a8c0bfe79eb208a76cde267930d19f0e8cea81c\",\"created_at\":\"2024-08-02T07:40:25.135939305Z\",\"effective_at\":\"2024-08-02T07:40:25.135939305Z\"},\"_errors\":[{\"field\":\"Mime-Version\",\"message\":\"No Mime-Version defined in headers\",\"type\":\"missing_header_field\"}]}",
+ "type": [
+ "info"
+ ]
+ },
+ "observer": {
+ "product": "Sublime Security",
+ "vendor": "Sublime Security"
+ },
+ "related": {
+ "hash": [
+ "1a2b3c",
+ "7h8i9j",
+ "1x2y3z",
+ "4d5e6f",
+ "1k2l3m",
+ "4a5b6c",
+ "7g8h9i",
+ "4n5o6p",
+ "7d8e9f"
+ ],
+ "hosts": [
+ "example.com",
+ "test.com",
+ "sublimesecurity.com"
+ ],
+ "ip": [
+ "1.128.0.0"
+ ],
+ "user": [
+ "user12",
+ "user@example.com",
+ "testing@sublimesecurity.com"
+ ]
+ },
+ "source": {
+ "domain": "sublimesecurity.com",
+ "top_level_domain": "com"
+ },
+ "sublime_security": {
+ "email_message": {
+ "attachments": [
+ {
+ "content": {
+ "id": "abc123",
+ "transfer_encoding": "base64",
+ "type": "application/pdf"
+ },
+ "file": {
+ "extension": ".pdf",
+ "name": "sample_document.pdf",
+ "type": "document"
+ },
+ "md5": "1a2b3c",
+ "raw": "JVBERi0xLjMKJcfs4AAQSkZjRgABAQE",
+ "sha1": "4d5e6f",
+ "sha256": "7g8h9i",
+ "size": 102400
+ },
+ {
+ "content": {
+ "id": "xyz456",
+ "transfer_encoding": "7bit",
+ "type": "image/jpeg"
+ },
+ "file": {
+ "extension": ".jpg",
+ "name": "image_photo.jpg",
+ "type": "image"
+ },
+ "md5": "7h8i9j",
+ "raw": "/9j/4AAQSkZJRgABAQEJVBERi0xLjMKJd",
+ "sha1": "1k2l3m",
+ "sha256": "4n5o6p",
+ "size": 204800
+ },
+ {
+ "content": {
+ "id": "efg789",
+ "transfer_encoding": "quoted-printable",
+ "type": "text/plain"
+ },
+ "file": {
+ "extension": ".txt",
+ "name": "notes.txt",
+ "type": "text"
+ },
+ "md5": "1x2y3z",
+ "raw": "SGVsbG8gdVsbG8gd29yb29ybGQhVsbG8gd29yb",
+ "sha1": "4a5b6c",
+ "sha256": "7d8e9f",
+ "size": 5120
+ }
+ ],
+ "body": {
+ "current_thread": {
+ "text": "Sublime Security test message."
+ },
+ "html": {
+ "charset": "utf-8",
+ "content_transfer_encoding": "base64",
+ "display_text": "Sublime Security test message.",
+ "inner_text": "Sublime Security test message.
",
+ "raw": "Sublime Security test message.
"
+ },
+ "ips": [
+ {
+ "ip": "1.128.0.0"
+ }
+ ],
+ "links": [
+ {
+ "display_text": "click here!",
+ "display_url": {
+ "domain": {
+ "domain": "example.com",
+ "punycode": "test",
+ "root_domain": "example.com",
+ "subdomain": "example",
+ "tld": "com",
+ "valid": true
+ },
+ "fragment": "top",
+ "password": "pass123",
+ "path": "/search",
+ "port": 80,
+ "query_params": "q=elasticsearch",
+ "rewrite": {
+ "encoders": [
+ "base64"
+ ],
+ "original": "test"
+ },
+ "scheme": "https",
+ "url": "https://example.com/search?q=elasticsearch#top",
+ "username": "user12"
+ },
+ "mismatched": true
+ },
+ {
+ "href_url": {
+ "domain": {
+ "domain": "example.com",
+ "punycode": "test",
+ "root_domain": "example.com",
+ "subdomain": "example",
+ "tld": "com",
+ "valid": true
+ },
+ "fragment": "top",
+ "password": "pass123",
+ "path": "/search",
+ "port": 80,
+ "query_params": "q=elasticsearch",
+ "rewrite": {
+ "encoders": [
+ "base64"
+ ],
+ "original": "test"
+ },
+ "scheme": "https",
+ "url": "https://example.com/search?q=elasticsearch#top",
+ "username": "user12"
+ }
+ }
+ ],
+ "plain": {
+ "raw": "Sublime Security test message.\n"
+ }
+ },
+ "errors": [
+ {
+ "field": "Mime-Version",
+ "message": "No Mime-Version defined in headers",
+ "type": "missing_header_field"
+ }
+ ],
+ "external": {
+ "created_at": "2024-08-02T07:40:25.135Z",
+ "message_id": "2fe271830bbad5fe3a70abbe7a8c0bfe7refe3ffe",
+ "route_type": "sent",
+ "spam": false,
+ "spam_folder": true
+ },
+ "headers": {
+ "date": "2019-10-21T18:23:24.000Z",
+ "date_original_offset": "-4",
+ "delivered_to": {
+ "domain": {
+ "domain": "example.com",
+ "subdomain": "example",
+ "tld": "com"
+ }
+ },
+ "domains": [
+ {
+ "domain": "test.com",
+ "subdomain": "test",
+ "tld": "com"
+ },
+ {
+ "domain": "example.com",
+ "subdomain": "example",
+ "tld": "com"
+ }
+ ],
+ "hops": [
+ {
+ "fields": [
+ {
+ "name": "To",
+ "position": 0,
+ "to": "user@example.com",
+ "value": "user@example.com"
+ },
+ {
+ "name": "Subject",
+ "position": 1,
+ "subject": "Sublime-Security-Standard-Test-String",
+ "value": "Sublime-Security-Standard-Test-String"
+ },
+ {
+ "date": "Mon, 21 Oct 2019 14:23:24 -0400",
+ "name": "Date",
+ "position": 2,
+ "value": "Mon, 21 Oct 2019 14:23:24 -0400"
+ },
+ {
+ "from": "Sublime Security Test ",
+ "name": "From",
+ "position": 3,
+ "value": "Sublime Security Test "
+ }
+ ],
+ "index": 0
+ }
+ ],
+ "ips": [
+ {
+ "ip": "1.128.0.0"
+ }
+ ],
+ "mailer": "MyCustomMailer",
+ "message_id": "2fe271830bbad5fe3a70abbe7a8c0bfe7refe3ffe",
+ "reply_to": [
+ {
+ "email": {
+ "domain": {
+ "domain": "example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "tld": "com",
+ "valid": true
+ },
+ "local_part": "user",
+ "value": "user@example.com"
+ }
+ }
+ ]
+ },
+ "mailbox": {
+ "email": {
+ "domain": {
+ "domain": "example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "tld": "com",
+ "valid": true
+ },
+ "local_part": "user",
+ "value": "user@example.com"
+ }
+ },
+ "meta": {
+ "canonical_id": "2fe271830bbad5fe3a70abbe7a8c0bfe79eb208a76cde267930d19f0e8cea81c",
+ "created_at": "2024-08-02T07:40:25.135Z",
+ "effective_at": "2024-08-02T07:40:25.135Z",
+ "id": "01911208-633c-7f03-b303-e594d92cf818"
+ },
+ "recipients": {
+ "to": [
+ {
+ "email": {
+ "domain": {
+ "domain": "example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "tld": "com",
+ "valid": true
+ },
+ "local_part": "user",
+ "value": "user@example.com"
+ }
+ }
+ ]
+ },
+ "sender": {
+ "display_name": "Sublime Security Test",
+ "email": {
+ "domain": {
+ "domain": "sublimesecurity.com",
+ "root_domain": "sublimesecurity.com",
+ "sld": "sublimesecurity",
+ "tld": "com",
+ "valid": true
+ },
+ "local_part": "testing",
+ "value": "testing@sublimesecurity.com"
+ }
+ },
+ "subject": {
+ "subject": "Sublime-Security-Standard-Test-String"
+ },
+ "type": {
+ "outbound": true
+ }
+ }
+ },
+ "tags": [
+ "preserve_duplicate_custom_fields"
+ ],
+ "url": [
+ {
+ "domain": "example.com",
+ "fragment": "top",
+ "full": "https://example.com/search?q=elasticsearch#top",
+ "password": "pass123",
+ "path": "/search",
+ "port": 80,
+ "query": "q=elasticsearch",
+ "scheme": "https",
+ "subdomain": "example",
+ "top_level_domain": "com",
+ "username": "user12"
+ }
+ ],
+ "user_agent": {
+ "device": {
+ "name": "Other"
+ },
+ "name": "Other",
+ "original": "MyCustomMailer"
+ }
+ },
+ {
+ "@timestamp": "2024-08-05T06:05:50.479Z",
+ "ecs": {
+ "version": "8.11.0"
+ },
+ "email": {
+ "direction": "inbound",
+ "from": {
+ "address": [
+ "testing@sublimesecurity.com"
+ ]
+ },
+ "subject": "Sublime-Standard-Test-String",
+ "to": {
+ "address": [
+ "user@example.com"
+ ]
+ }
+ },
+ "event": {
+ "category": [
+ "email"
+ ],
+ "id": "01912124-e085-7abc-aa36-5747852f7b42",
+ "kind": "event",
+ "original": "{\"body\":{\"plain\":{\"raw\":\"Sublime standard test message.\\n\"},\"current_thread\":{\"text\":\"Sublime standard test message.\"}},\"headers\":{\"date\":\"2019-10-21T18:23:24Z\",\"date_original_offset\":\"-4\",\"hops\":[{\"index\":0,\"fields\":[{\"name\":\"To\",\"value\":\"user@example.com\",\"position\":0},{\"name\":\"Subject\",\"value\":\"Sublime-Standard-Test-String\",\"position\":1},{\"name\":\"Date\",\"value\":\"Mon, 21 Oct 2019 14:23:24 -0400\",\"position\":2},{\"name\":\"From\",\"value\":\"Sublime Test \\u003ctesting@sublimesecurity.com\\u003e\",\"position\":3}]}]},\"type\":{\"inbound\":true},\"mailbox\":{\"email\":{\"email\":\"user@example.com\",\"local_part\":\"user\",\"domain\":{\"domain\":\"example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"tld\":\"com\",\"valid\":true}}},\"recipients\":{\"to\":[{\"email\":{\"email\":\"user@example.com\",\"local_part\":\"user\",\"domain\":{\"domain\":\"example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"tld\":\"com\",\"valid\":true}}}]},\"sender\":{\"display_name\":\"Sublime Test\",\"email\":{\"email\":\"testing@sublimesecurity.com\",\"local_part\":\"testing\",\"domain\":{\"domain\":\"sublimesecurity.com\",\"root_domain\":\"sublimesecurity.com\",\"sld\":\"sublimesecurity\",\"tld\":\"com\",\"valid\":true}}},\"subject\":{\"subject\":\"Sublime-Standard-Test-String\"},\"_meta\":{\"id\":\"01912124-e085-7abc-aa36-5747852f7b42\",\"canonical_id\":\"2fe271830bbad5fe3a70abbe7a8c0bfe79eb208a76cde267930d19f0e8cea81c\",\"created_at\":\"2024-08-05T06:05:50.479598876Z\",\"effective_at\":\"2024-08-05T06:05:50.479598876Z\"},\"_errors\":[{\"field\":\"Mime-Version\",\"message\":\"No Mime-Version defined in headers\",\"type\":\"missing_header_field\"}]}",
+ "type": [
+ "info"
+ ]
+ },
+ "observer": {
+ "product": "Sublime Security",
+ "vendor": "Sublime Security"
+ },
+ "related": {
+ "hosts": [
+ "example.com",
+ "sublimesecurity.com"
+ ],
+ "user": [
+ "user@example.com",
+ "testing@sublimesecurity.com"
+ ]
+ },
+ "source": {
+ "domain": "sublimesecurity.com",
+ "top_level_domain": "com"
+ },
+ "sublime_security": {
+ "email_message": {
+ "body": {
+ "current_thread": {
+ "text": "Sublime standard test message."
+ },
+ "plain": {
+ "raw": "Sublime standard test message.\n"
+ }
+ },
+ "errors": [
+ {
+ "field": "Mime-Version",
+ "message": "No Mime-Version defined in headers",
+ "type": "missing_header_field"
+ }
+ ],
+ "headers": {
+ "date": "2019-10-21T18:23:24.000Z",
+ "date_original_offset": "-4",
+ "hops": [
+ {
+ "fields": [
+ {
+ "name": "To",
+ "position": 0,
+ "to": "user@example.com",
+ "value": "user@example.com"
+ },
+ {
+ "name": "Subject",
+ "position": 1,
+ "subject": "Sublime-Standard-Test-String",
+ "value": "Sublime-Standard-Test-String"
+ },
+ {
+ "date": "Mon, 21 Oct 2019 14:23:24 -0400",
+ "name": "Date",
+ "position": 2,
+ "value": "Mon, 21 Oct 2019 14:23:24 -0400"
+ },
+ {
+ "from": "Sublime Test ",
+ "name": "From",
+ "position": 3,
+ "value": "Sublime Test "
+ }
+ ],
+ "index": 0
+ }
+ ]
+ },
+ "mailbox": {
+ "email": {
+ "domain": {
+ "domain": "example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "tld": "com",
+ "valid": true
+ },
+ "local_part": "user",
+ "value": "user@example.com"
+ }
+ },
+ "meta": {
+ "canonical_id": "2fe271830bbad5fe3a70abbe7a8c0bfe79eb208a76cde267930d19f0e8cea81c",
+ "created_at": "2024-08-05T06:05:50.479Z",
+ "effective_at": "2024-08-05T06:05:50.479Z",
+ "id": "01912124-e085-7abc-aa36-5747852f7b42"
+ },
+ "recipients": {
+ "to": [
+ {
+ "email": {
+ "domain": {
+ "domain": "example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "tld": "com",
+ "valid": true
+ },
+ "local_part": "user",
+ "value": "user@example.com"
+ }
+ }
+ ]
+ },
+ "sender": {
+ "display_name": "Sublime Test",
+ "email": {
+ "domain": {
+ "domain": "sublimesecurity.com",
+ "root_domain": "sublimesecurity.com",
+ "sld": "sublimesecurity",
+ "tld": "com",
+ "valid": true
+ },
+ "local_part": "testing",
+ "value": "testing@sublimesecurity.com"
+ }
+ },
+ "subject": {
+ "subject": "Sublime-Standard-Test-String"
+ },
+ "type": {
+ "inbound": true
+ }
+ }
+ },
+ "tags": [
+ "preserve_duplicate_custom_fields"
+ ]
+ },
+ {
+ "@timestamp": "2024-08-08T06:47:54.460Z",
+ "destination": {
+ "domain": "test.com",
+ "top_level_domain": "com"
+ },
+ "ecs": {
+ "version": "8.11.0"
+ },
+ "email": {
+ "direction": "inbound",
+ "from": {
+ "address": [
+ "alice123@test.com"
+ ]
+ },
+ "message_id": "",
+ "origination_timestamp": "2024-08-08T06:39:47.000Z",
+ "subject": "Fwd: How to Achieve Your Career Goals in 2024",
+ "to": {
+ "address": [
+ "john123@test.com"
+ ]
+ }
+ },
+ "event": {
+ "category": [
+ "email"
+ ],
+ "id": "019130be-779c-7641-87c7-284e8dcb10e5",
+ "kind": "event",
+ "original": "{\"body\":{\"html\":{\"raw\":\"\\r\\n\\r\\n \\r\\n \\r\\n \\r\\n\\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n
\\r\\n
\\r\\n \\r\\n | \\r\\n\",\"charset\":\"utf-8\",\"content_transfer_encoding\":\"quoted-printable\",\"inner_text\":\"---------- Forwarded message ---------\\nFrom:\\nxyz Instructor: Alice \\n<\\nno-reply@e.example.com\\n>\\nDate: Wed, 22 Nov, 2023, 3:07 pm\\nSubject: How to Achieve Your Career Goals in 2024\\nTo: <\\nalice123@test.com\\n>\\nNew Educational Announcement\\nHi Alice, an announcement has been made from Alice, instructor of\\nLinux Administration: The Complete Linux Bootcamp for 2023\\n.\\n\",\"display_text\":\"---------- Forwarded message ---------\\nFrom: xyz Instructor: \\nDate: Wed, 22 Nov, 2023, 3:07pm\\nSubject: How to Achieve Your Career Goals in 2024\\nTo: \\nNew Educational Announcement\\nHi Alice, an announcement has been made from Alice, instructor of Linux Administration: The Complete Linux Bootcamp for 2023.\"},\"plain\":{\"raw\":\"---------- Forwarded message ---------\\r\\nFrom: xyz Instructor: Alice \\r\\nDate: Wed, 22 Nov, 2023, 3:07 pm\\r\\nSubject: How to Achieve Your Career Goals in 2024\\r\\nTo: \\r\\n\\r\\n\\r\\n\\r\\n\\r\\n* New Educational Announcement *\\r\\n\\r\\n\",\"charset\":\"utf-8\",\"content_transfer_encoding\":\"quoted-printable\"},\"links\":[{\"display_text\":\"Linux Administration: The Complete Linux Bootcamp for 2023\",\"href_url\":{\"url\":\"https://e2.example.com/ls/click?upn=6n\",\"domain\":{\"domain\":\"e2.example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"e2\",\"tld\":\"com\",\"valid\":true},\"path\":\"/ls/click\",\"query_params\":\"upn=Z\",\"scheme\":\"https\"}},{\"display_text\":\"How I Went From Zero Job Offers To Working At xyz In 3 Years\",\"href_url\":{\"url\":\"https://e2.example.com/ls/click?upn=6n\",\"domain\":{\"domain\":\"e2.example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"e2\",\"tld\":\"com\",\"valid\":true},\"path\":\"/ls/click\",\"query_params\":\"upn=6n\",\"scheme\":\"https\"}},{\"display_text\":\"How to beat Imposter Syndrome!\",\"href_url\":{\"url\":\"https://e2.example.com/ls/click?upn=6nwDRRN3APL2A\",\"domain\":{\"domain\":\"e2.example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"e2\",\"tld\":\"com\",\"valid\":true},\"path\":\"/ls/click\",\"query_params\":\"upn=6nwDRRN3APL2A\",\"scheme\":\"https\"}},{\"display_text\":\"full state of AI for programmers\",\"href_url\":{\"url\":\"https://e2.example.com/ls/click?upn=6nwDR\",\"domain\":{\"domain\":\"e2.example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"e2\",\"tld\":\"com\",\"valid\":true},\"path\":\"/ls/click\",\"query_params\":\"upn=6nwDR\",\"scheme\":\"https\"}},{\"display_text\":\"See Announcement\",\"href_url\":{\"url\":\"https://e2.example.com/ls/click?upn=ZF3sOyS2SxEPIoSZT6Aoc\",\"domain\":{\"domain\":\"e2.example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"e2\",\"tld\":\"com\",\"valid\":true},\"path\":\"/ls/click\",\"query_params\":\"upn=ZF3sOyS2SxEPIoSZT6Aoc\",\"scheme\":\"https\"}},{\"display_text\":\"unsubscribe\",\"href_url\":{\"url\":\"https://e2.example.com/ls/click?upn=ZF3sOyS2S\",\"domain\":{\"domain\":\"e2.example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"e2\",\"tld\":\"com\",\"valid\":true},\"path\":\"/ls/click\",\"query_params\":\"upn=ZF3sOyS2S\",\"scheme\":\"https\"}},{\"display_text\":\"report abuse\",\"href_url\":{\"url\":\"https://e2.example.com/ls/click?upn=ZF3s\",\"domain\":{\"domain\":\"e2.example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"e2\",\"tld\":\"com\",\"valid\":true},\"path\":\"/ls/click\",\"query_params\":\"upn=ZF3s\",\"scheme\":\"https\"}},{\"display_url\":{\"url\":\"e.example.com\",\"domain\":{\"domain\":\"e.example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"e\",\"tld\":\"com\",\"valid\":true},\"scheme\":\"http\"},\"href_url\":{\"url\":\"e.example.com\",\"domain\":{\"domain\":\"e.example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"e\",\"tld\":\"com\",\"valid\":true},\"scheme\":\"http\"}},{\"display_url\":{\"url\":\"test.com\",\"domain\":{\"domain\":\"test.com\",\"root_domain\":\"test.com\",\"sld\":\"test\",\"tld\":\"com\",\"valid\":true},\"scheme\":\"http\"},\"href_url\":{\"url\":\"test.com\",\"domain\":{\"domain\":\"test.com\",\"root_domain\":\"test.com\",\"sld\":\"test\",\"tld\":\"com\",\"valid\":true},\"scheme\":\"http\"}}],\"current_thread\":{\"text\":\"\"}},\"external\":{\"created_at\":\"2024-08-08T06:39:47Z\",\"message_id\":\"11\",\"route_type\":\"received\",\"spam\":false},\"headers\":{\"auth_summary\":{\"dmarc\":{\"pass\":true,\"received_hop\":0,\"details\":{\"version\":null,\"verdict\":\"pass\",\"action\":null,\"policy\":\"NONE\",\"sub_policy\":\"QUARANTINE\",\"disposition\":\"NONE\",\"from\":{\"domain\":\"test.com\",\"root_domain\":\"test.com\",\"sld\":\"test\",\"tld\":\"com\",\"valid\":true}}},\"spf\":{\"pass\":true,\"error\":false,\"received_hop\":0,\"details\":{\"verdict\":\"pass\",\"server\":{\"domain\":\"test.com\",\"root_domain\":\"test.com\",\"sld\":\"test\",\"tld\":\"com\",\"valid\":true},\"client_ip\":{\"ip\":\"81.2.69.192\"},\"designator\":\"domain of alice123@test.com\",\"description\":\"test.com: domain of alice123@test.com designates 81.2.69.192 as permitted sender\"}}},\"date\":\"2024-08-08T06:39:33Z\",\"date_original_offset\":\"5\",\"delivered_to\":{\"email\":\"john123@test.com\",\"local_part\":\"john123\",\"domain\":{\"domain\":\"test.com\",\"root_domain\":\"test.com\",\"sld\":\"test\",\"tld\":\"com\",\"valid\":true}},\"domains\":[{\"domain\":\"mail-sor-f41.test.com\",\"root_domain\":\"test.com\",\"sld\":\"test\",\"subdomain\":\"mail-sor-f41\",\"tld\":\"com\",\"valid\":true},{\"domain\":\"mx.test.com\",\"root_domain\":\"test.com\",\"sld\":\"test\",\"subdomain\":\"mx\",\"tld\":\"com\",\"valid\":true},{\"domain\":\"test.com\",\"root_domain\":\"test.com\",\"sld\":\"test\",\"tld\":\"com\",\"valid\":true}],\"hops\":[{\"index\":0,\"authentication_results\":{\"compauth\": { \"verdict\": \"pass\", \"reason\": \"reason_value\" },\"type\":\"standard\",\"dkim\":\"pass\",\"dkim_details\":[{\"type\":\"dkim\",\"instance\":\"@test.com\",\"selector\":\"20230601\",\"signature\":\"elrBA+fb\"}],\"dmarc\":\"pass\",\"dmarc_details\":{\"version\":null,\"verdict\":\"pass\",\"action\":null,\"policy\":\"NONE\",\"sub_policy\":\"QUARANTINE\",\"disposition\":\"NONE\",\"from\":{\"domain\":\"test.com\",\"root_domain\":\"test.com\",\"sld\":\"test\",\"tld\":\"com\",\"valid\":true}},\"spf\":\"pass\",\"spf_details\":{\"verdict\":\"pass\",\"server\":{\"domain\":\"test.com\",\"root_domain\":\"test.com\",\"sld\":\"test\",\"tld\":\"com\",\"valid\":true},\"client_ip\":{\"ip\":\"81.2.69.192\"},\"designator\":\"alice123@test.com\",\"description\":\"test.com: domain of alice123@test.com designates 81.2.69.192 as permitted sender\"},\"server\":{\"domain\":\"mx.test.com\",\"root_domain\":\"test.com\",\"sld\":\"test\",\"subdomain\":\"mx\",\"tld\":\"com\",\"valid\":true}},\"signature\":{\"type\":\"dkim\",\"version\":\"1\",\"algorithm\":\"rsa-sha256\",\"selector\":\"20230601\",\"signature\":\"elrBA+fbKpLqfjEOj7s4cAR9f8s8Tz0lHFsCjgE4t5dSXKpL6YZRZ44EPNZ1I1ROJx jTmQ/zz41IUs7K4tWqtuJnM98GSCsEvc31Lr3w99k/kjWm0Raei5dWc/4OqxZKmEiV3J r4Un6IlHY5CiUO\",\"body_hash\":\"taAa59+CAu/Cmad8+7VJw9KpMlCezg5RHDG7X7f91P4=\",\"domain\":\"test.com\",\"headers\":\"to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to\"},\"received_spf\":{\"verdict\":\"pass\",\"server\":{\"domain\":\"test.com\",\"root_domain\":\"test.com\",\"sld\":\"test\",\"tld\":\"com\",\"valid\":true},\"client_ip\":{\"ip\":\"81.2.69.192\"},\"designator\":\"domain of alice123@test.com\",\"description\":\"test.com: domain of alice123@test.com designates 81.2.69.192 as permitted sender\"},\"fields\":[{\"name\":\"Content-Type\",\"value\":\"multipart/alternative; boundary=\\\"000000000000e2ee4a061f264a8a\\\"\",\"position\":0},{\"name\":\"To\",\"value\":\"john123@test.com\",\"position\":1},{\"name\":\"Subject\",\"value\":\"Fwd: How to Achieve Your Career Goals in 2024\",\"position\":2},{\"name\":\"Message-ID\",\"value\":\"\",\"position\":3},{\"name\":\"Date\",\"value\":\"Thu, 8 Aug 2024 12:09:33 +0530\",\"position\":4},{\"name\":\"From\",\"value\":\"Alice \",\"position\":5},{\"name\":\"In-Reply-To\",\"value\":\"\",\"position\":6},{\"name\":\"References\",\"value\":\"\",\"position\":7},{\"name\":\"MIME-Version\",\"value\":\"1.0\",\"position\":8},{\"name\":\"X-Received\",\"value\":\"by 2002:a05:6512:12cc:b0:52b:faa1:7c74 with SMTP id 2adb3069b0e04-530e5d21173mr181491e87.5.1723099185866; Wed, 07 Aug 2024 23:39:45 -0700 (PDT)\",\"position\":9},{\"name\":\"X-Test-Smtp-Source\",\"value\":\"AGHT+IEOPD6/KQ1QGxfpqSsNfRVL3tyvz5l2ZkiY/swtxVoJf6PjrsQMELt982FDdWiYdCh6nHFEnpPzh50Rx+gpG+8=\",\"position\":10},{\"name\":\"X-Gm-Message-State\",\"value\":\"AOJu0YyLnr/Zjgr7uXbT4OWJKXOdcruE0DB5eYAxH2GMsUDqfM81HEem KMt/4qXMzEYtzJJ+2fkjA2zpg2e3zN9iqNuiUI86WAOTl07NfeqPMJCIDDz0Q0gfeiOwIK8rlL8 jammp+/G9xCHMayr+inDiqemweFRyvA==\",\"position\":11},{\"name\":\"X-Test-DKIM-Signature\",\"value\":\"v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723099186; x=1723703986; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=taAa59+CAu/Cmad8+7VJw9KpMlCezg5RHDG7X7f91P4=; b=VcRvW5nfz7WbzaIuyv5g5x/Z2U0qbrDR6qP\",\"position\":12},{\"name\":\"DKIM-Signature\",\"value\":\"v=1; a=rsa-sha256; c=relaxed/relaxed; d=test.com; s=20230601; t=1723099186; x=1723703986; dara=test.com; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to; bh=taAa59+CAu/Cmad8+7VJw9KpMlCezg5RHDG7X7f91P4=\",\"position\":13},{\"name\":\"Authentication-Results\",\"value\":\"mx.test.com; dkim=pass header.i=@test.com header.s=20230601 header.b=elrBA+fb; spf=pass (test.com: domain of alice123@test.com designates 81.2.69.192 as permitted sender) smtp.mailfrom=alice123@test.com; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=test.com; dara=pass header.i=@test.com\",\"position\":14},{\"name\":\"Received-SPF\",\"value\":\"pass (test.com: domain of alice123@test.com designates 81.2.69.192 as permitted sender) client-ip=81.2.69.192;\",\"position\":15},{\"name\":\"Received\",\"value\":\"from mail-sor-f41.test.com (mail-sor-f41.test.com. [81.2.69.192]) by mx.test.com with SMTPS id 2adb3069b0e04-530de79d133sor508979e87.12.2024.08.07.23.39.46 for (Test Transport Security); Wed, 07 Aug 2024 23:39:47 -0700 (PDT)\",\"position\":16}],\"received\":{\"source\":{\"raw\":\"mail-sor-f41.test.com (mail-sor-f41.test.com. [81.2.69.192])\"},\"server\":{\"raw\":\"mx.test.com\"},\"mailbox\":{\"raw\":\"\"},\"protocol\":{\"raw\":\"SMTPS\"},\"id\":{\"raw\":\"2adb3069b1e04-530de79d133sor508979e87.12.2024.08.07.23.39.46\"},\"additional\":{\"raw\":\"(Test Transport Security)\"},\"time\":\"2024-08-08T06:39:47Z\",\"zone_offset\":\"-7\"}},{\"index\":1,\"authentication_results\":{\"type\":\"arc\",\"instance\":\"1\",\"dkim\":\"pass\",\"dkim_details\":[{\"type\":\"dkim\",\"instance\":\"@test.com\",\"selector\":\"20230601\",\"signature\":\"elrBA+fb\"}],\"dmarc\":\"pass\",\"dmarc_details\":{\"version\":null,\"verdict\":\"pass\",\"action\":null,\"policy\":\"NONE\",\"sub_policy\":\"QUARANTINE\",\"disposition\":\"NONE\",\"from\":{\"domain\":\"test.com\",\"root_domain\":\"test.com\",\"sld\":\"test\",\"tld\":\"com\",\"valid\":true}},\"spf\":\"pass\",\"spf_details\":{\"verdict\":\"pass\",\"server\":{\"domain\":\"test.com\",\"root_domain\":\"test.com\",\"sld\":\"test\",\"tld\":\"com\",\"valid\":true},\"client_ip\":{\"ip\":\"81.2.69.192\"},\"designator\":\"alice123@test.com\",\"description\":\"test.com: domain of alice123@test.com designates 81.2.69.192 as permitted sender\"},\"server\":{\"domain\":\"mx.test.com\",\"root_domain\":\"test.com\",\"sld\":\"test\",\"subdomain\":\"mx\",\"tld\":\"com\",\"valid\":true}},\"signature\":{\"type\":\"arc-message\",\"instance\":\"1\",\"algorithm\":\"rsa-sha256\",\"selector\":\"arc-20160816\",\"signature\":\"nKqpy2hvLAXWHwdm39Mg1dL6lziVFqVY7ikY9FaP1w0pDHO6t0zbiMwcwSkS/Crz+ Y38+/FHiPhk65AocA0Yzw9P96RpK60iDaHfXpEBsxJIhJt9GN7\",\"body_hash\":\"taAa59+CAu/Cmad8+7VJw9KpMlCezg5RHDG7X7f91P4=\",\"domain\":\"test.com\",\"headers\":\"to:subject:message-id:date:from:in-reply-to:references:mime-version :dkim-signature\"},\"fields\":[{\"name\":\"Return-Path\",\"value\":\"\",\"position\":17},{\"name\":\"ARC-Authentication-Results\",\"value\":\"i=1; mx.test.com; dkim=pass header.i=@test.com header.s=20230601 header.b=elrBA+fb; spf=pass (test.com: domain of alice123@test.com designates 81.2.69.192 as permitted sender) smtp.mailfrom=alice123@test.com; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=test.com; dara=pass header.i=@test.com\",\"position\":18},{\"name\":\"ARC-Message-Signature\",\"value\":\"i=1; a=rsa-sha256; c=relaxed/relaxed; d=test.com; s=arc-20160816; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :dkim-signature; bh=taAa59+CAu/Cmad8+7VJw9KpMlCezg5RHDG7X7f91P4=; fh=rEZ8N7lZwF+f2DJz7PZfSiLZqwmiZLvrdguxWR5M0Mw=; b=nKqpy2hvLAXWHw39Mg1dLY6lziVFqVY7ikY9FaP1\",\"position\":19},{\"name\":\"ARC-Seal\",\"value\":\"i=1; a=rsa-sha256; t=1723099187; cv=none; d=test.com; s=arc-20160816; b=s4+J1/60S5sNdJ0Fd56rNghLRYU+m7QHad7No6E0iBi+7WGCuOOd2w07CSfEx++0jx Y0lBuDGDzNrGGHVpfi3ODGvx/aoU2vg8/siNaHAnIR4ADSbV+sr67vFiIEPqYNmQyihC lhOm0gnxDVD7ozZ\",\"position\":20},{\"name\":\"X-Received\",\"value\":\"by 2002:a05:6512:1242:b0:52f:c398:8780 with SMTP id 2adb3069b0e04-530e5d70e42mr184435e87.18.1723099187103; Wed, 07 Aug 2024 23:39:47 -0700 (PDT)\",\"position\":21},{\"name\":\"Received\",\"value\":\"by 2002:a05:6850:988a:b0:5bb:ddaf:ae20 with SMTP id li10csp662340nnb; Wed, 7 Aug 2024 23:39:47 -0700 (PDT)\",\"position\":22}],\"received\":{\"server\":{\"raw\":\"2002:a05:6850:988a:b0:5bb:ddaf:ae20\"},\"protocol\":{\"raw\":\"SMTP\"},\"id\":{\"raw\":\"li10csp662340nnb\"},\"time\":\"2024-08-08T06:39:47Z\",\"zone_offset\":\"-7\"}},{\"index\":2,\"fields\":[{\"name\":\"Delivered-To\",\"value\":\"john123@test.com\",\"position\":23}]}],\"ips\":[{\"ip\":\"81.2.69.192\"}],\"message_id\":\"\",\"references\":[\"hpfhx9h8QtSRnWCE_AzviQ@geopod-ismtpd-56\"],\"in_reply_to\":\"\",\"return_path\":{\"email\":\"alice123@test.com\",\"local_part\":\"alice123\",\"domain\":{\"domain\":\"test.com\",\"root_domain\":\"test.com\",\"sld\":\"test\",\"tld\":\"com\",\"valid\":true}}},\"type\":{\"inbound\":true},\"mailbox\":{\"email\":{\"email\":\"john123@test.com\",\"local_part\":\"john123\",\"domain\":{\"domain\":\"test.com\",\"root_domain\":\"test.com\",\"sld\":\"test\",\"tld\":\"com\",\"valid\":true}}},\"recipients\":{\"to\":[{\"email\":{\"email\":\"john123@test.com\",\"local_part\":\"john123\",\"domain\":{\"domain\":\"test.com\",\"root_domain\":\"test.com\",\"sld\":\"test\",\"tld\":\"com\",\"valid\":true}}}]},\"sender\":{\"display_name\":\"Alice\",\"email\":{\"email\":\"alice123@test.com\",\"local_part\":\"alice123\",\"domain\":{\"domain\":\"test.com\",\"root_domain\":\"test.com\",\"sld\":\"test\",\"tld\":\"com\",\"valid\":true}}},\"subject\":{\"subject\":\"Fwd: How to Achieve Your Career Goals in 2024\"},\"_meta\":{\"id\":\"019130be-779c-7641-87c7-284e8dcb10e5\",\"canonical_id\":\"dc767a9c58a14ea5560b5786c644d5cb9ef7cadb11f680231ec09e8fdfeb4d53\",\"created_at\":\"2024-08-08T06:47:54.460399216Z\",\"effective_at\":\"2024-08-08T06:39:47Z\"}}",
+ "type": [
+ "info"
+ ]
+ },
+ "observer": {
+ "product": "Sublime Security",
+ "vendor": "Sublime Security"
+ },
+ "related": {
+ "hosts": [
+ "e.example.com",
+ "test.com",
+ "example.com",
+ "e2.example.com",
+ "mail-sor-f41.test.com",
+ "mx.test.com"
+ ],
+ "ip": [
+ "81.2.69.192"
+ ],
+ "user": [
+ "john123@test.com",
+ "alice123@test.com"
+ ]
+ },
+ "source": {
+ "domain": "test.com",
+ "top_level_domain": "com"
+ },
+ "sublime_security": {
+ "email_message": {
+ "body": {
+ "html": {
+ "charset": "utf-8",
+ "content_transfer_encoding": "quoted-printable",
+ "display_text": "---------- Forwarded message ---------\nFrom: xyz Instructor: \nDate: Wed, 22 Nov, 2023, 3:07pm\nSubject: How to Achieve Your Career Goals in 2024\nTo: \nNew Educational Announcement\nHi Alice, an announcement has been made from Alice, instructor of Linux Administration: The Complete Linux Bootcamp for 2023.",
+ "inner_text": "---------- Forwarded message ---------\nFrom:\nxyz Instructor: Alice \n<\nno-reply@e.example.com\n>\nDate: Wed, 22 Nov, 2023, 3:07 pm\nSubject: How to Achieve Your Career Goals in 2024\nTo: <\nalice123@test.com\n>\nNew Educational Announcement\nHi Alice, an announcement has been made from Alice, instructor of\nLinux Administration: The Complete Linux Bootcamp for 2023\n.\n",
+ "raw": "\r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n \r\n | \r\n"
+ },
+ "links": [
+ {
+ "display_text": "Linux Administration: The Complete Linux Bootcamp for 2023",
+ "href_url": {
+ "domain": {
+ "domain": "e2.example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "e2",
+ "tld": "com",
+ "valid": true
+ },
+ "path": "/ls/click",
+ "query_params": "upn=Z",
+ "scheme": "https",
+ "url": "https://e2.example.com/ls/click?upn=6n"
+ }
+ },
+ {
+ "display_text": "How I Went From Zero Job Offers To Working At xyz In 3 Years",
+ "href_url": {
+ "domain": {
+ "domain": "e2.example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "e2",
+ "tld": "com",
+ "valid": true
+ },
+ "path": "/ls/click",
+ "query_params": "upn=6n",
+ "scheme": "https",
+ "url": "https://e2.example.com/ls/click?upn=6n"
+ }
+ },
+ {
+ "display_text": "How to beat Imposter Syndrome!",
+ "href_url": {
+ "domain": {
+ "domain": "e2.example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "e2",
+ "tld": "com",
+ "valid": true
+ },
+ "path": "/ls/click",
+ "query_params": "upn=6nwDRRN3APL2A",
+ "scheme": "https",
+ "url": "https://e2.example.com/ls/click?upn=6nwDRRN3APL2A"
+ }
+ },
+ {
+ "display_text": "full state of AI for programmers",
+ "href_url": {
+ "domain": {
+ "domain": "e2.example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "e2",
+ "tld": "com",
+ "valid": true
+ },
+ "path": "/ls/click",
+ "query_params": "upn=6nwDR",
+ "scheme": "https",
+ "url": "https://e2.example.com/ls/click?upn=6nwDR"
+ }
+ },
+ {
+ "display_text": "See Announcement",
+ "href_url": {
+ "domain": {
+ "domain": "e2.example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "e2",
+ "tld": "com",
+ "valid": true
+ },
+ "path": "/ls/click",
+ "query_params": "upn=ZF3sOyS2SxEPIoSZT6Aoc",
+ "scheme": "https",
+ "url": "https://e2.example.com/ls/click?upn=ZF3sOyS2SxEPIoSZT6Aoc"
+ }
+ },
+ {
+ "display_text": "unsubscribe",
+ "href_url": {
+ "domain": {
+ "domain": "e2.example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "e2",
+ "tld": "com",
+ "valid": true
+ },
+ "path": "/ls/click",
+ "query_params": "upn=ZF3sOyS2S",
+ "scheme": "https",
+ "url": "https://e2.example.com/ls/click?upn=ZF3sOyS2S"
+ }
+ },
+ {
+ "display_text": "report abuse",
+ "href_url": {
+ "domain": {
+ "domain": "e2.example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "e2",
+ "tld": "com",
+ "valid": true
+ },
+ "path": "/ls/click",
+ "query_params": "upn=ZF3s",
+ "scheme": "https",
+ "url": "https://e2.example.com/ls/click?upn=ZF3s"
+ }
+ },
+ {
+ "display_url": {
+ "domain": {
+ "domain": "e.example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "e",
+ "tld": "com",
+ "valid": true
+ },
+ "scheme": "http",
+ "url": "e.example.com"
+ },
+ "href_url": {
+ "domain": {
+ "domain": "e.example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "e",
+ "tld": "com",
+ "valid": true
+ },
+ "scheme": "http",
+ "url": "e.example.com"
+ }
+ },
+ {
+ "display_url": {
+ "domain": {
+ "domain": "test.com",
+ "root_domain": "test.com",
+ "sld": "test",
+ "tld": "com",
+ "valid": true
+ },
+ "scheme": "http",
+ "url": "test.com"
+ },
+ "href_url": {
+ "domain": {
+ "domain": "test.com",
+ "root_domain": "test.com",
+ "sld": "test",
+ "tld": "com",
+ "valid": true
+ },
+ "scheme": "http",
+ "url": "test.com"
+ }
+ }
+ ],
+ "plain": {
+ "charset": "utf-8",
+ "content_transfer_encoding": "quoted-printable",
+ "raw": "---------- Forwarded message ---------\r\nFrom: xyz Instructor: Alice \r\nDate: Wed, 22 Nov, 2023, 3:07 pm\r\nSubject: How to Achieve Your Career Goals in 2024\r\nTo: \r\n\r\n\r\n\r\n\r\n* New Educational Announcement *\r\n\r\n"
+ }
+ },
+ "external": {
+ "created_at": "2024-08-08T06:39:47.000Z",
+ "message_id": "11",
+ "route_type": "received",
+ "spam": false
+ },
+ "headers": {
+ "auth_summary": {
+ "dmarc": {
+ "details": {
+ "disposition": "NONE",
+ "from": {
+ "domain": "test.com",
+ "root_domain": "test.com",
+ "sld": "test",
+ "tld": "com",
+ "valid": true
+ },
+ "policy": "NONE",
+ "sub_policy": "QUARANTINE",
+ "verdict": "pass"
+ },
+ "pass": true,
+ "received_hop": 0
+ },
+ "spf": {
+ "details": {
+ "client_ip": {
+ "ip": "81.2.69.192"
+ },
+ "description": "test.com: domain of alice123@test.com designates 81.2.69.192 as permitted sender",
+ "designator": "domain of alice123@test.com",
+ "server": {
+ "domain": "test.com",
+ "root_domain": "test.com",
+ "sld": "test",
+ "tld": "com",
+ "valid": true
+ },
+ "verdict": "pass"
+ },
+ "error": false,
+ "pass": true,
+ "received_hop": 0
+ }
+ },
+ "date": "2024-08-08T06:39:33.000Z",
+ "date_original_offset": "5",
+ "delivered_to": {
+ "domain": {
+ "domain": "test.com",
+ "root_domain": "test.com",
+ "sld": "test",
+ "tld": "com",
+ "valid": true
+ },
+ "email": "john123@test.com",
+ "local_part": "john123"
+ },
+ "domains": [
+ {
+ "domain": "mail-sor-f41.test.com",
+ "root_domain": "test.com",
+ "sld": "test",
+ "subdomain": "mail-sor-f41",
+ "tld": "com",
+ "valid": true
+ },
+ {
+ "domain": "mx.test.com",
+ "root_domain": "test.com",
+ "sld": "test",
+ "subdomain": "mx",
+ "tld": "com",
+ "valid": true
+ },
+ {
+ "domain": "test.com",
+ "root_domain": "test.com",
+ "sld": "test",
+ "tld": "com",
+ "valid": true
+ }
+ ],
+ "hops": [
+ {
+ "authentication_results": {
+ "compauth": {
+ "reason": "reason_value",
+ "verdict": "pass"
+ },
+ "dkim": "pass",
+ "dkim_details": [
+ {
+ "instance": "@test.com",
+ "selector": "20230601",
+ "signature": "elrBA+fb",
+ "type": "dkim"
+ }
+ ],
+ "dmarc": "pass",
+ "dmarc_details": {
+ "disposition": "NONE",
+ "from": {
+ "domain": "test.com",
+ "root_domain": "test.com",
+ "sld": "test",
+ "tld": "com",
+ "valid": true
+ },
+ "policy": "NONE",
+ "sub_policy": "QUARANTINE",
+ "verdict": "pass"
+ },
+ "server": {
+ "domain": "mx.test.com",
+ "root_domain": "test.com",
+ "sld": "test",
+ "subdomain": "mx",
+ "tld": "com",
+ "valid": true
+ },
+ "spf": "pass",
+ "spf_details": {
+ "client_ip": {
+ "ip": "81.2.69.192"
+ },
+ "description": "test.com: domain of alice123@test.com designates 81.2.69.192 as permitted sender",
+ "designator": "alice123@test.com",
+ "server": {
+ "domain": "test.com",
+ "root_domain": "test.com",
+ "sld": "test",
+ "tld": "com",
+ "valid": true
+ },
+ "verdict": "pass"
+ },
+ "type": "standard"
+ },
+ "fields": [
+ {
+ "content-type": "multipart/alternative; boundary=\"000000000000e2ee4a061f264a8a\"",
+ "name": "Content-Type",
+ "position": 0,
+ "value": "multipart/alternative; boundary=\"000000000000e2ee4a061f264a8a\""
+ },
+ {
+ "name": "To",
+ "position": 1,
+ "to": "john123@test.com",
+ "value": "john123@test.com"
+ },
+ {
+ "name": "Subject",
+ "position": 2,
+ "subject": "Fwd: How to Achieve Your Career Goals in 2024",
+ "value": "Fwd: How to Achieve Your Career Goals in 2024"
+ },
+ {
+ "message-id": "",
+ "name": "Message-ID",
+ "position": 3,
+ "value": ""
+ },
+ {
+ "date": "Thu, 8 Aug 2024 12:09:33 +0530",
+ "name": "Date",
+ "position": 4,
+ "value": "Thu, 8 Aug 2024 12:09:33 +0530"
+ },
+ {
+ "from": "Alice ",
+ "name": "From",
+ "position": 5,
+ "value": "Alice "
+ },
+ {
+ "in-reply-to": "",
+ "name": "In-Reply-To",
+ "position": 6,
+ "value": ""
+ },
+ {
+ "name": "References",
+ "position": 7,
+ "references": "",
+ "value": ""
+ },
+ {
+ "mime-version": "1.0",
+ "name": "MIME-Version",
+ "position": 8,
+ "value": "1.0"
+ },
+ {
+ "name": "X-Received",
+ "position": 9,
+ "value": "by 2002:a05:6512:12cc:b0:52b:faa1:7c74 with SMTP id 2adb3069b0e04-530e5d21173mr181491e87.5.1723099185866; Wed, 07 Aug 2024 23:39:45 -0700 (PDT)",
+ "x-received": "by 2002:a05:6512:12cc:b0:52b:faa1:7c74 with SMTP id 2adb3069b0e04-530e5d21173mr181491e87.5.1723099185866; Wed, 07 Aug 2024 23:39:45 -0700 (PDT)"
+ },
+ {
+ "name": "X-Test-Smtp-Source",
+ "position": 10,
+ "value": "AGHT+IEOPD6/KQ1QGxfpqSsNfRVL3tyvz5l2ZkiY/swtxVoJf6PjrsQMELt982FDdWiYdCh6nHFEnpPzh50Rx+gpG+8=",
+ "x-test-smtp-source": "AGHT+IEOPD6/KQ1QGxfpqSsNfRVL3tyvz5l2ZkiY/swtxVoJf6PjrsQMELt982FDdWiYdCh6nHFEnpPzh50Rx+gpG+8="
+ },
+ {
+ "name": "X-Gm-Message-State",
+ "position": 11,
+ "value": "AOJu0YyLnr/Zjgr7uXbT4OWJKXOdcruE0DB5eYAxH2GMsUDqfM81HEem KMt/4qXMzEYtzJJ+2fkjA2zpg2e3zN9iqNuiUI86WAOTl07NfeqPMJCIDDz0Q0gfeiOwIK8rlL8 jammp+/G9xCHMayr+inDiqemweFRyvA==",
+ "x-gm-message-state": "AOJu0YyLnr/Zjgr7uXbT4OWJKXOdcruE0DB5eYAxH2GMsUDqfM81HEem KMt/4qXMzEYtzJJ+2fkjA2zpg2e3zN9iqNuiUI86WAOTl07NfeqPMJCIDDz0Q0gfeiOwIK8rlL8 jammp+/G9xCHMayr+inDiqemweFRyvA=="
+ },
+ {
+ "name": "X-Test-DKIM-Signature",
+ "position": 12,
+ "value": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723099186; x=1723703986; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=taAa59+CAu/Cmad8+7VJw9KpMlCezg5RHDG7X7f91P4=; b=VcRvW5nfz7WbzaIuyv5g5x/Z2U0qbrDR6qP",
+ "x-test-dkim-signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723099186; x=1723703986; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=taAa59+CAu/Cmad8+7VJw9KpMlCezg5RHDG7X7f91P4=; b=VcRvW5nfz7WbzaIuyv5g5x/Z2U0qbrDR6qP"
+ },
+ {
+ "dkim-signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=test.com; s=20230601; t=1723099186; x=1723703986; dara=test.com; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to; bh=taAa59+CAu/Cmad8+7VJw9KpMlCezg5RHDG7X7f91P4=",
+ "name": "DKIM-Signature",
+ "position": 13,
+ "value": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=test.com; s=20230601; t=1723099186; x=1723703986; dara=test.com; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to; bh=taAa59+CAu/Cmad8+7VJw9KpMlCezg5RHDG7X7f91P4="
+ },
+ {
+ "authentication-results": "mx.test.com; dkim=pass header.i=@test.com header.s=20230601 header.b=elrBA+fb; spf=pass (test.com: domain of alice123@test.com designates 81.2.69.192 as permitted sender) smtp.mailfrom=alice123@test.com; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=test.com; dara=pass header.i=@test.com",
+ "name": "Authentication-Results",
+ "position": 14,
+ "value": "mx.test.com; dkim=pass header.i=@test.com header.s=20230601 header.b=elrBA+fb; spf=pass (test.com: domain of alice123@test.com designates 81.2.69.192 as permitted sender) smtp.mailfrom=alice123@test.com; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=test.com; dara=pass header.i=@test.com"
+ },
+ {
+ "name": "Received-SPF",
+ "position": 15,
+ "received-spf": "pass (test.com: domain of alice123@test.com designates 81.2.69.192 as permitted sender) client-ip=81.2.69.192;",
+ "value": "pass (test.com: domain of alice123@test.com designates 81.2.69.192 as permitted sender) client-ip=81.2.69.192;"
+ },
+ {
+ "name": "Received",
+ "position": 16,
+ "received": "from mail-sor-f41.test.com (mail-sor-f41.test.com. [81.2.69.192]) by mx.test.com with SMTPS id 2adb3069b0e04-530de79d133sor508979e87.12.2024.08.07.23.39.46 for (Test Transport Security); Wed, 07 Aug 2024 23:39:47 -0700 (PDT)",
+ "value": "from mail-sor-f41.test.com (mail-sor-f41.test.com. [81.2.69.192]) by mx.test.com with SMTPS id 2adb3069b0e04-530de79d133sor508979e87.12.2024.08.07.23.39.46 for (Test Transport Security); Wed, 07 Aug 2024 23:39:47 -0700 (PDT)"
+ }
+ ],
+ "index": 0,
+ "received": {
+ "additional": {
+ "raw": "(Test Transport Security)"
+ },
+ "id": {
+ "raw": "2adb3069b1e04-530de79d133sor508979e87.12.2024.08.07.23.39.46"
+ },
+ "mailbox": {
+ "raw": ""
+ },
+ "protocol": {
+ "raw": "SMTPS"
+ },
+ "server": {
+ "raw": "mx.test.com"
+ },
+ "source": {
+ "raw": "mail-sor-f41.test.com (mail-sor-f41.test.com. [81.2.69.192])"
+ },
+ "time": "2024-08-08T06:39:47.000Z",
+ "zone_offset": "-7"
+ },
+ "received_spf": {
+ "client_ip": {
+ "ip": "81.2.69.192"
+ },
+ "description": "test.com: domain of alice123@test.com designates 81.2.69.192 as permitted sender",
+ "designator": "domain of alice123@test.com",
+ "server": {
+ "domain": "test.com",
+ "root_domain": "test.com",
+ "sld": "test",
+ "tld": "com",
+ "valid": true
+ },
+ "verdict": "pass"
+ },
+ "signature": {
+ "algorithm": "rsa-sha256",
+ "body_hash": "taAa59+CAu/Cmad8+7VJw9KpMlCezg5RHDG7X7f91P4=",
+ "domain": "test.com",
+ "headers": "to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to",
+ "selector": "20230601",
+ "signature": "elrBA+fbKpLqfjEOj7s4cAR9f8s8Tz0lHFsCjgE4t5dSXKpL6YZRZ44EPNZ1I1ROJx jTmQ/zz41IUs7K4tWqtuJnM98GSCsEvc31Lr3w99k/kjWm0Raei5dWc/4OqxZKmEiV3J r4Un6IlHY5CiUO",
+ "type": "dkim",
+ "version": "1"
+ }
+ },
+ {
+ "authentication_results": {
+ "dkim": "pass",
+ "dkim_details": [
+ {
+ "instance": "@test.com",
+ "selector": "20230601",
+ "signature": "elrBA+fb",
+ "type": "dkim"
+ }
+ ],
+ "dmarc": "pass",
+ "dmarc_details": {
+ "disposition": "NONE",
+ "from": {
+ "domain": "test.com",
+ "root_domain": "test.com",
+ "sld": "test",
+ "tld": "com",
+ "valid": true
+ },
+ "policy": "NONE",
+ "sub_policy": "QUARANTINE",
+ "verdict": "pass"
+ },
+ "instance": "1",
+ "server": {
+ "domain": "mx.test.com",
+ "root_domain": "test.com",
+ "sld": "test",
+ "subdomain": "mx",
+ "tld": "com",
+ "valid": true
+ },
+ "spf": "pass",
+ "spf_details": {
+ "client_ip": {
+ "ip": "81.2.69.192"
+ },
+ "description": "test.com: domain of alice123@test.com designates 81.2.69.192 as permitted sender",
+ "designator": "alice123@test.com",
+ "server": {
+ "domain": "test.com",
+ "root_domain": "test.com",
+ "sld": "test",
+ "tld": "com",
+ "valid": true
+ },
+ "verdict": "pass"
+ },
+ "type": "arc"
+ },
+ "fields": [
+ {
+ "name": "Return-Path",
+ "position": 17,
+ "return-path": "",
+ "value": ""
+ },
+ {
+ "arc-authentication-results": "i=1; mx.test.com; dkim=pass header.i=@test.com header.s=20230601 header.b=elrBA+fb; spf=pass (test.com: domain of alice123@test.com designates 81.2.69.192 as permitted sender) smtp.mailfrom=alice123@test.com; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=test.com; dara=pass header.i=@test.com",
+ "name": "ARC-Authentication-Results",
+ "position": 18,
+ "value": "i=1; mx.test.com; dkim=pass header.i=@test.com header.s=20230601 header.b=elrBA+fb; spf=pass (test.com: domain of alice123@test.com designates 81.2.69.192 as permitted sender) smtp.mailfrom=alice123@test.com; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=test.com; dara=pass header.i=@test.com"
+ },
+ {
+ "arc-message-signature": "i=1; a=rsa-sha256; c=relaxed/relaxed; d=test.com; s=arc-20160816; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :dkim-signature; bh=taAa59+CAu/Cmad8+7VJw9KpMlCezg5RHDG7X7f91P4=; fh=rEZ8N7lZwF+f2DJz7PZfSiLZqwmiZLvrdguxWR5M0Mw=; b=nKqpy2hvLAXWHw39Mg1dLY6lziVFqVY7ikY9FaP1",
+ "name": "ARC-Message-Signature",
+ "position": 19,
+ "value": "i=1; a=rsa-sha256; c=relaxed/relaxed; d=test.com; s=arc-20160816; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :dkim-signature; bh=taAa59+CAu/Cmad8+7VJw9KpMlCezg5RHDG7X7f91P4=; fh=rEZ8N7lZwF+f2DJz7PZfSiLZqwmiZLvrdguxWR5M0Mw=; b=nKqpy2hvLAXWHw39Mg1dLY6lziVFqVY7ikY9FaP1"
+ },
+ {
+ "arc-seal": "i=1; a=rsa-sha256; t=1723099187; cv=none; d=test.com; s=arc-20160816; b=s4+J1/60S5sNdJ0Fd56rNghLRYU+m7QHad7No6E0iBi+7WGCuOOd2w07CSfEx++0jx Y0lBuDGDzNrGGHVpfi3ODGvx/aoU2vg8/siNaHAnIR4ADSbV+sr67vFiIEPqYNmQyihC lhOm0gnxDVD7ozZ",
+ "name": "ARC-Seal",
+ "position": 20,
+ "value": "i=1; a=rsa-sha256; t=1723099187; cv=none; d=test.com; s=arc-20160816; b=s4+J1/60S5sNdJ0Fd56rNghLRYU+m7QHad7No6E0iBi+7WGCuOOd2w07CSfEx++0jx Y0lBuDGDzNrGGHVpfi3ODGvx/aoU2vg8/siNaHAnIR4ADSbV+sr67vFiIEPqYNmQyihC lhOm0gnxDVD7ozZ"
+ },
+ {
+ "name": "X-Received",
+ "position": 21,
+ "value": "by 2002:a05:6512:1242:b0:52f:c398:8780 with SMTP id 2adb3069b0e04-530e5d70e42mr184435e87.18.1723099187103; Wed, 07 Aug 2024 23:39:47 -0700 (PDT)",
+ "x-received": "by 2002:a05:6512:1242:b0:52f:c398:8780 with SMTP id 2adb3069b0e04-530e5d70e42mr184435e87.18.1723099187103; Wed, 07 Aug 2024 23:39:47 -0700 (PDT)"
+ },
+ {
+ "name": "Received",
+ "position": 22,
+ "received": "by 2002:a05:6850:988a:b0:5bb:ddaf:ae20 with SMTP id li10csp662340nnb; Wed, 7 Aug 2024 23:39:47 -0700 (PDT)",
+ "value": "by 2002:a05:6850:988a:b0:5bb:ddaf:ae20 with SMTP id li10csp662340nnb; Wed, 7 Aug 2024 23:39:47 -0700 (PDT)"
+ }
+ ],
+ "index": 1,
+ "received": {
+ "id": {
+ "raw": "li10csp662340nnb"
+ },
+ "protocol": {
+ "raw": "SMTP"
+ },
+ "server": {
+ "raw": "2002:a05:6850:988a:b0:5bb:ddaf:ae20"
+ },
+ "time": "2024-08-08T06:39:47.000Z",
+ "zone_offset": "-7"
+ },
+ "signature": {
+ "algorithm": "rsa-sha256",
+ "body_hash": "taAa59+CAu/Cmad8+7VJw9KpMlCezg5RHDG7X7f91P4=",
+ "domain": "test.com",
+ "headers": "to:subject:message-id:date:from:in-reply-to:references:mime-version :dkim-signature",
+ "instance": "1",
+ "selector": "arc-20160816",
+ "signature": "nKqpy2hvLAXWHwdm39Mg1dL6lziVFqVY7ikY9FaP1w0pDHO6t0zbiMwcwSkS/Crz+ Y38+/FHiPhk65AocA0Yzw9P96RpK60iDaHfXpEBsxJIhJt9GN7",
+ "type": "arc-message"
+ }
+ },
+ {
+ "fields": [
+ {
+ "delivered-to": "john123@test.com",
+ "name": "Delivered-To",
+ "position": 23,
+ "value": "john123@test.com"
+ }
+ ],
+ "index": 2
+ }
+ ],
+ "in_reply_to": "",
+ "ips": [
+ {
+ "ip": "81.2.69.192"
+ }
+ ],
+ "message_id": "",
+ "references": [
+ "hpfhx9h8QtSRnWCE_AzviQ@geopod-ismtpd-56"
+ ],
+ "return_path": {
+ "domain": {
+ "domain": "test.com",
+ "root_domain": "test.com",
+ "sld": "test",
+ "tld": "com",
+ "valid": true
+ },
+ "email": "alice123@test.com",
+ "local_part": "alice123"
+ }
+ },
+ "mailbox": {
+ "email": {
+ "domain": {
+ "domain": "test.com",
+ "root_domain": "test.com",
+ "sld": "test",
+ "tld": "com",
+ "valid": true
+ },
+ "local_part": "john123",
+ "value": "john123@test.com"
+ }
+ },
+ "meta": {
+ "canonical_id": "dc767a9c58a14ea5560b5786c644d5cb9ef7cadb11f680231ec09e8fdfeb4d53",
+ "created_at": "2024-08-08T06:47:54.460Z",
+ "effective_at": "2024-08-08T06:39:47.000Z",
+ "id": "019130be-779c-7641-87c7-284e8dcb10e5"
+ },
+ "recipients": {
+ "to": [
+ {
+ "email": {
+ "domain": {
+ "domain": "test.com",
+ "root_domain": "test.com",
+ "sld": "test",
+ "tld": "com",
+ "valid": true
+ },
+ "local_part": "john123",
+ "value": "john123@test.com"
+ }
+ }
+ ]
+ },
+ "sender": {
+ "display_name": "Alice",
+ "email": {
+ "domain": {
+ "domain": "test.com",
+ "root_domain": "test.com",
+ "sld": "test",
+ "tld": "com",
+ "valid": true
+ },
+ "local_part": "alice123",
+ "value": "alice123@test.com"
+ }
+ },
+ "subject": {
+ "subject": "Fwd: How to Achieve Your Career Goals in 2024"
+ },
+ "type": {
+ "inbound": true
+ }
+ }
+ },
+ "tags": [
+ "preserve_duplicate_custom_fields"
+ ],
+ "url": [
+ {
+ "domain": "e2.example.com",
+ "full": "https://e2.example.com/ls/click?upn=6n",
+ "path": "/ls/click",
+ "query": "upn=Z",
+ "scheme": "https",
+ "subdomain": "e2",
+ "top_level_domain": "com"
+ },
+ {
+ "domain": "e2.example.com",
+ "full": "https://e2.example.com/ls/click?upn=6n",
+ "path": "/ls/click",
+ "query": "upn=6n",
+ "scheme": "https",
+ "subdomain": "e2",
+ "top_level_domain": "com"
+ },
+ {
+ "domain": "e2.example.com",
+ "full": "https://e2.example.com/ls/click?upn=6nwDRRN3APL2A",
+ "path": "/ls/click",
+ "query": "upn=6nwDRRN3APL2A",
+ "scheme": "https",
+ "subdomain": "e2",
+ "top_level_domain": "com"
+ },
+ {
+ "domain": "e2.example.com",
+ "full": "https://e2.example.com/ls/click?upn=6nwDR",
+ "path": "/ls/click",
+ "query": "upn=6nwDR",
+ "scheme": "https",
+ "subdomain": "e2",
+ "top_level_domain": "com"
+ },
+ {
+ "domain": "e2.example.com",
+ "full": "https://e2.example.com/ls/click?upn=ZF3sOyS2SxEPIoSZT6Aoc",
+ "path": "/ls/click",
+ "query": "upn=ZF3sOyS2SxEPIoSZT6Aoc",
+ "scheme": "https",
+ "subdomain": "e2",
+ "top_level_domain": "com"
+ },
+ {
+ "domain": "e2.example.com",
+ "full": "https://e2.example.com/ls/click?upn=ZF3sOyS2S",
+ "path": "/ls/click",
+ "query": "upn=ZF3sOyS2S",
+ "scheme": "https",
+ "subdomain": "e2",
+ "top_level_domain": "com"
+ },
+ {
+ "domain": "e2.example.com",
+ "full": "https://e2.example.com/ls/click?upn=ZF3s",
+ "path": "/ls/click",
+ "query": "upn=ZF3s",
+ "scheme": "https",
+ "subdomain": "e2",
+ "top_level_domain": "com"
+ },
+ {
+ "domain": "e.example.com",
+ "full": "e.example.com",
+ "scheme": "http",
+ "subdomain": "e",
+ "top_level_domain": "com"
+ },
+ {
+ "domain": "test.com",
+ "full": "test.com",
+ "scheme": "http",
+ "top_level_domain": "com"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/packages/sublime_security/data_stream/email_message/_dev/test/system/test-aws-s3-config.yml b/packages/sublime_security/data_stream/email_message/_dev/test/system/test-aws-s3-config.yml
new file mode 100644
index 00000000000..bb6b6f37112
--- /dev/null
+++ b/packages/sublime_security/data_stream/email_message/_dev/test/system/test-aws-s3-config.yml
@@ -0,0 +1,14 @@
+input: aws-s3
+wait_for_data_timeout: 20m
+vars:
+ access_key_id: "{{AWS_ACCESS_KEY_ID}}"
+ secret_access_key: "{{AWS_SECRET_ACCESS_KEY}}"
+ session_token: "{{AWS_SESSION_TOKEN}}"
+data_stream:
+ vars:
+ queue_url: "{{TF_OUTPUT_queue_url}}"
+ preserve_original_event: true
+ file_selectors: |
+ - regex: '^(.+?)\.log'
+ assert:
+ hit_count: 1
diff --git a/packages/sublime_security/data_stream/email_message/agent/stream/aws-s3.yml.hbs b/packages/sublime_security/data_stream/email_message/agent/stream/aws-s3.yml.hbs
new file mode 100644
index 00000000000..8fbc7eee6de
--- /dev/null
+++ b/packages/sublime_security/data_stream/email_message/agent/stream/aws-s3.yml.hbs
@@ -0,0 +1,94 @@
+{{#if collect_s3_logs}}
+
+{{#if bucket_arn}}
+bucket_arn: {{bucket_arn}}
+{{/if}}
+{{#if number_of_workers}}
+number_of_workers: {{number_of_workers}}
+{{/if}}
+{{#if interval}}
+bucket_list_interval: {{interval}}
+{{/if}}
+{{#if bucket_list_prefix}}
+bucket_list_prefix: {{bucket_list_prefix}}
+{{/if}}
+
+{{else}}
+
+{{#if queue_url}}
+queue_url: {{queue_url}}
+{{/if}}
+{{#if region}}
+region: {{region}}
+{{/if}}
+{{#if visibility_timeout}}
+visibility_timeout: {{visibility_timeout}}
+{{/if}}
+{{#if api_timeout}}
+api_timeout: {{api_timeout}}
+{{/if}}
+{{#if max_number_of_messages}}
+max_number_of_messages: {{max_number_of_messages}}
+{{/if}}
+{{#if file_selectors}}
+file_selectors:
+{{file_selectors}}
+{{/if}}
+
+{{/if}}
+
+{{#if access_key_id}}
+access_key_id: {{access_key_id}}
+{{/if}}
+{{#if secret_access_key}}
+secret_access_key: {{secret_access_key}}
+{{/if}}
+{{#if session_token}}
+session_token: {{session_token}}
+{{/if}}
+{{#if shared_credential_file}}
+shared_credential_file: {{shared_credential_file}}
+{{/if}}
+{{#if credential_profile_name}}
+credential_profile_name: {{credential_profile_name}}
+{{/if}}
+{{#if role_arn}}
+role_arn: {{role_arn}}
+{{/if}}
+{{#if external_id}}
+external_id: {{external_id}}
+{{/if}}
+{{#if default_region}}
+default_region: {{default_region}}
+{{/if}}
+{{#if fips_enabled}}
+fips_enabled: {{fips_enabled}}
+{{/if}}
+{{#if proxy_url}}
+proxy_url: {{proxy_url}}
+{{/if}}
+{{#if ssl}}
+ssl: {{ssl}}
+{{/if}}
+tags:
+{{#if collect_s3_logs}}
+ - collect_s3_logs
+{{else}}
+ - collect_sqs_logs
+{{/if}}
+{{#if preserve_original_event}}
+ - preserve_original_event
+{{/if}}
+{{#if preserve_duplicate_custom_fields}}
+ - preserve_duplicate_custom_fields
+{{/if}}
+{{#each tags as |tag|}}
+ - {{tag}}
+{{/each}}
+{{#contains "forwarded" tags}}
+publisher_pipeline.disable_host: true
+{{/contains}}
+{{#if processors}}
+processors:
+{{processors}}
+{{/if}}
diff --git a/packages/sublime_security/data_stream/email_message/elasticsearch/ingest_pipeline/default.yml b/packages/sublime_security/data_stream/email_message/elasticsearch/ingest_pipeline/default.yml
new file mode 100644
index 00000000000..83f3a843934
--- /dev/null
+++ b/packages/sublime_security/data_stream/email_message/elasticsearch/ingest_pipeline/default.yml
@@ -0,0 +1,2165 @@
+---
+description: Pipeline for processing email_message logs.
+processors:
+ - set:
+ field: ecs.version
+ tag: set_ecs_version
+ value: 8.11.0
+ - rename:
+ field: message
+ tag: rename_message_to_event_original
+ target_field: event.original
+ ignore_missing: true
+ description: Renames the original `message` field to `event.original` to store a copy of the original message. The `event.original` field is not touched if the document already has one; it may happen when Logstash sends the document.
+ if: ctx.event?.original == null
+ - remove:
+ field: message
+ tag: remove_message
+ ignore_missing: true
+ description: The `message` field is no longer required if the document has an `event.original` field.
+ if: ctx.event?.original != null
+ - json:
+ field: event.original
+ tag: json_event_original
+ target_field: json
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - set:
+ field: event.kind
+ tag: set_event_kind_to_event
+ value: event
+ - append:
+ field: event.category
+ tag: append_email_into_event_category
+ value: email
+ - append:
+ field: event.type
+ tag: append_info_into_event_type
+ value: info
+ - set:
+ field: observer.vendor
+ tag: set_observer_vendor
+ value: Sublime Security
+ - set:
+ field: observer.product
+ tag: set_observer_product
+ value: Sublime Security
+ - foreach:
+ field: json.attachments
+ if: ctx.json?.attachments instanceof List
+ processor:
+ rename:
+ field: _ingest._value.content_id
+ tag: rename_attachments_content_id
+ target_field: _ingest._value.content.id
+ ignore_missing: true
+ - foreach:
+ field: json.attachments
+ if: ctx.json?.attachments instanceof List
+ processor:
+ rename:
+ field: _ingest._value.content_transfer_encoding
+ tag: rename_attachments_content_transfer_encoding
+ target_field: _ingest._value.content.transfer_encoding
+ ignore_missing: true
+ - foreach:
+ field: json.attachments
+ if: ctx.json?.attachments instanceof List
+ processor:
+ rename:
+ field: _ingest._value.content_type
+ tag: rename_attachments_content_type
+ target_field: _ingest._value.content.type
+ ignore_missing: true
+ - foreach:
+ field: json.attachments
+ if: ctx.json?.attachments instanceof List
+ processor:
+ rename:
+ field: _ingest._value.file_name
+ tag: rename_attachments_file_name
+ target_field: _ingest._value.file.name
+ ignore_missing: true
+ - foreach:
+ field: json.attachments
+ if: ctx.json?.attachments instanceof List
+ processor:
+ rename:
+ field: _ingest._value.file_type
+ tag: rename_attachments_file_type
+ target_field: _ingest._value.file.type
+ ignore_missing: true
+ - foreach:
+ field: json.attachments
+ if: ctx.json?.attachments instanceof List
+ processor:
+ rename:
+ field: _ingest._value.file_extension
+ tag: rename_attachments_file_extension
+ target_field: _ingest._value.file.extension
+ ignore_missing: true
+ - foreach:
+ field: json.attachments
+ if: ctx.json?.attachments instanceof List
+ processor:
+ append:
+ field: related.hash
+ tag: append_attachments_md5_into_related_hash
+ value: '{{{_ingest._value.md5}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.attachments
+ if: ctx.json?.attachments instanceof List
+ processor:
+ append:
+ field: related.hash
+ tag: append_attachments_sha1_into_related_hash
+ value: '{{{_ingest._value.sha1}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.attachments
+ if: ctx.json?.attachments instanceof List
+ processor:
+ append:
+ field: related.hash
+ tag: append_attachments_sha256_into_related_hash
+ value: '{{{_ingest._value.sha256}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.attachments
+ if: ctx.json?.attachments instanceof List
+ processor:
+ convert:
+ field: _ingest._value.size
+ tag: convert_attachments_size_to_long
+ type: long
+ ignore_missing: true
+ on_failure:
+ - remove:
+ field: _ingest._value.size
+ ignore_missing: true
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - rename:
+ field: json.attachments
+ tag: rename_attachments
+ target_field: sublime_security.email_message.attachments
+ ignore_missing: true
+ - script:
+ description: Set email attachments field.
+ tag: script_to_set_email_attachments_field
+ lang: painless
+ if: ctx.sublime_security?.email_message?.attachments instanceof List
+ source: |-
+ def attachmentList = new ArrayList();
+ for (attachment in ctx.sublime_security.email_message.attachments) {
+ def object = new HashMap();
+ object.put('file', new HashMap());
+ object.file.put('hash', new HashMap());
+ object.file.put('mime_type', attachment.content.type);
+ object.file.put('extension', attachment.file.extension);
+ object.file.put('name', attachment.file.name);
+ object.file.put('size', attachment.size);
+ object.file.hash.put('md5', attachment.md5);
+ object.file.hash.put('sha1', attachment.sha1);
+ object.file.hash.put('sha256', attachment.sha256);
+ attachmentList.add(object);
+ }
+ ctx.put('email',new HashMap());
+ ctx.email.attachments = attachmentList;
+ - script:
+ description: Extract extension name from email attachments.
+ tag: script_to_extract_extension_name
+ lang: painless
+ if: ctx.email?.attachments instanceof List
+ source: |-
+ for (attachment in ctx.email.attachments) {
+ if (attachment.file.extension != null && attachment.file.extension.startsWith('.')) {
+ String extension = attachment.file.extension.substring(1);
+ attachment.file.extension = extension;
+ }
+ }
+ - rename:
+ field: json.body.current_thread.text
+ tag: rename_body_current_thread_text
+ target_field: sublime_security.email_message.body.current_thread.text
+ ignore_missing: true
+ - rename:
+ field: json.body.html.charset
+ tag: rename_body_html_charset
+ target_field: sublime_security.email_message.body.html.charset
+ ignore_missing: true
+ - rename:
+ field: json.body.html.content_transfer_encoding
+ tag: rename_body_html_content_transfer_encoding
+ target_field: sublime_security.email_message.body.html.content_transfer_encoding
+ ignore_missing: true
+ - rename:
+ field: json.body.html.display_text
+ tag: rename_body_html_display_text
+ target_field: sublime_security.email_message.body.html.display_text
+ ignore_missing: true
+ - rename:
+ field: json.body.html.inner_text
+ tag: rename_body_html_inner_text
+ target_field: sublime_security.email_message.body.html.inner_text
+ ignore_missing: true
+ - rename:
+ field: json.body.html.raw
+ tag: rename_body_html_raw
+ target_field: sublime_security.email_message.body.html.raw
+ ignore_missing: true
+ - foreach:
+ field: json.body.ips
+ if: ctx.json?.body?.ips instanceof List
+ processor:
+ convert:
+ field: _ingest._value.ip
+ tag: convert_body_ips_ip_to_ip
+ type: ip
+ ignore_missing: true
+ on_failure:
+ - remove:
+ field: _ingest._value.ip
+ ignore_missing: true
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - foreach:
+ field: json.body.ips
+ if: ctx.json?.body?.ips instanceof List
+ processor:
+ append:
+ field: related.ip
+ tag: append_body_ips_ip_into_related_ip
+ value: '{{{_ingest._value.ip}}}'
+ allow_duplicates: false
+ - rename:
+ field: json.body.ips
+ tag: rename_body_ips
+ target_field: sublime_security.email_message.body.ips
+ ignore_missing: true
+ - foreach:
+ field: json.body.links
+ if: ctx.json?.body?.links instanceof List
+ processor:
+ append:
+ field: related.hosts
+ tag: append_body_links_display_url_domain_domain_into_related_hosts
+ value: '{{{_ingest._value.display_url.domain.domain}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.body.links
+ if: ctx.json?.body?.links instanceof List
+ processor:
+ convert:
+ field: _ingest._value.display_url.port
+ tag: convert_body_links_display_url_port_to_long
+ type: long
+ ignore_missing: true
+ on_failure:
+ - remove:
+ field: _ingest._value.display_url.port
+ ignore_missing: true
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - foreach:
+ field: json.body.links
+ if: ctx.json?.body?.links instanceof List
+ processor:
+ append:
+ field: related.hosts
+ tag: append_body_links_display_url_domain_root_domain_into_related_hosts
+ value: '{{{_ingest._value.display_url.domain.root_domain}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.body.links
+ if: ctx.json?.body?.links instanceof List
+ processor:
+ append:
+ field: related.user
+ tag: append_body_links_display_url_username_into_related_user
+ value: '{{{_ingest._value.display_url.username}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.body.links
+ if: ctx.json?.body?.links instanceof List
+ processor:
+ convert:
+ field: _ingest._value.display_url.domain.valid
+ tag: convert_body_links_display_url_domain_valid_to_boolean
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - remove:
+ field: _ingest._value.display_url.domain.valid
+ ignore_missing: true
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - foreach:
+ field: json.body.links
+ if: ctx.json?.body?.links instanceof List
+ processor:
+ append:
+ field: related.hosts
+ tag: append_body_links_href_url_domain_domain_into_related_hosts
+ value: '{{{_ingest._value.href_url.domain.domain}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.body.links
+ if: ctx.json?.body?.links instanceof List
+ processor:
+ append:
+ field: related.hosts
+ tag: append_body_links_href_url_domain_root_domain_into_related_hosts
+ value: '{{{_ingest._value.href_url.domain.root_domain}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.body.links
+ if: ctx.json?.body?.links instanceof List
+ processor:
+ convert:
+ field: _ingest._value.href_url.port
+ tag: convert_body_links_href_url_port_to_long
+ type: long
+ ignore_missing: true
+ on_failure:
+ - remove:
+ field: _ingest._value.href_url.port
+ ignore_missing: true
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - foreach:
+ field: json.body.links
+ if: ctx.json?.body?.links instanceof List
+ processor:
+ append:
+ field: related.user
+ tag: append_body_links_href_url_username_into_related.user
+ value: '{{{_ingest._value.href_url.username}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.body.links
+ if: ctx.json?.body?.links instanceof List
+ processor:
+ convert:
+ field: _ingest._value.href_url.domain.valid
+ tag: convert_body_links_href_url_domain_valid_to_boolean
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - remove:
+ field: _ingest._value.href_url.domain.valid
+ ignore_missing: true
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - foreach:
+ field: json.body.links
+ if: ctx.json?.body?.links instanceof List
+ processor:
+ convert:
+ field: _ingest._value.mismatched
+ tag: convert_body_links_mismatched_to_boolean
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - remove:
+ field: _ingest._value.mismatched
+ ignore_missing: true
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - script:
+ description: Set url field.
+ tag: script_to_set_url_field
+ lang: painless
+ if: ctx.json?.body?.links instanceof List
+ source: |-
+ def links = new ArrayList();
+ for (link in ctx.json.body.links) {
+ def object = new HashMap();
+ if(link?.href_url != null) {
+ object.put('domain', link.href_url.domain.domain);
+ object.put('subdomain', link.href_url.domain.subdomain);
+ object.put('top_level_domain', link.href_url.domain.tld);
+ object.put('fragment', link.href_url.fragment);
+ object.put('password', link.href_url.password);
+ object.put('path', link.href_url.path);
+ object.put('port', link.href_url.port);
+ object.put('query', link.href_url.query_params);
+ object.put('scheme', link.href_url.scheme);
+ object.put('full', link.href_url.url);
+ object.put('username', link.href_url.username);
+ links.add(object);
+ }
+ }
+ ctx.put('url',new HashMap());
+ ctx.url = links;
+ - rename:
+ field: json.body.links
+ tag: rename_body_links
+ target_field: sublime_security.email_message.body.links
+ ignore_missing: true
+ - rename:
+ field: json.body.plain.charset
+ tag: rename_body_plain_charset
+ target_field: sublime_security.email_message.body.plain.charset
+ ignore_missing: true
+ - rename:
+ field: json.body.plain.content_transfer_encoding
+ tag: rename_body_plain_content_transfer_encoding
+ target_field: sublime_security.email_message.body.plain.content_transfer_encoding
+ ignore_missing: true
+ - rename:
+ field: json.body.plain.raw
+ tag: rename_body_plain_raw
+ target_field: sublime_security.email_message.body.plain.raw
+ ignore_missing: true
+ - rename:
+ field: json._errors
+ tag: rename_errors
+ target_field: sublime_security.email_message.errors
+ ignore_missing: true
+ - date:
+ field: json.external.created_at
+ tag: date_external_created_at
+ target_field: sublime_security.email_message.external.created_at
+ formats:
+ - ISO8601
+ if: ctx.json?.external?.created_at != null && ctx.json.external.created_at != ''
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - set:
+ field: email.origination_timestamp
+ tag: set_email_origination_timestamp_from_email_message_external_created_at
+ copy_from: sublime_security.email_message.external.created_at
+ ignore_empty_value: true
+ - rename:
+ field: json.external.message_id
+ tag: rename_external_message_id
+ target_field: sublime_security.email_message.external.message_id
+ ignore_missing: true
+ - rename:
+ field: json.external.route_type
+ tag: rename_external_route_type
+ target_field: sublime_security.email_message.external.route_type
+ ignore_missing: true
+ - convert:
+ field: json.external.spam
+ tag: convert_external_spam_to_boolean
+ target_field: sublime_security.email_message.external.spam
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - convert:
+ field: json.external.spam_folder
+ tag: convert_external_spam_folder_to_boolean
+ target_field: sublime_security.email_message.external.spam_folder
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - rename:
+ field: json.external.thread_id
+ tag: rename_external_thread_id
+ target_field: sublime_security.email_message.external.thread_id
+ ignore_missing: true
+ - rename:
+ field: json.headers.auth_summary.dmarc.details.action
+ tag: rename_headers_auth_summary_dmarc_details_action
+ target_field: sublime_security.email_message.headers.auth_summary.dmarc.details.action
+ ignore_missing: true
+ - rename:
+ field: json.headers.auth_summary.dmarc.details.disposition
+ tag: rename_headers_auth_summary_dmarc_details_disposition
+ target_field: sublime_security.email_message.headers.auth_summary.dmarc.details.disposition
+ ignore_missing: true
+ - rename:
+ field: json.headers.auth_summary.dmarc.details.from.domain
+ tag: rename_headers_auth_summary_dmarc_details_from_domain
+ target_field: sublime_security.email_message.headers.auth_summary.dmarc.details.from.domain
+ ignore_missing: true
+ - append:
+ field: related.hosts
+ tag: append_headers_auth_summary_dmarc_details_from_domain_into_related_hosts
+ value: '{{{sublime_security.email_message.headers.auth_summary.dmarc.details.from.domain}}}'
+ allow_duplicates: false
+ - rename:
+ field: json.headers.auth_summary.dmarc.details.from.punycode
+ tag: rename_headers_auth_summary_dmarc_details_from_punycode
+ target_field: sublime_security.email_message.headers.auth_summary.dmarc.details.from.punycode
+ ignore_missing: true
+ - rename:
+ field: json.headers.auth_summary.dmarc.details.from.root_domain
+ tag: rename_headers_auth_summary_dmarc_details_from_root_domain
+ target_field: sublime_security.email_message.headers.auth_summary.dmarc.details.from.root_domain
+ ignore_missing: true
+ - append:
+ field: related.hosts
+ tag: append_headers_auth_summary_dmarc_details_from_root_domain_into_related_hosts
+ value: '{{{sublime_security.email_message.headers.auth_summary.dmarc.details.from.root_domain}}}'
+ allow_duplicates: false
+ - rename:
+ field: json.headers.auth_summary.dmarc.details.from.sld
+ tag: rename_headers_auth_summary_dmarc_details_from_sld
+ target_field: sublime_security.email_message.headers.auth_summary.dmarc.details.from.sld
+ ignore_missing: true
+ - rename:
+ field: json.headers.auth_summary.dmarc.details.from.subdomain
+ tag: rename_headers_auth_summary_dmarc_details_from_subdomain
+ target_field: sublime_security.email_message.headers.auth_summary.dmarc.details.from.subdomain
+ ignore_missing: true
+ - rename:
+ field: json.headers.auth_summary.dmarc.details.from.tld
+ tag: rename_headers_auth_summary_dmarc_details_from_tld
+ target_field: sublime_security.email_message.headers.auth_summary.dmarc.details.from.tld
+ ignore_missing: true
+ - convert:
+ field: json.headers.auth_summary.dmarc.details.from.valid
+ tag: convert_headers_auth_summary_dmarc_details_from_valid_to_boolean
+ target_field: sublime_security.email_message.headers.auth_summary.dmarc.details.from.valid
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - rename:
+ field: json.headers.auth_summary.dmarc.details.policy
+ tag: rename_headers_auth_summary_dmarc_details_policy
+ target_field: sublime_security.email_message.headers.auth_summary.dmarc.details.policy
+ ignore_missing: true
+ - rename:
+ field: json.headers.auth_summary.dmarc.details.sub_policy
+ tag: rename_headers_auth_summary_dmarc_details_sub_policy
+ target_field: sublime_security.email_message.headers.auth_summary.dmarc.details.sub_policy
+ ignore_missing: true
+ - rename:
+ field: json.headers.auth_summary.dmarc.details.verdict
+ tag: rename_headers_auth_summary_dmarc_details_verdict
+ target_field: sublime_security.email_message.headers.auth_summary.dmarc.details.verdict
+ ignore_missing: true
+ - rename:
+ field: json.headers.auth_summary.dmarc.details.version
+ tag: rename_headers_auth_summary_dmarc_details_version
+ target_field: sublime_security.email_message.headers.auth_summary.dmarc.details.version
+ ignore_missing: true
+ - convert:
+ field: json.headers.auth_summary.dmarc.pass
+ tag: convert_headers_auth_summary_dmarc_pass_to_boolean
+ target_field: sublime_security.email_message.headers.auth_summary.dmarc.pass
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - convert:
+ field: json.headers.auth_summary.dmarc.received_hop
+ tag: convert_headers_auth_summary_dmarc_received_hop_to_long
+ target_field: sublime_security.email_message.headers.auth_summary.dmarc.received_hop
+ type: long
+ ignore_missing: true
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - convert:
+ field: json.headers.auth_summary.spf.details.client_ip.ip
+ tag: convert_headers_auth_summary_spf_details_client_ip_ip_to_ip
+ target_field: sublime_security.email_message.headers.auth_summary.spf.details.client_ip.ip
+ type: ip
+ ignore_missing: true
+ if: ctx.json?.headers?.auth_summary?.spf?.details?.client_ip?.ip != null && ctx.json.headers.auth_summary.spf.details.client_ip.ip != ''
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - append:
+ field: related.ip
+ tag: append_headers_auth_summary_spf_details_client_ip_into_related_ip
+ value: '{{{sublime_security.email_message.headers.auth_summary.spf.details.client_ip.ip}}}'
+ allow_duplicates: false
+ - rename:
+ field: json.headers.auth_summary.spf.details.description
+ tag: rename_headers_auth_summary_spf_details_description
+ target_field: sublime_security.email_message.headers.auth_summary.spf.details.description
+ ignore_missing: true
+ - rename:
+ field: json.headers.auth_summary.spf.details.designator
+ tag: rename_headers_auth_summary_spf_details_designator
+ target_field: sublime_security.email_message.headers.auth_summary.spf.details.designator
+ ignore_missing: true
+ - rename:
+ field: json.headers.auth_summary.spf.details.helo.domain
+ tag: rename_headers_auth_summary_spf_details_helo_domain
+ target_field: sublime_security.email_message.headers.auth_summary.spf.details.helo.domain
+ ignore_missing: true
+ - append:
+ field: related.hosts
+ tag: append_headers_auth_summary_spf_details_helo_domain_into_related_host
+ value: '{{{sublime_security.email_message.headers.auth_summary.spf.details.helo.domain}}}'
+ allow_duplicates: false
+ - rename:
+ field: json.headers.auth_summary.spf.details.helo.punycode
+ tag: rename_headers_auth_summary_spf_details_helo_punycode
+ target_field: sublime_security.email_message.headers.auth_summary.spf.details.helo.punycode
+ ignore_missing: true
+ - rename:
+ field: json.headers.auth_summary.spf.details.helo.root_domain
+ tag: rename_headers_auth_summary_spf_details_helo_root_domain
+ target_field: sublime_security.email_message.headers.auth_summary.spf.details.helo.root_domain
+ ignore_missing: true
+ - append:
+ field: related.hosts
+ tag: append_headers_auth_summary_spf_details_helo_root_domain_into_related_host
+ value: '{{{sublime_security.email_message.headers.auth_summary.spf.details.helo.root_domain}}}'
+ allow_duplicates: false
+ - rename:
+ field: json.headers.auth_summary.spf.details.helo.sld
+ tag: rename_headers_auth_summary_spf_details_helo_sld
+ target_field: sublime_security.email_message.headers.auth_summary.spf.details.helo.sld
+ ignore_missing: true
+ - rename:
+ field: json.headers.auth_summary.spf.details.helo.subdomain
+ tag: rename_headers_auth_summary_spf_details_helo_subdomain
+ target_field: sublime_security.email_message.headers.auth_summary.spf.details.helo.subdomain
+ ignore_missing: true
+ - rename:
+ field: json.headers.auth_summary.spf.details.helo.tld
+ tag: rename_headers_auth_summary_spf_details_helo_tld
+ target_field: sublime_security.email_message.headers.auth_summary.spf.details.helo.tld
+ ignore_missing: true
+ - convert:
+ field: json.headers.auth_summary.spf.details.helo.valid
+ tag: convert_headers_auth_summary_spf_details_helo_valid_to_boolean
+ target_field: sublime_security.email_message.headers.auth_summary.spf.details.helo.valid
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - rename:
+ field: json.headers.auth_summary.spf.details.server.domain
+ tag: rename_headers_auth_summary_spf_details_server_domain
+ target_field: sublime_security.email_message.headers.auth_summary.spf.details.server.domain
+ ignore_missing: true
+ - append:
+ field: related.hosts
+ tag: append_headers_auth_summary_spf_details_server_domain_into_related_host
+ value: '{{{sublime_security.email_message.headers.auth_summary.spf.details.server.domain}}}'
+ allow_duplicates: false
+ - rename:
+ field: json.headers.auth_summary.spf.details.server.punycode
+ tag: rename_headers_auth_summary_spf_details_server_punycode
+ target_field: sublime_security.email_message.headers.auth_summary.spf.details.server.punycode
+ ignore_missing: true
+ - rename:
+ field: json.headers.auth_summary.spf.details.server.root_domain
+ tag: rename_headers_auth_summary_spf_details_server_root_domain
+ target_field: sublime_security.email_message.headers.auth_summary.spf.details.server.root_domain
+ ignore_missing: true
+ - append:
+ field: related.hosts
+ tag: append_headers_auth_summary_spf_details_server_root_domain_into_related_host
+ value: '{{{sublime_security.email_message.headers.auth_summary.spf.details.server.root_domain}}}'
+ allow_duplicates: false
+ - rename:
+ field: json.headers.auth_summary.spf.details.server.sld
+ tag: rename_headers_auth_summary_spf_details_server_sld
+ target_field: sublime_security.email_message.headers.auth_summary.spf.details.server.sld
+ ignore_missing: true
+ - rename:
+ field: json.headers.auth_summary.spf.details.server.subdomain
+ tag: rename_headers_auth_summary_spf_details_server_subdomain
+ target_field: sublime_security.email_message.headers.auth_summary.spf.details.server.subdomain
+ ignore_missing: true
+ - rename:
+ field: json.headers.auth_summary.spf.details.server.tld
+ tag: rename_headers_auth_summary_spf_details_server_tld
+ target_field: sublime_security.email_message.headers.auth_summary.spf.details.server.tld
+ ignore_missing: true
+ - convert:
+ field: json.headers.auth_summary.spf.details.server.valid
+ tag: convert_headers_auth_summary_spf_details_server_valid_to_boolean
+ target_field: sublime_security.email_message.headers.auth_summary.spf.details.server.valid
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - rename:
+ field: json.headers.auth_summary.spf.details.verdict
+ tag: rename_headers_auth_summary_spf_details_verdict
+ target_field: sublime_security.email_message.headers.auth_summary.spf.details.verdict
+ ignore_missing: true
+ - convert:
+ field: json.headers.auth_summary.spf.error
+ tag: convert_headers_auth_summary_spf_error_to_boolean
+ target_field: sublime_security.email_message.headers.auth_summary.spf.error
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - convert:
+ field: json.headers.auth_summary.spf.pass
+ tag: convert_headers_auth_summary_spf_pass_to_boolean
+ target_field: sublime_security.email_message.headers.auth_summary.spf.pass
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - convert:
+ field: json.headers.auth_summary.spf.received_hop
+ tag: convert_headers_auth_summary_spf_received_hop_to_long
+ target_field: sublime_security.email_message.headers.auth_summary.spf.received_hop
+ type: long
+ ignore_missing: true
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - date:
+ field: json.headers.date
+ tag: date_headers_date
+ target_field: sublime_security.email_message.headers.date
+ formats:
+ - ISO8601
+ if: ctx.json?.headers?.date != null && ctx.json.headers.date != ''
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - rename:
+ field: json.headers.date_original_offset
+ tag: rename_headers_date_original_offset
+ target_field: sublime_security.email_message.headers.date_original_offset
+ ignore_missing: true
+ - rename:
+ field: json.headers.delivered_to.domain.domain
+ tag: rename_headers_delivered_to_domain_domain
+ target_field: sublime_security.email_message.headers.delivered_to.domain.domain
+ ignore_missing: true
+ - set:
+ field: destination.domain
+ tag: set_destination_domain_from_headers_delivered_to_domain_domain
+ copy_from: sublime_security.email_message.headers.delivered_to.domain.domain
+ ignore_empty_value: true
+ - rename:
+ field: json.headers.delivered_to.domain.punycode
+ tag: rename_headers_delivered_to_domain_punycode
+ target_field: sublime_security.email_message.headers.delivered_to.domain.punycode
+ ignore_missing: true
+ - rename:
+ field: json.headers.delivered_to.domain.root_domain
+ tag: rename_headers_delivered_to_domain_root_domain
+ target_field: sublime_security.email_message.headers.delivered_to.domain.root_domain
+ ignore_missing: true
+ - rename:
+ field: json.headers.delivered_to.domain.sld
+ tag: rename_headers_delivered_to_domain_sld
+ target_field: sublime_security.email_message.headers.delivered_to.domain.sld
+ ignore_missing: true
+ - rename:
+ field: json.headers.delivered_to.domain.subdomain
+ tag: rename_headers_delivered_to_domain_subdomain
+ target_field: sublime_security.email_message.headers.delivered_to.domain.subdomain
+ ignore_missing: true
+ - set:
+ field: destination.subdomain
+ tag: set_destination_subdomain_from_headers_delivered_to_domain_subdomain
+ copy_from: sublime_security.email_message.headers.delivered_to.domain.subdomain
+ ignore_empty_value: true
+ - rename:
+ field: json.headers.delivered_to.domain.tld
+ tag: rename_headers_delivered_to_domain_tld
+ target_field: sublime_security.email_message.headers.delivered_to.domain.tld
+ ignore_missing: true
+ - set:
+ field: destination.top_level_domain
+ tag: set_destination_top_level_domain_from_headers_delivered_to_domain_tld
+ copy_from: sublime_security.email_message.headers.delivered_to.domain.tld
+ ignore_empty_value: true
+ - convert:
+ field: json.headers.delivered_to.domain.valid
+ tag: convert_headers_delivered_to_domain_valid_to_boolean
+ target_field: sublime_security.email_message.headers.delivered_to.domain.valid
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - rename:
+ field: json.headers.delivered_to.email
+ tag: rename_headers_delivered_to_email
+ target_field: sublime_security.email_message.headers.delivered_to.email
+ ignore_missing: true
+ - rename:
+ field: json.headers.delivered_to.local_part
+ tag: rename_headers_delivered_to_local_part
+ target_field: sublime_security.email_message.headers.delivered_to.local_part
+ ignore_missing: true
+ - foreach:
+ field: json.headers.domains
+ if: ctx.json?.headers?.domains instanceof List
+ processor:
+ append:
+ field: related.hosts
+ tag: append_headers_domains_domain_into_related_hosts
+ value: '{{{_ingest._value.domain}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.headers.domains
+ if: ctx.json?.headers?.domains instanceof List
+ processor:
+ append:
+ field: related.hosts
+ tag: append_headers_domains_root_domain_into_related_hosts
+ value: '{{{_ingest._value.root_domain}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.headers.domains
+ if: ctx.json?.headers?.domains instanceof List
+ processor:
+ convert:
+ field: _ingest._value.valid
+ tag: convert_headers_domains_valid_to_boolean
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - remove:
+ field: _ingest._value.valid
+ ignore_missing: true
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - rename:
+ field: json.headers.domains
+ tag: rename_headers_domains
+ target_field: sublime_security.email_message.headers.domains
+ ignore_missing: true
+ - foreach:
+ field: json.headers.hops
+ if: ctx.json?.headers?.hops instanceof List
+ processor:
+ convert:
+ field: _ingest._value.authentication_results.dmarc_details.from.valid
+ tag: convert_headers_hops_authentication_results_dmarc_details_from_valid_to_boolean
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - remove:
+ field: _ingest._value.authentication_results.dmarc_details.from.valid
+ ignore_missing: true
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - foreach:
+ field: json.headers.hops
+ if: ctx.json?.headers?.hops instanceof List
+ processor:
+ convert:
+ field: _ingest._value.authentication_results.server.valid
+ tag: convert_headers_hops_authentication_results_server_valid_to_boolean
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - remove:
+ field: _ingest._value.authentication_results.server.valid
+ ignore_missing: true
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - foreach:
+ field: json.headers.hops
+ if: ctx.json?.headers?.hops instanceof List
+ processor:
+ foreach:
+ field: _ingest._value.fields
+ ignore_failure: true
+ processor:
+ convert:
+ field: _ingest._value.position
+ tag: convert_headers_hops_fields_position_to_long
+ type: long
+ ignore_missing: true
+ on_failure:
+ - remove:
+ field: _ingest._value.position
+ ignore_missing: true
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - script:
+ lang: painless
+ description: add mapping of name and value in fields array.
+ tag: script to add mapping of name and value in fields array
+ if: ctx.json?.headers?.hops instanceof List
+ source: |
+ def hops = ctx.json.headers.hops;
+ for (int i = 0; i < hops.size(); i++) {
+ def hop = hops[i];
+ if(hop.fields instanceof List) {
+ for (def field : hop.fields) {
+ def lowercaseName = field.name.toLowerCase();
+ field[lowercaseName] = field.value;
+ }
+ }
+ }
+ - foreach:
+ field: json.headers.hops
+ if: ctx.json?.headers?.hops instanceof List
+ processor:
+ append:
+ field: related.hash
+ tag: append_headers_hops_authentication_results_dkim_details_body_hash_into_related_hash
+ value: '{{{_ingest._value.authentication_results.dkim_details.body_hash}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.headers.hops
+ if: ctx.json?.headers?.hops instanceof List
+ processor:
+ append:
+ field: related.hosts
+ tag: append_headers_hops_authentication_results_dmarc_details_from_domain_into_related_hosts
+ value: '{{{_ingest._value.authentication_results.dmarc_details.from.domain}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.headers.hops
+ if: ctx.json?.headers?.hops instanceof List
+ processor:
+ append:
+ field: related.hosts
+ tag: append_headers_hops_authentication_results_dmarc_details_from_root_domain_into_related_hosts
+ value: '{{{_ingest._value.authentication_results.dmarc_details.from.root_domain}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.headers.hops
+ if: ctx.json?.headers?.hops instanceof List
+ processor:
+ append:
+ field: related.hosts
+ tag: append_headers_hops_authentication_results_server_domain_into_related_hosts
+ value: '{{{_ingest._value.authentication_results.server.domain}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.headers.hops
+ if: ctx.json?.headers?.hops instanceof List
+ processor:
+ append:
+ field: related.hosts
+ tag: append_headers_hops_authentication_results_server_root_domain_into_related_hosts
+ value: '{{{_ingest._value.authentication_results.server.root_domain}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.headers.hops
+ if: ctx.json?.headers?.hops instanceof List
+ processor:
+ convert:
+ field: _ingest._value.index
+ tag: convert_headers_hops_index_to_long
+ type: long
+ ignore_missing: true
+ on_failure:
+ - remove:
+ field: _ingest._value.index
+ ignore_missing: true
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - foreach:
+ field: json.headers.hops
+ if: ctx.json?.headers?.hops instanceof List
+ processor:
+ date:
+ field: _ingest._value.received.time
+ tag: date_headers_hops_received_time
+ target_field: _ingest._value.received.time
+ formats:
+ - ISO8601
+ on_failure:
+ - remove:
+ field: _ingest._value.received.time
+ ignore_missing: true
+ - foreach:
+ field: json.headers.hops
+ if: ctx.json?.headers?.hops instanceof List
+ processor:
+ convert:
+ field: _ingest._value.received_spf.client_ip.ip
+ tag: convert_headers_hops_received_spf_client_ip_ip_to_ip
+ type: ip
+ ignore_missing: true
+ on_failure:
+ - remove:
+ field: _ingest._value.received_spf.client_ip.ip
+ ignore_missing: true
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - foreach:
+ field: json.headers.hops
+ if: ctx.json?.headers?.hops instanceof List
+ processor:
+ append:
+ field: related.ip
+ tag: append_headers_hops_received_spf_client_ip_ip_into_related_ip
+ value: '{{{_ingest._value.received_spf.client_ip.ip}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.headers.hops
+ if: ctx.json?.headers?.hops instanceof List
+ processor:
+ append:
+ field: related.hosts
+ tag: append_headers_hops_received_spf_helo_domain_into_related_hosts
+ value: '{{{_ingest._value.received_spf.helo.domain}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.headers.hops
+ if: ctx.json?.headers?.hops instanceof List
+ processor:
+ append:
+ field: related.hosts
+ tag: append_headers_hops_received_spf_helo_root_domain_into_related_hosts
+ value: '{{{_ingest._value.received_spf.helo.root_domain}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.headers.hops
+ if: ctx.json?.headers?.hops instanceof List
+ processor:
+ convert:
+ field: _ingest._value.received_spf.helo.valid
+ tag: convert_headers_hops_received_spf_helo_valid_to_boolean
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - remove:
+ field: _ingest._value.received_spf.helo.valid
+ ignore_missing: true
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - foreach:
+ field: json.headers.hops
+ if: ctx.json?.headers?.hops instanceof List
+ processor:
+ append:
+ field: related.hosts
+ tag: append_headers_hops_received_spf_server_domain_into_related_hosts
+ value: '{{{_ingest._value.received_spf.server.domain}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.headers.hops
+ if: ctx.json?.headers?.hops instanceof List
+ processor:
+ append:
+ field: related.hosts
+ tag: append_headers_hops_received_spf_server_root_domain_into_related_hosts
+ value: '{{{_ingest._value.received_spf.server.root_domain}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.headers.hops
+ if: ctx.json?.headers?.hops instanceof List
+ processor:
+ convert:
+ field: _ingest._value.received_spf.server.valid
+ tag: convert_headers_hops_received_spf_server_valid_to_boolean
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - remove:
+ field: _ingest._value.received_spf.server.valid
+ ignore_missing: true
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - foreach:
+ field: json.headers.hops
+ if: ctx.json?.headers?.hops instanceof List
+ processor:
+ convert:
+ field: _ingest._value.authentication_results.spf_details.client_ip.ip
+ tag: convert_headers_hops_authentication_results_spf_details_client_ip_ip_to_ip
+ type: ip
+ ignore_missing: true
+ on_failure:
+ - remove:
+ field: _ingest._value.authentication_results.spf_details.client_ip.ip
+ ignore_missing: true
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - foreach:
+ field: json.headers.hops
+ if: ctx.json?.headers?.hops instanceof List
+ processor:
+ append:
+ field: related.ip
+ tag: append_headers_hops_authentication_results_spf_details_client_ip_ip_into_related_ip
+ value: '{{{_ingest._value.authentication_results.spf_details.client_ip.ip}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.headers.hops
+ if: ctx.json?.headers?.hops instanceof List
+ processor:
+ append:
+ field: related.hosts
+ tag: append_headers_hops_authentication_results_spf_details_helo_domain_into_related_hosts
+ value: '{{{_ingest._value.authentication_results.spf_details.helo.domain}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.headers.hops
+ if: ctx.json?.headers?.hops instanceof List
+ processor:
+ append:
+ field: related.hosts
+ tag: append_headers_hops_authentication_results_spf_details_helo_root_domain_into_related_hosts
+ value: '{{{_ingest._value.authentication_results.spf_details.helo.root_domain}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.headers.hops
+ if: ctx.json?.headers?.hops instanceof List
+ processor:
+ convert:
+ field: _ingest._value.authentication_results.spf_details.helo.valid
+ tag: convert_headers_hops_authentication_results_spf_details_helo_valid_to_boolean
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - remove:
+ field: _ingest._value.authentication_results.spf_details.helo.valid
+ ignore_missing: true
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - foreach:
+ field: json.headers.hops
+ if: ctx.json?.headers?.hops instanceof List
+ processor:
+ append:
+ field: related.hosts
+ tag: append_headers_hops_authentication_results_spf_details_server_domain_into_related_hosts
+ value: '{{{_ingest._value.authentication_results.spf_details.server.domain}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.headers.hops
+ if: ctx.json?.headers?.hops instanceof List
+ processor:
+ append:
+ field: related.hosts
+ tag: append_headers_hops_authentication_results_spf_details_server_root_domain_into_related_hosts
+ value: '{{{_ingest._value.authentication_results.spf_details.server.root_domain}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.headers.hops
+ if: ctx.json?.headers?.hops instanceof List
+ processor:
+ convert:
+ field: _ingest._value.authentication_results.spf_details.server.valid
+ tag: convert_headers_hops_authentication_results_spf_details_server_valid_to_boolean
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - remove:
+ field: _ingest._value.authentication_results.spf_details.server.valid
+ ignore_missing: true
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - rename:
+ field: json.headers.hops
+ tag: rename_headers_hops
+ target_field: sublime_security.email_message.headers.hops
+ ignore_missing: true
+ - rename:
+ field: json.headers.in_reply_to
+ tag: rename_headers_in_reply_to
+ target_field: sublime_security.email_message.headers.in_reply_to
+ ignore_missing: true
+ - foreach:
+ field: json.headers.ips
+ if: ctx.json?.headers?.ips instanceof List
+ processor:
+ append:
+ field: related.ip
+ tag: append_headers_ips_ip_into_related_ip
+ value: '{{{_ingest._value.ip}}}'
+ allow_duplicates: false
+ - rename:
+ field: json.headers.ips
+ tag: rename_headers_ips
+ target_field: sublime_security.email_message.headers.ips
+ ignore_missing: true
+ - rename:
+ field: json.headers.mailer
+ tag: rename_headers_mailer
+ target_field: sublime_security.email_message.headers.mailer
+ ignore_missing: true
+ - set:
+ field: email.x_mailer
+ tag: set_email_x_mailer_from_email_message_headers_mailer
+ copy_from: sublime_security.email_message.headers.mailer
+ ignore_empty_value: true
+ - user_agent:
+ field: email.x_mailer
+ ignore_missing: true
+ - rename:
+ field: json.headers.message_id
+ tag: rename_headers_message_id
+ target_field: sublime_security.email_message.headers.message_id
+ ignore_missing: true
+ - set:
+ field: email.message_id
+ tag: set_email_message_id_from_email_message_headers_message_id
+ copy_from: sublime_security.email_message.headers.message_id
+ ignore_empty_value: true
+ - rename:
+ field: json.headers.references
+ tag: rename_headers_references
+ target_field: sublime_security.email_message.headers.references
+ ignore_missing: true
+ - foreach:
+ field: json.headers.reply_to
+ if: ctx.json?.headers?.reply_to instanceof List
+ processor:
+ append:
+ field: related.hosts
+ tag: append_headers_reply_to_email_domain_domain_into_related_hosts
+ value: '{{{_ingest._value.email.domain.domain}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.headers.reply_to
+ if: ctx.json?.headers?.reply_to instanceof List
+ processor:
+ append:
+ field: related.hosts
+ tag: append_headers_reply_to_email_domain_root_domain_into_related_hosts
+ value: '{{{_ingest._value.email.domain.root_domain}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.headers.reply_to
+ if: ctx.json?.headers?.reply_to instanceof List
+ processor:
+ convert:
+ field: _ingest._value.email.domain.valid
+ tag: convert_headers_reply_to_email_domain_valid_to_boolean
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - remove:
+ field: _ingest._value.email.domain.valid
+ ignore_missing: true
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - foreach:
+ field: json.headers.reply_to
+ if: ctx.json?.headers?.reply_to instanceof List
+ processor:
+ append:
+ field: email.reply_to.address
+ tag: append_headers_reply_to_email_email_into_email_reply_to_address
+ value: '{{{_ingest._value.email.email}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.headers.reply_to
+ if: ctx.json?.headers?.reply_to instanceof List
+ processor:
+ append:
+ field: related.user
+ tag: append_headers_reply_to_email_email_into_related_user
+ value: '{{{_ingest._value.email.email}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.headers.reply_to
+ if: ctx.json?.headers?.reply_to instanceof List
+ processor:
+ rename:
+ field: _ingest._value.email.email
+ tag: rename_headers_reply_to_email_email_to_value
+ target_field: _ingest._value.email.value
+ ignore_missing: true
+ - rename:
+ field: json.headers.reply_to
+ tag: rename_headers_reply_to
+ target_field: sublime_security.email_message.headers.reply_to
+ ignore_missing: true
+ - rename:
+ field: json.headers.return_path.domain.domain
+ tag: rename_headers_return_path_domain_domain
+ target_field: sublime_security.email_message.headers.return_path.domain.domain
+ ignore_missing: true
+ - append:
+ field: related.hosts
+ tag: append_headers_return_path_domain_domain_into_related_hosts
+ value: '{{{sublime_security.email_message.headers.return_path.domain.domain}}}'
+ allow_duplicates: false
+ - rename:
+ field: json.headers.return_path.domain.punycode
+ tag: rename_headers_return_path_domain_punycode
+ target_field: sublime_security.email_message.headers.return_path.domain.punycode
+ ignore_missing: true
+ - rename:
+ field: json.headers.return_path.domain.root_domain
+ tag: rename_headers_return_path_domain_root_domain
+ target_field: sublime_security.email_message.headers.return_path.domain.root_domain
+ ignore_missing: true
+ - append:
+ field: related.hosts
+ tag: append_headers_return_path_domain_root_domain_into_related_hosts
+ value: '{{{sublime_security.email_message.headers.return_path.domain.root_domain}}}'
+ allow_duplicates: false
+ - rename:
+ field: json.headers.return_path.domain.sld
+ tag: rename_headers_return_path_domain_sld
+ target_field: sublime_security.email_message.headers.return_path.domain.sld
+ ignore_missing: true
+ - rename:
+ field: json.headers.return_path.domain.subdomain
+ tag: rename_headers_return_path_domain_subdomain
+ target_field: sublime_security.email_message.headers.return_path.domain.subdomain
+ ignore_missing: true
+ - rename:
+ field: json.headers.return_path.domain.tld
+ tag: rename_headers_return_path_domain_tld
+ target_field: sublime_security.email_message.headers.return_path.domain.tld
+ ignore_missing: true
+ - convert:
+ field: json.headers.return_path.domain.valid
+ tag: convert_headers_return_path_domain_valid_to_boolean
+ target_field: sublime_security.email_message.headers.return_path.domain.valid
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - rename:
+ field: json.headers.return_path.email
+ tag: rename_headers_return_path_email
+ target_field: sublime_security.email_message.headers.return_path.email
+ ignore_missing: true
+ - rename:
+ field: json.headers.return_path.local_part
+ tag: rename_headers_return_path_local_part
+ target_field: sublime_security.email_message.headers.return_path.local_part
+ ignore_missing: true
+ - rename:
+ field: json.headers.x_authenticated_domain.domain
+ tag: rename_headers_x_authenticated_domain_domain
+ target_field: sublime_security.email_message.headers.x_authenticated_domain.domain
+ ignore_missing: true
+ - append:
+ field: related.hosts
+ tag: append_headers_x_authenticated_domain_domain_into_related_hosts
+ value: '{{{sublime_security.email_message.headers.x_authenticated_domain.domain}}}'
+ allow_duplicates: false
+ - rename:
+ field: json.headers.x_authenticated_domain.punycode
+ tag: rename_headers_x_authenticated_domain_punycode
+ target_field: sublime_security.email_message.headers.x_authenticated_domain.punycode
+ ignore_missing: true
+ - rename:
+ field: json.headers.x_authenticated_domain.root_domain
+ tag: rename_headers_x_authenticated_domain_root_domain
+ target_field: sublime_security.email_message.headers.x_authenticated_domain.root_domain
+ ignore_missing: true
+ - append:
+ field: related.hosts
+ tag: append_headers_x_authenticated_domain_root_domain_into_related_hosts
+ value: '{{{sublime_security.email_message.headers.x_authenticated_domain.root_domain}}}'
+ allow_duplicates: false
+ - rename:
+ field: json.headers.x_authenticated_domain.sld
+ tag: rename_headers_x_authenticated_domain_sld
+ target_field: sublime_security.email_message.headers.x_authenticated_domain.sld
+ ignore_missing: true
+ - rename:
+ field: json.headers.x_authenticated_domain.subdomain
+ tag: rename_headers_x_authenticated_domain_subdomain
+ target_field: sublime_security.email_message.headers.x_authenticated_domain.subdomain
+ ignore_missing: true
+ - rename:
+ field: json.headers.x_authenticated_domain.tld
+ tag: rename_headers_x_authenticated_domain_tld
+ target_field: sublime_security.email_message.headers.x_authenticated_domain.tld
+ ignore_missing: true
+ - convert:
+ field: json.headers.x_authenticated_domain.valid
+ tag: convert_headers_x_authenticated_domain_valid_to_boolean
+ target_field: sublime_security.email_message.headers.x_authenticated_domain.valid
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - rename:
+ field: json.headers.x_authenticated_sender.domain.domain
+ tag: rename_headers_x_authenticated_sender_domain_domain
+ target_field: sublime_security.email_message.headers.x_authenticated_sender.domain.domain
+ ignore_missing: true
+ - append:
+ field: related.hosts
+ tag: append_headers_x_authenticated_sender_domain_domain_into_related_hosts
+ value: '{{{sublime_security.email_message.headers.x_authenticated_sender.domain.domain}}}'
+ allow_duplicates: false
+ - rename:
+ field: json.headers.x_authenticated_sender.domain.punycode
+ tag: rename_headers_x_authenticated_sender_domain_punycode
+ target_field: sublime_security.email_message.headers.x_authenticated_sender.domain.punycode
+ ignore_missing: true
+ - rename:
+ field: json.headers.x_authenticated_sender.domain.root_domain
+ tag: rename_headers_x_authenticated_sender_domain_root_domain
+ target_field: sublime_security.email_message.headers.x_authenticated_sender.domain.root_domain
+ ignore_missing: true
+ - append:
+ field: related.hosts
+ tag: append_headers_x_authenticated_sender_domain_root_domain_into_related_hosts
+ value: '{{{sublime_security.email_message.headers.x_authenticated_sender.domain.root_domain}}}'
+ allow_duplicates: false
+ - rename:
+ field: json.headers.x_authenticated_sender.domain.sld
+ tag: rename_headers_x_authenticated_sender_domain_sld
+ target_field: sublime_security.email_message.headers.x_authenticated_sender.domain.sld
+ ignore_missing: true
+ - rename:
+ field: json.headers.x_authenticated_sender.domain.subdomain
+ tag: rename_headers_x_authenticated_sender_domain_subdomain
+ target_field: sublime_security.email_message.headers.x_authenticated_sender.domain.subdomain
+ ignore_missing: true
+ - rename:
+ field: json.headers.x_authenticated_sender.domain.tld
+ tag: rename_headers_x_authenticated_sender_domain_tld
+ target_field: sublime_security.email_message.headers.x_authenticated_sender.domain.tld
+ ignore_missing: true
+ - convert:
+ field: json.headers.x_authenticated_sender.domain.valid
+ tag: convert_headers_x_authenticated_sender_domain_valid_to_boolean
+ target_field: sublime_security.email_message.headers.x_authenticated_sender.domain.valid
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - rename:
+ field: json.headers.x_authenticated_sender.email
+ tag: rename_headers_x_authenticated_sender_email
+ target_field: sublime_security.email_message.headers.x_authenticated_sender.email
+ ignore_missing: true
+ - rename:
+ field: json.headers.x_authenticated_sender.local_part
+ tag: rename_headers_x_authenticated_sender_local_part
+ target_field: sublime_security.email_message.headers.x_authenticated_sender.local_part
+ ignore_missing: true
+ - convert:
+ field: json.headers.x_client_ip.ip
+ tag: convert_headers_x_client_ip_ip_to_ip
+ target_field: sublime_security.email_message.headers.x_client_ip.ip
+ type: ip
+ ignore_missing: true
+ if: ctx.json?.headers?.x_client_ip?.ip != null && ctx.json.headers.x_client_ip.ip != ''
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - set:
+ field: source.ip
+ tag: set_source_ip_from_headers_x_client_ip_ip
+ copy_from: sublime_security.email_message.headers.x_client_ip.ip
+ ignore_empty_value: true
+ - append:
+ field: related.ip
+ tag: append_headers_x_client_ip_ip_into_related_ip
+ value: '{{{sublime_security.email_message.headers.x_client_ip.ip}}}'
+ allow_duplicates: false
+ - convert:
+ field: json.headers.x_originating_ip.ip
+ tag: convert_headers_x_originating_ip_ip_to_ip
+ target_field: sublime_security.email_message.headers.x_originating_ip.ip
+ type: ip
+ ignore_missing: true
+ if: ctx.json?.headers?.x_originating_ip?.ip != null && ctx.json.headers.x_originating_ip.ip != ''
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - append:
+ field: related.ip
+ tag: append_headers_x_originating_ip_ip_into_related_ip
+ value: '{{{sublime_security.email_message.headers.x_originating_ip.ip}}}'
+ allow_duplicates: false
+ - rename:
+ field: json.headers.x_secure_server_account
+ tag: rename_headers_x_secure_server_account
+ target_field: sublime_security.email_message.headers.x_secure_server_account
+ ignore_missing: true
+ - rename:
+ field: json.headers.x_sender.domain.domain
+ tag: rename_headers_x_sender_domain_domain
+ target_field: sublime_security.email_message.headers.x_sender.domain.domain
+ ignore_missing: true
+ - append:
+ field: related.hosts
+ tag: append_headers_x_sender_domain_domain_into_related_hosts
+ value: '{{{sublime_security.email_message.headers.x_sender.domain.domain}}}'
+ allow_duplicates: false
+ - rename:
+ field: json.headers.x_sender.domain.punycode
+ tag: rename_headers_x_sender_domain_punycode
+ target_field: sublime_security.email_message.headers.x_sender.domain.punycode
+ ignore_missing: true
+ - rename:
+ field: json.headers.x_sender.domain.root_domain
+ tag: rename_headers_x_sender_domain_root_domain
+ target_field: sublime_security.email_message.headers.x_sender.domain.root_domain
+ ignore_missing: true
+ - append:
+ field: related.hosts
+ tag: append_headers_x_sender_domain_root_domain_into_related_hosts
+ value: '{{{sublime_security.email_message.headers.x_sender.domain.root_domain}}}'
+ allow_duplicates: false
+ - rename:
+ field: json.headers.x_sender.domain.sld
+ tag: rename_headers_x_sender_domain_sld
+ target_field: sublime_security.email_message.headers.x_sender.domain.sld
+ ignore_missing: true
+ - rename:
+ field: json.headers.x_sender.domain.subdomain
+ tag: rename_headers_x_sender_domain_subdomain
+ target_field: sublime_security.email_message.headers.x_sender.domain.subdomain
+ ignore_missing: true
+ - rename:
+ field: json.headers.x_sender.domain.tld
+ tag: rename_headers_x_sender_domain_tld
+ target_field: sublime_security.email_message.headers.x_sender.domain.tld
+ ignore_missing: true
+ - convert:
+ field: json.headers.x_sender.domain.valid
+ tag: convert_headers_x_sender_domain_valid_to_boolean
+ target_field: sublime_security.email_message.headers.x_sender.domain.valid
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - rename:
+ field: json.headers.x_sender.email
+ tag: rename_headers_x_sender_email
+ target_field: sublime_security.email_message.headers.x_sender.email
+ ignore_missing: true
+ - rename:
+ field: json.headers.x_sender.local_part
+ tag: rename_headers_x_sender_local_part
+ target_field: sublime_security.email_message.headers.x_sender.local_part
+ ignore_missing: true
+ - rename:
+ field: json.mailbox.display_name
+ tag: rename_mailbox_display_name
+ target_field: sublime_security.email_message.mailbox.display_name
+ ignore_missing: true
+ - rename:
+ field: json.mailbox.email.domain.domain
+ tag: rename_mailbox_email_domain_domain
+ target_field: sublime_security.email_message.mailbox.email.domain.domain
+ ignore_missing: true
+ - append:
+ field: related.hosts
+ tag: append_mailbox_email_domain_domain_into_related_hosts
+ value: '{{{sublime_security.email_message.mailbox.email.domain.domain}}}'
+ allow_duplicates: false
+ - rename:
+ field: json.mailbox.email.domain.punycode
+ tag: rename_mailbox_email_domain_punycode
+ target_field: sublime_security.email_message.mailbox.email.domain.punycode
+ ignore_missing: true
+ - rename:
+ field: json.mailbox.email.domain.root_domain
+ tag: rename_mailbox_email_domain_root_domain
+ target_field: sublime_security.email_message.mailbox.email.domain.root_domain
+ ignore_missing: true
+ - append:
+ field: related.hosts
+ tag: append_mailbox_email_domain_root_domain_into_related_hosts
+ value: '{{{sublime_security.email_message.mailbox.email.domain.root_domain}}}'
+ allow_duplicates: false
+ - rename:
+ field: json.mailbox.email.domain.sld
+ tag: rename_mailbox_email_domain_sld
+ target_field: sublime_security.email_message.mailbox.email.domain.sld
+ ignore_missing: true
+ - rename:
+ field: json.mailbox.email.domain.subdomain
+ tag: rename_mailbox_email_domain_subdomain
+ target_field: sublime_security.email_message.mailbox.email.domain.subdomain
+ ignore_missing: true
+ - rename:
+ field: json.mailbox.email.domain.tld
+ tag: rename_mailbox_email_domain_tld
+ target_field: sublime_security.email_message.mailbox.email.domain.tld
+ ignore_missing: true
+ - convert:
+ field: json.mailbox.email.domain.valid
+ tag: convert_mailbox_email_domain_valid_to_boolean
+ target_field: sublime_security.email_message.mailbox.email.domain.valid
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - rename:
+ field: json.mailbox.email.email
+ tag: rename_mailbox_email_email
+ target_field: sublime_security.email_message.mailbox.email.value
+ ignore_missing: true
+ - append:
+ field: related.user
+ tag: append_mailbox_email_value_into_related_user
+ value: '{{{sublime_security.email_message.mailbox.email.value}}}'
+ allow_duplicates: false
+ - rename:
+ field: json.mailbox.email.local_part
+ tag: rename_mailbox_email_local_part
+ target_field: sublime_security.email_message.mailbox.email.local_part
+ ignore_missing: true
+ - rename:
+ field: json._meta.canonical_id
+ tag: rename_meta_canonical_id
+ target_field: sublime_security.email_message.meta.canonical_id
+ ignore_missing: true
+ - date:
+ field: json._meta.created_at
+ tag: date_meta_created_at
+ target_field: sublime_security.email_message.meta.created_at
+ formats:
+ - ISO8601
+ if: ctx.json?._meta?.created_at != null && ctx.json._meta.created_at != ''
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - set:
+ field: '@timestamp'
+ tag: set_@timestamp_from_email_message_meta_created_at
+ copy_from: sublime_security.email_message.meta.created_at
+ ignore_empty_value: true
+ - date:
+ field: json._meta.effective_at
+ tag: date_meta_effective_at
+ target_field: sublime_security.email_message.meta.effective_at
+ formats:
+ - ISO8601
+ if: ctx.json?._meta?.effective_at != null && ctx.json._meta.effective_at != ''
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - rename:
+ field: json._meta.id
+ tag: rename_meta_id
+ target_field: sublime_security.email_message.meta.id
+ ignore_missing: true
+ - set:
+ field: event.id
+ tag: set_event_id_from_meta_id
+ copy_from: sublime_security.email_message.meta.id
+ ignore_empty_value: true
+ - foreach:
+ field: json.recipients.bcc
+ if: ctx.json?.recipients?.bcc instanceof List
+ processor:
+ append:
+ field: related.hosts
+ tag: append_recipients_bcc_email_domain_domain_into_related_hosts
+ value: '{{{_ingest._value.email.domain.domain}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.recipients.bcc
+ if: ctx.json?.recipients?.bcc instanceof List
+ processor:
+ append:
+ field: related.hosts
+ tag: append_recipients_bcc_email_domain_root_domain_into_related_hosts
+ value: '{{{_ingest._value.email.domain.root_domain}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.recipients.bcc
+ if: ctx.json?.recipients?.bcc instanceof List
+ processor:
+ convert:
+ field: _ingest._value.email.domain.valid
+ tag: convert_recipients_bcc_email_domain_valid_to_boolean
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - remove:
+ field: _ingest._value.email.domain.valid
+ ignore_missing: true
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - foreach:
+ field: json.recipients.bcc
+ if: ctx.json?.recipients?.bcc instanceof List
+ processor:
+ append:
+ field: email.bcc.address
+ tag: append_recipients_bcc_email_email_into_email_bcc_address
+ value: '{{{_ingest._value.email.email}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.recipients.bcc
+ if: ctx.json?.recipients?.bcc instanceof List
+ processor:
+ append:
+ field: related.user
+ tag: append_recipients_bcc_email_email_into_related_user
+ value: '{{{_ingest._value.email.email}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.recipients.bcc
+ if: ctx.json?.recipients?.bcc instanceof List
+ processor:
+ rename:
+ field: _ingest._value.email.email
+ tag: rename_recipients_bcc_email_email_to_value
+ target_field: _ingest._value.email.value
+ ignore_missing: true
+ - rename:
+ field: json.recipients.bcc
+ tag: rename_recipients_bcc
+ target_field: sublime_security.email_message.recipients.bcc
+ ignore_missing: true
+ - foreach:
+ field: json.recipients.cc
+ if: ctx.json?.recipients?.cc instanceof List
+ processor:
+ append:
+ field: related.hosts
+ tag: append_recipients_cc_email_domain_domain_into_related_hosts
+ value: '{{{_ingest._value.email.domain.domain}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.recipients.cc
+ if: ctx.json?.recipients?.cc instanceof List
+ processor:
+ append:
+ field: related.hosts
+ tag: append_recipients_cc_email_domain_root_domain_into_related_hosts
+ value: '{{{_ingest._value.email.domain.root_domain}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.recipients.cc
+ if: ctx.json?.recipients?.cc instanceof List
+ processor:
+ convert:
+ field: _ingest._value.email.domain.valid
+ tag: convert_recipients_cc_email_domain_valid_to_boolean
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - remove:
+ field: _ingest._value.email.domain.valid
+ ignore_missing: true
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - foreach:
+ field: json.recipients.cc
+ if: ctx.json?.recipients?.cc instanceof List
+ processor:
+ append:
+ field: email.cc.address
+ tag: append_recipients_cc_email_email_into_email_cc_address
+ value: '{{{_ingest._value.email.email}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.recipients.cc
+ if: ctx.json?.recipients?.cc instanceof List
+ processor:
+ append:
+ field: related.user
+ tag: append_recipients_cc_email_email_into_related_user
+ value: '{{{_ingest._value.email.email}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.recipients.cc
+ if: ctx.json?.recipients?.cc instanceof List
+ processor:
+ rename:
+ field: _ingest._value.email.email
+ tag: rename_recipients_cc_email_email_to_value
+ target_field: _ingest._value.email.value
+ ignore_missing: true
+ - rename:
+ field: json.recipients.cc
+ tag: rename_recipients_cc
+ target_field: sublime_security.email_message.recipients.cc
+ ignore_missing: true
+ - foreach:
+ field: json.recipients.to
+ if: ctx.json?.recipients?.to instanceof List
+ processor:
+ append:
+ field: related.hosts
+ tag: append_recipients_to_email_domain_domain_into_related_hosts
+ value: '{{{_ingest._value.email.domain.domain}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.recipients.to
+ if: ctx.json?.recipients?.to instanceof List
+ processor:
+ append:
+ field: related.hosts
+ tag: append_recipients_to_email_domain_root_domain_into_related_hosts
+ value: '{{{_ingest._value.email.domain.root_domain}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.recipients.to
+ if: ctx.json?.recipients?.to instanceof List
+ processor:
+ convert:
+ field: _ingest._value.email.domain.valid
+ tag: convert_recipients_to_email_domain_valid_to_boolean
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - remove:
+ field: _ingest._value.email.domain.valid
+ ignore_missing: true
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - foreach:
+ field: json.recipients.to
+ if: ctx.json?.recipients?.to instanceof List
+ processor:
+ append:
+ field: email.to.address
+ tag: append_recipients_to_email_email_into_email_to_address
+ value: '{{{_ingest._value.email.email}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.recipients.to
+ if: ctx.json?.recipients?.to instanceof List
+ processor:
+ append:
+ field: related.user
+ tag: append_recipients_to_email_email_into_related_user
+ value: '{{{_ingest._value.email.email}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.recipients.to
+ if: ctx.json?.recipients?.to instanceof List
+ processor:
+ rename:
+ field: _ingest._value.email.email
+ tag: rename_recipients_to_email_email_to_value
+ target_field: _ingest._value.email.value
+ ignore_missing: true
+ - rename:
+ field: json.recipients.to
+ tag: rename_recipients_to
+ target_field: sublime_security.email_message.recipients.to
+ ignore_missing: true
+ - rename:
+ field: json.sender.display_name
+ tag: rename_sender_display_name
+ target_field: sublime_security.email_message.sender.display_name
+ ignore_missing: true
+ - rename:
+ field: json.sender.email.domain.domain
+ tag: rename_sender_email_domain_domain
+ target_field: sublime_security.email_message.sender.email.domain.domain
+ ignore_missing: true
+ - append:
+ field: related.hosts
+ tag: append_sender_email_domain_domain_into_related_hosts
+ value: '{{{sublime_security.email_message.sender.email.domain.domain}}}'
+ allow_duplicates: false
+ - set:
+ field: source.domain
+ tag: set_source_domain_from_sender_email_domain_domain
+ copy_from: sublime_security.email_message.sender.email.domain.domain
+ ignore_empty_value: true
+ - rename:
+ field: json.sender.email.domain.punycode
+ tag: rename_sender_email_domain_punycode
+ target_field: sublime_security.email_message.sender.email.domain.punycode
+ ignore_missing: true
+ - rename:
+ field: json.sender.email.domain.root_domain
+ tag: rename_sender_email_domain_root_domain
+ target_field: sublime_security.email_message.sender.email.domain.root_domain
+ ignore_missing: true
+ - append:
+ field: related.hosts
+ tag: append_sender_email_domain_root_domain_into_related_hosts
+ value: '{{{sublime_security.email_message.sender.email.domain.root_domain}}}'
+ allow_duplicates: false
+ - rename:
+ field: json.sender.email.domain.sld
+ tag: rename_sender_email_domain_sld
+ target_field: sublime_security.email_message.sender.email.domain.sld
+ ignore_missing: true
+ - rename:
+ field: json.sender.email.domain.subdomain
+ tag: rename_sender_email_domain_subdomain
+ target_field: sublime_security.email_message.sender.email.domain.subdomain
+ ignore_missing: true
+ - set:
+ field: source.subdomain
+ tag: set_source_subdomain_from_sender_email_domain_subdomain
+ copy_from: sublime_security.email_message.sender.email.domain.subdomain
+ ignore_empty_value: true
+ - rename:
+ field: json.sender.email.domain.tld
+ tag: rename_sender_email_domain_tld
+ target_field: sublime_security.email_message.sender.email.domain.tld
+ ignore_missing: true
+ - set:
+ field: source.top_level_domain
+ tag: set_source_top_level_domain_from_sender_email_domain_tld
+ copy_from: sublime_security.email_message.sender.email.domain.tld
+ ignore_empty_value: true
+ - convert:
+ field: json.sender.email.domain.valid
+ tag: convert_sender_email_domain_valid_to_boolean
+ target_field: sublime_security.email_message.sender.email.domain.valid
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - rename:
+ field: json.sender.email.email
+ tag: rename_sender_email_email
+ target_field: sublime_security.email_message.sender.email.value
+ ignore_missing: true
+ - append:
+ field: email.from.address
+ tag: append_sublime_security_email_message_sender_email_value_into_email_from_address
+ value: '{{{sublime_security.email_message.sender.email.value}}}'
+ allow_duplicates: false
+ if: ctx.sublime_security?.email_message?.sender?.email?.value != null
+ - append:
+ field: related.user
+ tag: append_sender_email_value_into_related_user
+ value: '{{{sublime_security.email_message.sender.email.value}}}'
+ allow_duplicates: false
+ - rename:
+ field: json.sender.email.local_part
+ tag: rename_sender_email_local_part
+ target_field: sublime_security.email_message.sender.email.local_part
+ ignore_missing: true
+ - rename:
+ field: json.subject.subject
+ tag: rename_subject_subject
+ target_field: sublime_security.email_message.subject.subject
+ ignore_missing: true
+ - set:
+ field: email.subject
+ tag: set_email_subject_from_email_message_subject_subject
+ copy_from: sublime_security.email_message.subject.subject
+ ignore_empty_value: true
+ - convert:
+ field: json.type.inbound
+ tag: convert_type_inbound_to_boolean
+ target_field: sublime_security.email_message.type.inbound
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - set:
+ field: email.direction
+ tag: set_email_direction_inbound_from_type_inbound
+ value: inbound
+ if: ctx.sublime_security?.email_message?.type?.inbound == true
+ ignore_empty_value: true
+ - convert:
+ field: json.type.internal
+ tag: convert_type_internal_to_boolean
+ target_field: sublime_security.email_message.type.internal
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - set:
+ field: email.direction
+ tag: set_email_direction_internal_from_type_internal
+ value: internal
+ if: ctx.sublime_security?.email_message?.type?.internal == true
+ ignore_empty_value: true
+ - convert:
+ field: json.type.outbound
+ tag: convert_type_outbound_to_boolean
+ target_field: sublime_security.email_message.type.outbound
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - set:
+ field: email.direction
+ tag: set_email_direction_outbound_from_type_outbound
+ value: outbound
+ if: ctx.sublime_security?.email_message?.type?.outbound == true
+ ignore_empty_value: true
+ - foreach:
+ field: sublime_security.email_message.attachments
+ if: ctx.sublime_security?.email_message?.attachments instanceof List
+ processor:
+ remove:
+ field:
+ - _ingest._value.content.type
+ - _ingest._value.file.extension
+ - _ingest._value.file.name
+ - _ingest._value.md5
+ - _ingest._value.sha1
+ - _ingest._value.sha256
+ - _ingest._value.size
+ tag: remove_custom_duplicate_fields_from_sublime_security_email_message_attachments
+ ignore_missing: true
+ if: ctx.tags == null || !(ctx.tags.contains('preserve_duplicate_custom_fields'))
+ - foreach:
+ field: sublime_security.email_message.body.links
+ if: ctx.sublime_security?.email_message?.body?.links instanceof List
+ processor:
+ remove:
+ field:
+ - _ingest._value.href_url.domain.domain
+ - _ingest._value.href_url.domain.subdomain
+ - _ingest._value.href_url.domain.tld
+ - _ingest._value.href_url.fragment
+ - _ingest._value.href_url.password
+ - _ingest._value.href_url.path
+ - _ingest._value.href_url.port
+ - _ingest._value.href_url.query_params
+ - _ingest._value.href_url.scheme
+ - _ingest._value.href_url.url
+ - _ingest._value.href_url.username
+ tag: remove_custom_duplicate_fields_from_sublime_security_email_message_body_links
+ ignore_missing: true
+ if: ctx.tags == null || !(ctx.tags.contains('preserve_duplicate_custom_fields'))
+ - foreach:
+ field: sublime_security.email_message.headers.reply_to
+ if: ctx.sublime_security?.email_message?.headers?.reply_to instanceof List
+ processor:
+ remove:
+ field: _ingest._value.email.value
+ tag: remove_custom_duplicate_fields_from_sublime_security_email_message_headers_reply_to
+ ignore_missing: true
+ if: ctx.tags == null || !(ctx.tags.contains('preserve_duplicate_custom_fields'))
+ - foreach:
+ field: sublime_security.email_message.recipients.bcc
+ if: ctx.sublime_security?.email_message?.recipients?.bcc instanceof List
+ processor:
+ remove:
+ field: _ingest._value.email.value
+ tag: remove_custom_duplicate_fields_from_sublime_security_email_message_recipients_bcc
+ ignore_missing: true
+ if: ctx.tags == null || !(ctx.tags.contains('preserve_duplicate_custom_fields'))
+ - foreach:
+ field: sublime_security.email_message.recipients.cc
+ if: ctx.sublime_security?.email_message?.recipients?.cc instanceof List
+ processor:
+ remove:
+ field: _ingest._value.email.value
+ tag: remove_custom_duplicate_fields_from_sublime_security_email_message_recipients_cc
+ ignore_missing: true
+ if: ctx.tags == null || !(ctx.tags.contains('preserve_duplicate_custom_fields'))
+ - foreach:
+ field: sublime_security.email_message.recipients.to
+ if: ctx.sublime_security?.email_message?.recipients?.to instanceof List
+ processor:
+ remove:
+ field: _ingest._value.email.value
+ tag: remove_custom_duplicate_fields_from_sublime_security_email_message_recipients_to
+ ignore_missing: true
+ if: ctx.tags == null || !(ctx.tags.contains('preserve_duplicate_custom_fields'))
+ - remove:
+ field:
+ - sublime_security.email_message.external.created_at
+ - sublime_security.email_message.headers.delivered_to.domain.domain
+ - sublime_security.email_message.headers.delivered_to.domain.subdomain
+ - sublime_security.email_message.headers.delivered_to.domain.tld
+ - sublime_security.email_message.headers.mailer
+ - sublime_security.email_message.headers.message_id
+ - sublime_security.email_message.headers.x_client_ip.ip
+ - sublime_security.email_message.meta.created_at
+ - sublime_security.email_message.meta.id
+ - sublime_security.email_message.sender.email.domain.domain
+ - sublime_security.email_message.sender.email.domain.subdomain
+ - sublime_security.email_message.sender.email.domain.tld
+ - sublime_security.email_message.sender.email.value
+ - sublime_security.email_message.subject.subject
+ tag: remove_custom_duplicate_fields
+ ignore_missing: true
+ if: ctx.tags == null || !(ctx.tags.contains('preserve_duplicate_custom_fields'))
+ - remove:
+ field: json
+ tag: remove_json
+ ignore_missing: true
+ - script:
+ lang: painless
+ description: Drops null/empty values recursively.
+ tag: painless_remove_null
+ source: |-
+ boolean drop(Object object) {
+ if (object == null || object == '') {
+ return true;
+ } else if (object instanceof Map) {
+ ((Map) object).values().removeIf(v -> drop(v));
+ return (((Map) object).size() == 0);
+ } else if (object instanceof List) {
+ ((List) object).removeIf(v -> drop(v));
+ return (((List) object).length == 0);
+ }
+ return false;
+ }
+ drop(ctx);
+ - set:
+ field: event.kind
+ value: pipeline_error
+ tag: set_pipeline_error_into_event_kind
+ if: ctx.error?.message != null
+on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - set:
+ field: event.kind
+ tag: set_pipeline_error_to_event_kind
+ value: pipeline_error
diff --git a/packages/sublime_security/data_stream/email_message/fields/base-fields.yml b/packages/sublime_security/data_stream/email_message/fields/base-fields.yml
new file mode 100644
index 00000000000..97435bd3ccc
--- /dev/null
+++ b/packages/sublime_security/data_stream/email_message/fields/base-fields.yml
@@ -0,0 +1,20 @@
+- name: data_stream.type
+ type: constant_keyword
+ description: Data stream type.
+- name: data_stream.dataset
+ type: constant_keyword
+ description: Data stream dataset.
+- name: data_stream.namespace
+ type: constant_keyword
+ description: Data stream namespace.
+- name: event.module
+ type: constant_keyword
+ description: Event module.
+ value: sublime_security
+- name: event.dataset
+ type: constant_keyword
+ description: Event dataset.
+ value: sublime_security.email_message
+- name: '@timestamp'
+ type: date
+ description: Event timestamp.
diff --git a/packages/sublime_security/data_stream/email_message/fields/beats.yml b/packages/sublime_security/data_stream/email_message/fields/beats.yml
new file mode 100644
index 00000000000..fff1b3f1b6b
--- /dev/null
+++ b/packages/sublime_security/data_stream/email_message/fields/beats.yml
@@ -0,0 +1,24 @@
+- name: input.type
+ type: keyword
+ description: Type of filebeat input.
+- name: log.offset
+ type: long
+ description: Log offset.
+- name: aws.s3
+ type: group
+ fields:
+ - name: bucket
+ type: group
+ fields:
+ - name: name
+ type: keyword
+ description: The AWS S3 bucket name.
+ - name: arn
+ type: keyword
+ description: The AWS S3 bucket ARN.
+ - name: object
+ type: group
+ fields:
+ - name: key
+ type: keyword
+ description: The AWS S3 Object key.
diff --git a/packages/sublime_security/data_stream/email_message/fields/fields.yml b/packages/sublime_security/data_stream/email_message/fields/fields.yml
new file mode 100644
index 00000000000..ebd5e6a90f5
--- /dev/null
+++ b/packages/sublime_security/data_stream/email_message/fields/fields.yml
@@ -0,0 +1,1222 @@
+- name: sublime_security
+ type: group
+ fields:
+ - name: email_message
+ type: group
+ fields:
+ - name: attachments
+ type: group
+ fields:
+ - name: content
+ type: group
+ fields:
+ - name: id
+ type: keyword
+ description: Content-ID extracted from the MIME payload.
+ - name: transfer_encoding
+ type: keyword
+ description: Content-Transfer-Encoding extracted from the MIME payload.
+ - name: type
+ type: keyword
+ description: Content-Type extracted from the MIME payload.
+ - name: file
+ type: group
+ fields:
+ - name: extension
+ type: keyword
+ description: File extension from context such as headers.
+ - name: name
+ type: keyword
+ description: File name.
+ - name: type
+ type: keyword
+ description: File type determined by looking at the magic bytes in the file.
+ - name: md5
+ type: keyword
+ description: MD5 hash of the raw contents.
+ - name: raw
+ type: keyword
+ description: Base64 encoded source of the file.
+ - name: sha1
+ type: keyword
+ description: SHA1 hash of the raw contents.
+ - name: sha256
+ type: keyword
+ description: SHA256 hash of the raw contents.
+ - name: size
+ type: long
+ description: Size of the file in bytes.
+ - name: body
+ type: group
+ fields:
+ - name: current_thread
+ type: group
+ fields:
+ - name: text
+ type: keyword
+ description: The text content from the latest reply/forward in a message thread. This typically excludes content from forwarded messages and warning banners.
+ - name: html
+ type: group
+ fields:
+ - name: charset
+ type: keyword
+ description: charset of the text/[subtype].
+ - name: content_transfer_encoding
+ type: keyword
+ description: Content-Transfer-Encoding of the text/[subtype].
+ - name: display_text
+ type: keyword
+ description: Visible text of the HTML document, with invisible characters removed and non-ASCII characters converted to ASCII spaces.
+ - name: inner_text
+ type: keyword
+ description: Inner text of the HTML document that doesn't include HTML tags.
+ - name: raw
+ type: keyword
+ description: Decoded raw content of a body text type (text/[subtype] section).
+ - name: ips
+ type: group
+ fields:
+ - name: ip
+ type: ip
+ description: The raw IP.
+ - name: links
+ type: group
+ fields:
+ - name: display_text
+ type: keyword
+ description: The text of a hyperlink, if it's not a URL.
+ - name: display_url
+ type: group
+ fields:
+ - name: domain
+ type: group
+ fields:
+ - name: domain
+ type: keyword
+ description: The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar.
+ - name: punycode
+ type: keyword
+ description: Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com.
+ - name: root_domain
+ type: keyword
+ description: The root domain, including the TLD.
+ - name: sld
+ type: keyword
+ description: Second-level domain, e.g. 'windows' for the domain 'windows.net'.
+ - name: subdomain
+ type: keyword
+ description: Subdomain, e.g. 'drive' for the domain 'drive.google.com'.
+ - name: tld
+ type: keyword
+ description: The domain's top-level domain. E.g. the TLD of google.com is 'com'.
+ - name: valid
+ type: boolean
+ description: Whether the domain is valid.
+ - name: fragment
+ type: keyword
+ description: 'Fragment identifier; the text following the # in the href_url (also called the anchor tag).'
+ - name: password
+ type: keyword
+ description: The password specified before the domain name.
+ - name: path
+ type: keyword
+ description: Everything after the TLD and before the query parameters.
+ - name: port
+ type: long
+ description: The port used for the href_url. If no explicit port is set, the port will be inferred from the protocol.
+ - name: query_params
+ type: keyword
+ description: The query parameters of the href_url.
+ - name: rewrite
+ type: group
+ fields:
+ - name: encoders
+ type: keyword
+ description: List of detected URL rewrite encoders while unraveling the URL.
+ - name: original
+ type: keyword
+ description: Original URL without any unraveling URL rewrites.
+ - name: scheme
+ type: keyword
+ description: Protocol for the href_url request, e.g. http.
+ - name: url
+ type: keyword
+ description: Full URL.
+ - name: username
+ type: keyword
+ description: The username specified before the domain name of the href_url.
+ - name: href_url
+ type: group
+ fields:
+ - name: domain
+ type: group
+ fields:
+ - name: domain
+ type: keyword
+ description: The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar.
+ - name: punycode
+ type: keyword
+ description: Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com.
+ - name: root_domain
+ type: keyword
+ description: The root domain, including the TLD.
+ - name: sld
+ type: keyword
+ description: Second-level domain, e.g. 'windows' for the domain 'windows.net'.
+ - name: subdomain
+ type: keyword
+ description: Subdomain, e.g. 'drive' for the domain 'drive.google.com'.
+ - name: tld
+ type: keyword
+ description: The domain's top-level domain. E.g. the TLD of google.com is 'com'.
+ - name: valid
+ type: boolean
+ description: Whether the domain is valid.
+ - name: fragment
+ type: keyword
+ description: 'Fragment identifier; the text following the # in the href_url (also called the anchor tag).'
+ - name: password
+ type: keyword
+ description: The password specified before the domain name.
+ - name: path
+ type: keyword
+ description: Everything after the TLD and before the query parameters.
+ - name: port
+ type: long
+ description: The port used for the href_url. If no explicit port is set, the port will be inferred from the protocol.
+ - name: query_params
+ type: keyword
+ description: The query parameters of the href_url.
+ - name: rewrite
+ type: group
+ fields:
+ - name: encoders
+ type: keyword
+ description: List of detected URL rewrite encoders while unraveling the URL.
+ - name: original
+ type: keyword
+ description: Original URL without any unraveling URL rewrites.
+ - name: scheme
+ type: keyword
+ description: Protocol for the href_url request, e.g. http.
+ - name: url
+ type: keyword
+ description: Full URL.
+ - name: username
+ type: keyword
+ description: The username specified before the domain name of the href_url.
+ - name: mismatched
+ type: boolean
+ description: Whether the display URL and href URL root domains are mismatched (i.e. .href_url.domain.root_domain != .display_url.domain.root_domain, where both are not null and valid domains).
+ - name: plain
+ type: group
+ fields:
+ - name: charset
+ type: keyword
+ description: charset of the text/[subtype].
+ - name: content_transfer_encoding
+ type: keyword
+ description: Content-Transfer-Encoding of the text/[subtype].
+ - name: raw
+ type: keyword
+ description: Decoded raw content of a body text type (text/[subtype] section).
+ - name: errors
+ type: object
+ object_type: keyword
+ description: Non-fatal errors while parsing MDM.
+ - name: external
+ type: group
+ fields:
+ - name: created_at
+ type: date
+ description: The created time of the message as provided by the cloud API (G Suite or Office 365) or other external source. This is typically the time the external source received the message.
+ - name: message_id
+ type: keyword
+ description: The message ID as provided by the cloud API (G Suite or Office 365) or other external source.
+ - name: route_type
+ type: keyword
+ description: whether the message was sent or received.
+ - name: spam
+ type: boolean
+ description: The upstream mail gateway determined the message to be spam. For cloud API providers, this will be the same as spam_folder. For other implementation methods like transport rules, this will be determined by message header values (e.g. X-SPAM) if supported.
+ - name: spam_folder
+ type: boolean
+ description: The message arrived in the user's spam folder. This only applies to cloud APIs (G Suite or Office 365).
+ - name: thread_id
+ type: keyword
+ description: The thread/conversation's unique ID as provided by the cloud API (G Suite or Office 365).
+ - name: headers
+ type: group
+ fields:
+ - name: auth_summary
+ type: group
+ fields:
+ - name: dmarc
+ type: group
+ fields:
+ - name: details
+ type: group
+ fields:
+ - name: action
+ type: keyword
+ description: Indicates the action taken by the spam filter based on the results of the DMARC check. For more information see https://docs.microsoft.com/en-us/microsoft-365/security/office-365-security/anti-spam-message-headers?view=o365-worldwide#authentication-results-message-header-fields.
+ - name: disposition
+ type: keyword
+ description: Gmail-applied policy.
+ - name: from
+ type: group
+ fields:
+ - name: domain
+ type: keyword
+ description: The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar.
+ - name: punycode
+ type: keyword
+ description: Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com.
+ - name: root_domain
+ type: keyword
+ description: The root domain, including the TLD.
+ - name: sld
+ type: keyword
+ description: Second-level domain, e.g. 'windows' for the domain 'windows.net'.
+ - name: subdomain
+ type: keyword
+ description: Subdomain, e.g. 'drive' for the domain 'drive.google.com'.
+ - name: tld
+ type: keyword
+ description: The domain's top-level domain. E.g. the TLD of google.com is 'com'.
+ - name: valid
+ type: boolean
+ description: Whether the domain is valid.
+ - name: policy
+ type: keyword
+ description: Policy for the organizational domain.
+ - name: sub_policy
+ type: keyword
+ description: Policy for the subdomain of the organizational domain.
+ - name: verdict
+ type: keyword
+ description: Describes the results of the DMARC check for the message.
+ - name: version
+ type: keyword
+ description: DMARC version.
+ - name: pass
+ type: boolean
+ description: Whether the DMARC check passed.
+ - name: received_hop
+ type: long
+ description: The lowest hop at which the DMARC check was made.
+ - name: spf
+ type: group
+ fields:
+ - name: details
+ type: group
+ fields:
+ - name: client_ip
+ type: group
+ fields:
+ - name: ip
+ type: ip
+ description: The raw IP.
+ - name: description
+ type: keyword
+ description: Verbose description of the SPF verdict.
+ - name: designator
+ type: keyword
+ description: Email or domain of the designating body.
+ - name: helo
+ type: group
+ fields:
+ - name: domain
+ type: keyword
+ description: The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar.
+ - name: punycode
+ type: keyword
+ description: Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com.
+ - name: root_domain
+ type: keyword
+ description: The root domain, including the TLD.
+ - name: sld
+ type: keyword
+ description: Second-level domain, e.g. 'windows' for the domain 'windows.net'.
+ - name: subdomain
+ type: keyword
+ description: Subdomain, e.g. 'drive' for the domain 'drive.google.com'.
+ - name: tld
+ type: keyword
+ description: The domain's top-level domain. E.g. the TLD of google.com is 'com'.
+ - name: valid
+ type: boolean
+ description: Whether the domain is valid.
+ - name: server
+ type: group
+ fields:
+ - name: domain
+ type: keyword
+ description: The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar.
+ - name: punycode
+ type: keyword
+ description: Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com.
+ - name: root_domain
+ type: keyword
+ description: The root domain, including the TLD.
+ - name: sld
+ type: keyword
+ description: Second-level domain, e.g. 'windows' for the domain 'windows.net'.
+ - name: subdomain
+ type: keyword
+ description: Subdomain, e.g. 'drive' for the domain 'drive.google.com'.
+ - name: tld
+ type: keyword
+ description: The domain's top-level domain. E.g. the TLD of google.com is 'com'.
+ - name: valid
+ type: boolean
+ description: Whether the domain is valid.
+ - name: verdict
+ type: keyword
+ description: Verdict of the SPF.
+ - name: error
+ type: boolean
+ description: Whether the SPF check errored.
+ - name: pass
+ type: boolean
+ description: Whether the SPF check passed.
+ - name: received_hop
+ type: long
+ description: The lowest hop at which the SPF check was made.
+ - name: date
+ type: date
+ description: Date the email was sent in UTC.
+ - name: date_original_offset
+ type: keyword
+ description: UTC timezone offset of the sender.
+ - name: delivered_to
+ type: group
+ fields:
+ - name: domain
+ type: group
+ fields:
+ - name: domain
+ type: keyword
+ description: The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar.
+ - name: punycode
+ type: keyword
+ description: Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com.
+ - name: root_domain
+ type: keyword
+ description: The root domain, including the TLD.
+ - name: sld
+ type: keyword
+ description: Second-level domain, e.g. 'windows' for the domain 'windows.net'.
+ - name: subdomain
+ type: keyword
+ description: Subdomain, e.g. 'drive' for the domain 'drive.google.com'.
+ - name: tld
+ type: keyword
+ description: The domain's top-level domain. E.g. the TLD of google.com is 'com'.
+ - name: valid
+ type: boolean
+ description: Whether the domain is valid.
+ - name: email
+ type: keyword
+ description: Full email address.
+ - name: local_part
+ type: keyword
+ description: Local-part, i.e. before the @.
+ - name: domains
+ type: group
+ fields:
+ - name: domain
+ type: keyword
+ description: The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar.
+ - name: punycode
+ type: keyword
+ description: Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com.
+ - name: root_domain
+ type: keyword
+ description: The root domain, including the TLD.
+ - name: sld
+ type: keyword
+ description: Second-level domain, e.g. 'windows' for the domain 'windows.net'.
+ - name: subdomain
+ type: keyword
+ description: Subdomain, e.g. 'drive' for the domain 'drive.google.com'.
+ - name: tld
+ type: keyword
+ description: The domain's top-level domain. E.g. the TLD of google.com is 'com'.
+ - name: valid
+ type: boolean
+ description: Whether the domain is valid.
+ - name: hops
+ type: group
+ fields:
+ - name: authentication_results
+ type: group
+ fields:
+ - name: compauth
+ type: group
+ fields:
+ - name: reason
+ type: keyword
+ description: Reason for the verdict.
+ - name: verdict
+ type: keyword
+ description: Verdict of the compauth.
+ - name: dkim
+ type: keyword
+ description: Verdict of the Domain Keys Identified Mail check.
+ - name: dkim_details
+ type: group
+ fields:
+ - name: algorithm
+ type: keyword
+ description: Signing algorithm.
+ - name: body_hash
+ type: keyword
+ description: Body Hash.
+ - name: domain
+ type: keyword
+ description: Domain identified in the DKIM signature if any. This is the domain that's queried for the public key.
+ - name: headers
+ type: keyword
+ description: Header fields signed by the algorithm.
+ - name: instance
+ type: keyword
+ description: Instance number of this signature (if ARC).
+ - name: selector
+ type: keyword
+ description: Selector.
+ - name: signature
+ type: keyword
+ description: Signature of headers and body.
+ - name: type
+ type: keyword
+ description: The type of signature, derived from the field name.
+ - name: version
+ type: keyword
+ description: Version.
+ - name: dmarc
+ type: keyword
+ description: Verdict of the Domain-based Message Authentication, Reporting & Conformance check.
+ - name: dmarc_details
+ type: group
+ fields:
+ - name: action
+ type: keyword
+ description: Indicates the action taken by the spam filter based on the results of the DMARC check. For more information see https://docs.microsoft.com/en-us/microsoft-365/security/office-365-security/anti-spam-message-headers?view=o365-worldwide#authentication-results-message-header-fields.
+ - name: disposition
+ type: keyword
+ description: Gmail-applied policy.
+ - name: from
+ type: group
+ fields:
+ - name: domain
+ type: keyword
+ description: The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar.
+ - name: punycode
+ type: keyword
+ description: Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com.
+ - name: root_domain
+ type: keyword
+ description: The root domain, including the TLD.
+ - name: sld
+ type: keyword
+ description: Second-level domain, e.g. 'windows' for the domain 'windows.net'.
+ - name: subdomain
+ type: keyword
+ description: Subdomain, e.g. 'drive' for the domain 'drive.google.com'.
+ - name: tld
+ type: keyword
+ description: The domain's top-level domain. E.g. the TLD of google.com is 'com'.
+ - name: valid
+ type: boolean
+ description: Whether the domain is valid.
+ - name: policy
+ type: keyword
+ description: Policy for the organizational domain.
+ - name: sub_policy
+ type: keyword
+ description: Policy for the subdomain of the organizational domain.
+ - name: verdict
+ type: keyword
+ description: Describes the results of the DMARC check for the message.
+ - name: version
+ type: keyword
+ description: DMARC version.
+ - name: instance
+ type: keyword
+ description: Instance number of this auth result (if ARC).
+ - name: server
+ type: group
+ fields:
+ - name: domain
+ type: keyword
+ description: The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar.
+ - name: punycode
+ type: keyword
+ description: Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com.
+ - name: root_domain
+ type: keyword
+ description: The root domain, including the TLD.
+ - name: sld
+ type: keyword
+ description: Second-level domain, e.g. 'windows' for the domain 'windows.net'.
+ - name: subdomain
+ type: keyword
+ description: Subdomain, e.g. 'drive' for the domain 'drive.google.com'.
+ - name: tld
+ type: keyword
+ description: The domain's top-level domain. E.g. the TLD of google.com is 'com'.
+ - name: valid
+ type: boolean
+ description: Whether the domain is valid.
+ - name: spf
+ type: keyword
+ description: Verdict of the Sender Policy Framework.
+ - name: spf_details
+ type: group
+ fields:
+ - name: client_ip
+ type: group
+ fields:
+ - name: ip
+ type: ip
+ description: The raw IP.
+ - name: description
+ type: keyword
+ description: Verbose description of the SPF verdict.
+ - name: designator
+ type: keyword
+ description: Email or domain of the designating body.
+ - name: helo
+ type: group
+ fields:
+ - name: domain
+ type: keyword
+ description: The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar.
+ - name: punycode
+ type: keyword
+ description: Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com.
+ - name: root_domain
+ type: keyword
+ description: The root domain, including the TLD.
+ - name: sld
+ type: keyword
+ description: Second-level domain, e.g. 'windows' for the domain 'windows.net'.
+ - name: subdomain
+ type: keyword
+ description: Subdomain, e.g. 'drive' for the domain 'drive.google.com'.
+ - name: tld
+ type: keyword
+ description: The domain's top-level domain. E.g. the TLD of google.com is 'com'.
+ - name: valid
+ type: boolean
+ description: Whether the domain is valid.
+ - name: server
+ type: group
+ fields:
+ - name: domain
+ type: keyword
+ description: The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar.
+ - name: punycode
+ type: keyword
+ description: Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com.
+ - name: root_domain
+ type: keyword
+ description: The root domain, including the TLD.
+ - name: sld
+ type: keyword
+ description: Second-level domain, e.g. 'windows' for the domain 'windows.net'.
+ - name: subdomain
+ type: keyword
+ description: Subdomain, e.g. 'drive' for the domain 'drive.google.com'.
+ - name: tld
+ type: keyword
+ description: The domain's top-level domain. E.g. the TLD of google.com is 'com'.
+ - name: valid
+ type: boolean
+ description: Whether the domain is valid.
+ - name: verdict
+ type: keyword
+ description: Verdict of the SPF.
+ - name: type
+ type: keyword
+ description: The type of authentication result, derived from the field name.
+ - name: fields
+ type: object
+ object_type: keyword
+ - name: index
+ type: long
+ description: Index indicates the order in which a hop occurred from sender to recipient.
+ - name: received
+ type: group
+ fields:
+ - name: additional
+ type: group
+ fields:
+ - name: raw
+ type: keyword
+ description: The raw string for remaining additional clauses, such as transport information.
+ - name: id
+ type: group
+ fields:
+ - name: raw
+ type: keyword
+ description: The raw string of 'id' section.
+ - name: link
+ type: group
+ fields:
+ - name: raw
+ type: keyword
+ description: The raw string of 'via' section.
+ - name: mailbox
+ type: group
+ fields:
+ - name: raw
+ type: keyword
+ description: The raw string of 'for' section.
+ - name: protocol
+ type: group
+ fields:
+ - name: raw
+ type: keyword
+ description: The raw string of 'with' section.
+ - name: server
+ type: group
+ fields:
+ - name: raw
+ type: keyword
+ description: The raw string of 'by' section.
+ - name: source
+ type: group
+ fields:
+ - name: raw
+ type: keyword
+ description: The raw string of 'from' section.
+ - name: time
+ type: date
+ description: Time parsed from the Received header.
+ - name: zone_offset
+ type: keyword
+ description: Timezone offset parsed from the Received header.
+ - name: received_spf
+ type: group
+ fields:
+ - name: client_ip
+ type: group
+ fields:
+ - name: ip
+ type: ip
+ description: The raw IP.
+ - name: description
+ type: keyword
+ description: Verbose description of the SPF verdict.
+ - name: designator
+ type: keyword
+ description: Email or domain of the designating body.
+ - name: helo
+ type: group
+ fields:
+ - name: domain
+ type: keyword
+ description: The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar.
+ - name: punycode
+ type: keyword
+ description: Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com.
+ - name: root_domain
+ type: keyword
+ description: The root domain, including the TLD.
+ - name: sld
+ type: keyword
+ description: Second-level domain, e.g. 'windows' for the domain 'windows.net'.
+ - name: subdomain
+ type: keyword
+ description: Subdomain, e.g. 'drive' for the domain 'drive.google.com'.
+ - name: tld
+ type: keyword
+ description: The domain's top-level domain. E.g. the TLD of google.com is 'com'.
+ - name: valid
+ type: boolean
+ description: Whether the domain is valid.
+ - name: server
+ type: group
+ fields:
+ - name: domain
+ type: keyword
+ description: The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar.
+ - name: punycode
+ type: keyword
+ description: Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com.
+ - name: root_domain
+ type: keyword
+ description: The root domain, including the TLD.
+ - name: sld
+ type: keyword
+ description: Second-level domain, e.g. 'windows' for the domain 'windows.net'.
+ - name: subdomain
+ type: keyword
+ description: Subdomain, e.g. 'drive' for the domain 'drive.google.com'.
+ - name: tld
+ type: keyword
+ description: The domain's top-level domain. E.g. the TLD of google.com is 'com'.
+ - name: valid
+ type: boolean
+ description: Whether the domain is valid.
+ - name: verdict
+ type: keyword
+ description: Verdict of the SPF.
+ - name: signature
+ type: group
+ fields:
+ - name: algorithm
+ type: keyword
+ description: Signing algorithm.
+ - name: body_hash
+ type: keyword
+ description: Body Hash.
+ - name: domain
+ type: keyword
+ description: Domain identified in the DKIM signature if any. This is the domain that's queried for the public key.
+ - name: headers
+ type: keyword
+ description: Header fields signed by the algorithm.
+ - name: instance
+ type: keyword
+ description: Instance number of this signature (if ARC).
+ - name: selector
+ type: keyword
+ description: Selector.
+ - name: signature
+ type: keyword
+ description: Signature of headers and body.
+ - name: type
+ type: keyword
+ description: The type of signature, derived from the field name.
+ - name: version
+ type: keyword
+ description: Version.
+ - name: in_reply_to
+ type: keyword
+ description: In-Reply-To header value which identifies its parent message if exists.
+ - name: ips
+ type: group
+ fields:
+ - name: ip
+ type: keyword
+ description: The raw IP.
+ - name: mailer
+ type: keyword
+ description: X-Mailer or User-Agent extracted from headers.
+ - name: message_id
+ type: keyword
+ description: Message-ID extracted from the header.
+ - name: references
+ type: keyword
+ description: The Message-IDs of the other messages within this chain.
+ - name: reply_to
+ type: group
+ fields:
+ - name: display_name
+ type: keyword
+ description: Display name.
+ - name: email
+ type: group
+ fields:
+ - name: domain
+ type: group
+ fields:
+ - name: domain
+ type: keyword
+ description: The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar.
+ - name: punycode
+ type: keyword
+ description: Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com.
+ - name: root_domain
+ type: keyword
+ description: The root domain, including the TLD.
+ - name: sld
+ type: keyword
+ description: Second-level domain, e.g. 'windows' for the domain 'windows.net'.
+ - name: subdomain
+ type: keyword
+ description: Subdomain, e.g. 'drive' for the domain 'drive.google.com'.
+ - name: tld
+ type: keyword
+ description: The domain's top-level domain. E.g. the TLD of google.com is 'com'.
+ - name: valid
+ type: boolean
+ description: Whether the domain is valid.
+ - name: local_part
+ type: keyword
+ description: Local-part, i.e. before the @.
+ - name: value
+ type: keyword
+ description: Full email address.
+ - name: return_path
+ type: group
+ fields:
+ - name: domain
+ type: group
+ fields:
+ - name: domain
+ type: keyword
+ description: The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar.
+ - name: punycode
+ type: keyword
+ description: Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com.
+ - name: root_domain
+ type: keyword
+ description: The root domain, including the TLD.
+ - name: sld
+ type: keyword
+ description: Second-level domain, e.g. 'windows' for the domain 'windows.net'.
+ - name: subdomain
+ type: keyword
+ description: Subdomain, e.g. 'drive' for the domain 'drive.google.com'.
+ - name: tld
+ type: keyword
+ description: The domain's top-level domain. E.g. the TLD of google.com is 'com'.
+ - name: valid
+ type: boolean
+ description: Whether the domain is valid.
+ - name: email
+ type: keyword
+ description: Full email address.
+ - name: local_part
+ type: keyword
+ description: Local-part, i.e. before the @.
+ - name: x_authenticated_domain
+ type: group
+ fields:
+ - name: domain
+ type: keyword
+ description: The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar.
+ - name: punycode
+ type: keyword
+ description: Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com.
+ - name: root_domain
+ type: keyword
+ description: The root domain, including the TLD.
+ - name: sld
+ type: keyword
+ description: Second-level domain, e.g. 'windows' for the domain 'windows.net'.
+ - name: subdomain
+ type: keyword
+ description: Subdomain, e.g. 'drive' for the domain 'drive.google.com'.
+ - name: tld
+ type: keyword
+ description: The domain's top-level domain. E.g. the TLD of google.com is 'com'.
+ - name: valid
+ type: boolean
+ description: Whether the domain is valid.
+ - name: x_authenticated_sender
+ type: group
+ fields:
+ - name: domain
+ type: group
+ fields:
+ - name: domain
+ type: keyword
+ description: The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar.
+ - name: punycode
+ type: keyword
+ description: Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com.
+ - name: root_domain
+ type: keyword
+ description: The root domain, including the TLD.
+ - name: sld
+ type: keyword
+ description: Second-level domain, e.g. 'windows' for the domain 'windows.net'.
+ - name: subdomain
+ type: keyword
+ description: Subdomain, e.g. 'drive' for the domain 'drive.google.com'.
+ - name: tld
+ type: keyword
+ description: The domain's top-level domain. E.g. the TLD of google.com is 'com'.
+ - name: valid
+ type: boolean
+ description: Whether the domain is valid.
+ - name: email
+ type: keyword
+ description: Full email address.
+ - name: local_part
+ type: keyword
+ description: Local-part, i.e. before the @.
+ - name: x_client_ip
+ type: group
+ fields:
+ - name: ip
+ type: ip
+ description: The raw IP.
+ - name: x_originating_ip
+ type: group
+ fields:
+ - name: ip
+ type: ip
+ description: The raw IP.
+ - name: x_secure_server_account
+ type: keyword
+ description: X-SecureServer-Acct header, which represents a unique identifier associated with the sender's email account on a secure server and can be used to trace the email back to a specific account or user.
+ - name: x_sender
+ type: group
+ fields:
+ - name: domain
+ type: group
+ fields:
+ - name: domain
+ type: keyword
+ description: The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar.
+ - name: punycode
+ type: keyword
+ description: Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com.
+ - name: root_domain
+ type: keyword
+ description: The root domain, including the TLD.
+ - name: sld
+ type: keyword
+ description: Second-level domain, e.g. 'windows' for the domain 'windows.net'.
+ - name: subdomain
+ type: keyword
+ description: Subdomain, e.g. 'drive' for the domain 'drive.google.com'.
+ - name: tld
+ type: keyword
+ description: The domain's top-level domain. E.g. the TLD of google.com is 'com'.
+ - name: valid
+ type: boolean
+ description: Whether the domain is valid.
+ - name: email
+ type: keyword
+ description: Full email address.
+ - name: local_part
+ type: keyword
+ description: Local-part, i.e. before the @.
+ - name: mailbox
+ type: group
+ fields:
+ - name: display_name
+ type: keyword
+ description: Display name.
+ - name: email
+ type: group
+ fields:
+ - name: domain
+ type: group
+ fields:
+ - name: domain
+ type: keyword
+ description: The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar.
+ - name: punycode
+ type: keyword
+ description: Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com.
+ - name: root_domain
+ type: keyword
+ description: The root domain, including the TLD.
+ - name: sld
+ type: keyword
+ description: Second-level domain, e.g. 'windows' for the domain 'windows.net'.
+ - name: subdomain
+ type: keyword
+ description: Subdomain, e.g. 'drive' for the domain 'drive.google.com'.
+ - name: tld
+ type: keyword
+ description: The domain's top-level domain. E.g. the TLD of google.com is 'com'.
+ - name: valid
+ type: boolean
+ description: Whether the domain is valid.
+ - name: local_part
+ type: keyword
+ description: Local-part, i.e. before the @.
+ - name: value
+ type: keyword
+ description: Full email address.
+ - name: meta
+ type: group
+ fields:
+ - name: canonical_id
+ type: keyword
+ description: A deterministic ID, generated from metadata such as Attachments, Body, Subject, Sender and is used to group similar messages/campaigns together.
+ - name: created_at
+ type: date
+ description: Creation time of the data model.
+ - name: effective_at
+ type: date
+ description: Effective time of the data model, used for evaluation against lists and historical functions such as sender profiles or whois.
+ - name: id
+ type: keyword
+ description: Message ID.
+ - name: recipients
+ type: group
+ fields:
+ - name: bcc
+ type: group
+ fields:
+ - name: display_name
+ type: keyword
+ description: Display name.
+ - name: email
+ type: group
+ fields:
+ - name: domain
+ type: group
+ fields:
+ - name: domain
+ type: keyword
+ description: The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar.
+ - name: punycode
+ type: keyword
+ description: Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com.
+ - name: root_domain
+ type: keyword
+ description: The root domain, including the TLD.
+ - name: sld
+ type: keyword
+ description: Second-level domain, e.g. 'windows' for the domain 'windows.net'.
+ - name: subdomain
+ type: keyword
+ description: Subdomain, e.g. 'drive' for the domain 'drive.google.com'.
+ - name: tld
+ type: keyword
+ description: The domain's top-level domain. E.g. the TLD of google.com is 'com'.
+ - name: valid
+ type: boolean
+ description: Whether the domain is valid.
+ - name: local_part
+ type: keyword
+ description: Local-part, i.e. before the @.
+ - name: value
+ type: keyword
+ description: Full email address.
+ - name: cc
+ type: group
+ fields:
+ - name: display_name
+ type: keyword
+ description: Display name.
+ - name: email
+ type: group
+ fields:
+ - name: domain
+ type: group
+ fields:
+ - name: domain
+ type: keyword
+ description: The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar.
+ - name: punycode
+ type: keyword
+ description: Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com.
+ - name: root_domain
+ type: keyword
+ description: The root domain, including the TLD.
+ - name: sld
+ type: keyword
+ description: Second-level domain, e.g. 'windows' for the domain 'windows.net'.
+ - name: subdomain
+ type: keyword
+ description: Subdomain, e.g. 'drive' for the domain 'drive.google.com'.
+ - name: tld
+ type: keyword
+ description: The domain's top-level domain. E.g. the TLD of google.com is 'com'.
+ - name: valid
+ type: boolean
+ description: Whether the domain is valid.
+ - name: local_part
+ type: keyword
+ description: Local-part, i.e. before the @.
+ - name: value
+ type: keyword
+ description: Full email address.
+ - name: to
+ type: group
+ fields:
+ - name: display_name
+ type: keyword
+ description: Display name.
+ - name: email
+ type: group
+ fields:
+ - name: domain
+ type: group
+ fields:
+ - name: domain
+ type: keyword
+ description: The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar.
+ - name: punycode
+ type: keyword
+ description: Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com.
+ - name: root_domain
+ type: keyword
+ description: The root domain, including the TLD.
+ - name: sld
+ type: keyword
+ description: Second-level domain, e.g. 'windows' for the domain 'windows.net'.
+ - name: subdomain
+ type: keyword
+ description: Subdomain, e.g. 'drive' for the domain 'drive.google.com'.
+ - name: tld
+ type: keyword
+ description: The domain's top-level domain. E.g. the TLD of google.com is 'com'.
+ - name: valid
+ type: boolean
+ description: Whether the domain is valid.
+ - name: local_part
+ type: keyword
+ description: Local-part, i.e. before the @.
+ - name: value
+ type: keyword
+ description: Full email address.
+ - name: sender
+ type: group
+ fields:
+ - name: display_name
+ type: keyword
+ description: Display name.
+ - name: email
+ type: group
+ fields:
+ - name: domain
+ type: group
+ fields:
+ - name: domain
+ type: keyword
+ description: The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar.
+ - name: punycode
+ type: keyword
+ description: Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com.
+ - name: root_domain
+ type: keyword
+ description: The root domain, including the TLD.
+ - name: sld
+ type: keyword
+ description: Second-level domain, e.g. 'windows' for the domain 'windows.net'.
+ - name: subdomain
+ type: keyword
+ description: Subdomain, e.g. 'drive' for the domain 'drive.google.com'.
+ - name: tld
+ type: keyword
+ description: The domain's top-level domain. E.g. the TLD of google.com is 'com'.
+ - name: valid
+ type: boolean
+ description: Whether the domain is valid.
+ - name: local_part
+ type: keyword
+ description: Local-part, i.e. before the @.
+ - name: value
+ type: keyword
+ description: Full email address.
+ - name: subject
+ type: group
+ fields:
+ - name: subject
+ type: keyword
+ description: Subject of the email.
+ - name: type
+ type: group
+ fields:
+ - name: inbound
+ type: boolean
+ description: Message was sent from someone outside your organization, to at least one recipient inside your organization.
+ - name: internal
+ type: boolean
+ description: Message was sent from someone inside your organization, to at least one recipient inside your organization. Messages must be authenticated by either SPF or DKIM to be treated as internal.
+ - name: outbound
+ type: boolean
+ description: Message was sent from someone inside your organization, to at least one recipient outside your organization.
diff --git a/packages/sublime_security/data_stream/email_message/manifest.yml b/packages/sublime_security/data_stream/email_message/manifest.yml
new file mode 100644
index 00000000000..232f07c86e2
--- /dev/null
+++ b/packages/sublime_security/data_stream/email_message/manifest.yml
@@ -0,0 +1,117 @@
+title: Sublime Security Email Message logs
+type: logs
+streams:
+ - input: aws-s3
+ template_path: aws-s3.yml.hbs
+ title: Sublime Security Email Message logs via AWS S3 or SQS
+ description: Collecting Sublime Security Email Message logs via AWS S3 or SQS input.
+ enabled: false
+ vars:
+ - name: bucket_arn
+ type: text
+ title: '[S3] Bucket ARN'
+ multi: false
+ required: false
+ show_user: true
+ description: ARN of the AWS S3 bucket that will be polled for list operation. It is a required parameter for collecting logs via the AWS S3.
+ - name: bucket_list_prefix
+ type: text
+ title: '[S3] Bucket Prefix'
+ multi: false
+ required: false
+ show_user: true
+ description: Prefix to apply for the list request to the S3 bucket.
+ - name: interval
+ type: text
+ title: '[S3] Interval'
+ multi: false
+ required: false
+ show_user: true
+ default: 120s
+ description: Listing of the S3 bucket will be polled according to the time interval defined by bucket_list_interval config. Default value is 120 secs. Supported units for this parameter are h/m/s.
+ - name: number_of_workers
+ type: integer
+ title: '[S3] Number of Workers'
+ multi: false
+ required: false
+ show_user: true
+ default: 5
+ description: Number of workers that will process the S3 objects listed.
+ - name: queue_url
+ type: text
+ title: '[SQS] Queue URL'
+ multi: false
+ required: false
+ show_user: true
+ description: URL of the AWS SQS queue that messages will be received from. It is a required parameter for collecting logs via the AWS SQS.
+ - name: visibility_timeout
+ type: text
+ title: '[SQS] Visibility Timeout'
+ multi: false
+ required: false
+ show_user: true
+ default: 300s
+ description: The duration that the received messages are hidden from subsequent retrieve requests after being retrieved by a ReceiveMessage request. The maximum is 12 hours. Supported units for this parameter are h/m/s.
+ - name: api_timeout
+ type: text
+ title: '[SQS] API Timeout'
+ multi: false
+ required: false
+ show_user: true
+ default: 120s
+ description: The maximum duration of AWS API can take. The maximum is half of the visibility timeout value. Supported units for this parameter are h/m/s.
+ - name: max_number_of_messages
+ type: integer
+ title: '[SQS] Maximum Concurrent SQS Messages'
+ required: false
+ show_user: true
+ default: 5
+ description: The maximum number of SQS messages that can be inflight at any time.
+ - name: file_selectors
+ type: yaml
+ title: '[SQS] File Selectors'
+ multi: false
+ required: false
+ show_user: false
+ description: >-
+ If the SQS queue will have events that correspond to files that this integration shouldn’t process, file_selectors can be used to limit the files that are downloaded. This is a list of selectors which are made up of regex and expand_event_list_from_field options. The regex should match the S3 object key in the SQS message, and the optional expand_event_list_from_field is the same as the global setting. If file_selectors is given, then any global expand_event_list_from_field value is ignored in favor of the ones specified in the file_selectors. Regexes use [RE2 syntax](https://pkg.go.dev/regexp/syntax). Files that do not match one of the regexes will not be processed.
+ - name: external_id
+ type: text
+ title: External ID
+ multi: false
+ required: false
+ show_user: false
+ description: External ID to use when assuming a role in another account.
+ - name: tags
+ type: text
+ title: Tags
+ multi: true
+ required: true
+ show_user: false
+ default:
+ - forwarded
+ - sublime_security-email_message
+ - name: preserve_original_event
+ required: false
+ show_user: true
+ title: Preserve original event
+ description: Preserves a raw copy of the original event, added to the field `event.original`.
+ type: bool
+ multi: false
+ default: false
+ - name: preserve_duplicate_custom_fields
+ required: true
+ show_user: false
+ title: Preserve duplicate custom fields
+ description: Preserve sublime_security.email_message fields that were mapped to Elastic Common Schema (ECS) fields.
+ type: bool
+ multi: false
+ default: false
+ - name: processors
+ type: yaml
+ title: Processors
+ multi: false
+ required: false
+ show_user: false
+ description: >-
+ Processors are used to reduce the number of fields in the exported event or to enhance the event with metadata. This executes in the agent before the logs are parsed. See [Processors](https://www.elastic.co/guide/en/beats/filebeat/current/filtering-and-enhancing-data.html) for details.
diff --git a/packages/sublime_security/data_stream/email_message/sample_event.json b/packages/sublime_security/data_stream/email_message/sample_event.json
new file mode 100644
index 00000000000..bbb0f3711e2
--- /dev/null
+++ b/packages/sublime_security/data_stream/email_message/sample_event.json
@@ -0,0 +1,762 @@
+{
+ "@timestamp": "2024-08-02T07:40:25.135Z",
+ "agent": {
+ "ephemeral_id": "832ebf28-565e-4f38-a67e-ee5ea9f51e89",
+ "id": "5f3fcbb9-1a97-4ff3-857f-167af6664464",
+ "name": "docker-fleet-agent",
+ "type": "filebeat",
+ "version": "8.13.0"
+ },
+ "aws": {
+ "s3": {
+ "bucket": {
+ "arn": "arn:aws:s3:::elastic-package-sublime-security-bucket-33881",
+ "name": "elastic-package-sublime-security-bucket-33881"
+ },
+ "object": {
+ "key": "email-message.log"
+ }
+ }
+ },
+ "cloud": {
+ "region": "us-east-1"
+ },
+ "data_stream": {
+ "dataset": "sublime_security.email_message",
+ "namespace": "57022",
+ "type": "logs"
+ },
+ "destination": {
+ "domain": "example.com",
+ "subdomain": "example",
+ "top_level_domain": "com"
+ },
+ "ecs": {
+ "version": "8.11.0"
+ },
+ "elastic_agent": {
+ "id": "5f3fcbb9-1a97-4ff3-857f-167af6664464",
+ "snapshot": false,
+ "version": "8.13.0"
+ },
+ "email": {
+ "attachments": [
+ {
+ "file": {
+ "extension": "pdf",
+ "hash": {
+ "md5": "1a2b3c",
+ "sha1": "4d5e6f",
+ "sha256": "7g8h9i"
+ },
+ "mime_type": "application/pdf",
+ "name": "sample_document.pdf",
+ "size": 102400
+ }
+ },
+ {
+ "file": {
+ "extension": "jpg",
+ "hash": {
+ "md5": "7h8i9j",
+ "sha1": "1k2l3m",
+ "sha256": "4n5o6p"
+ },
+ "mime_type": "image/jpeg",
+ "name": "image_photo.jpg",
+ "size": 204800
+ }
+ },
+ {
+ "file": {
+ "extension": "txt",
+ "hash": {
+ "md5": "1x2y3z",
+ "sha1": "4a5b6c",
+ "sha256": "7d8e9f"
+ },
+ "mime_type": "text/plain",
+ "name": "notes.txt",
+ "size": 5120
+ }
+ }
+ ],
+ "bcc": {
+ "address": [
+ "john.doe@example.com"
+ ]
+ },
+ "cc": {
+ "address": [
+ "jane.smith@example.org"
+ ]
+ },
+ "direction": "outbound",
+ "from": {
+ "address": [
+ "testing@sublimesecurity.com"
+ ]
+ },
+ "message_id": "2fe271830bbad5fe3a70abbe7a8c0bfe7refe3ffe",
+ "origination_timestamp": "2024-08-02T07:40:25.135Z",
+ "reply_to": {
+ "address": [
+ "user@example.com"
+ ]
+ },
+ "subject": "Sublime-Security-Standard-Test-String",
+ "to": {
+ "address": [
+ "user@example.com"
+ ]
+ },
+ "x_mailer": "MyCustomMailer"
+ },
+ "event": {
+ "agent_id_status": "verified",
+ "category": [
+ "email"
+ ],
+ "dataset": "sublime_security.email_message",
+ "id": "01911208-633c-7f03-b303-e594d92cf818",
+ "ingested": "2024-08-28T10:59:37Z",
+ "kind": "event",
+ "original": "{\"body\":{\"plain\":{\"raw\":\"Sublime Security test message.\\n\",\"charset\":\"utf-8\",\"content_transfer_encoding\":\"base64\"},\"current_thread\":{\"text\":\"Sublime Security test message.\"},\"html\":{\"charset\":\"utf-8\",\"content_transfer_encoding\":\"base64\",\"display_text\":\"Sublime Security test message.\",\"raw\":\"Sublime Security test message.
\",\"inner_text\":\"Sublime Security test message.
\"},\"ips\":[{\"ip\":\"1.128.0.0\"}],\"links\":[{\"display_text\":\"Click here!\",\"mismatched\":true,\"display_url\":{\"fragment\":\"search\",\"password\":\"pass123\",\"path\":\"/test\",\"port\":80,\"query_params\":\"q=elasticsearch\",\"rewrite\":{\"encoders\":[\"base64\"],\"original\":\"demo\"},\"scheme\":\"https\",\"url\":\"https://example.com/test?q=elasticsearch#search\",\"username\":\"test\",\"domain\":{\"domain\":\"example.com\",\"punycode\":\"demo\",\"root_domain\":\"example.com\",\"subdomain\":\"example\",\"tld\":\"com\",\"valid\":true,\"sld\":\"example\"}}},{\"href_url\":{\"fragment\":\"search\",\"password\":\"pass123\",\"path\":\"/test\",\"port\":80,\"query_params\":\"q=elasticsearch\",\"rewrite\":{\"encoders\":[\"base64\"],\"original\":\"demo\"},\"scheme\":\"https\",\"url\":\"https://example.com/test?q=elasticsearch#search\",\"username\":\"test\",\"domain\":{\"domain\":\"example.com\",\"punycode\":\"demo\",\"root_domain\":\"example.com\",\"subdomain\":\"example\",\"tld\":\"com\",\"valid\":true,\"sld\":\"example\"}}}]},\"external\":{\"created_at\":\"2024-08-02T07:40:25.135939305Z\",\"message_id\":\"2fe271830bbad5fe3a70abbe7a8c0bfe7refe3ffe\",\"route_type\":\"sent\",\"spam\":false,\"spam_folder\":true,\"thread_id\":\"sample_data\"},\"attachments\":[{\"content_id\":\"abc123\",\"content_transfer_encoding\":\"base64\",\"content_type\":\"application/pdf\",\"file_extension\":\".pdf\",\"file_name\":\"sample_document.pdf\",\"file_type\":\"document\",\"md5\":\"1a2b3c\",\"raw\":\"JVBERi0xLjMKJcfs4AAQSkZjRgABAQE\",\"sha1\":\"4d5e6f\",\"sha256\":\"7g8h9i\",\"size\":102400},{\"content_id\":\"xyz456\",\"content_transfer_encoding\":\"7bit\",\"content_type\":\"image/jpeg\",\"file_extension\":\".jpg\",\"file_name\":\"image_photo.jpg\",\"file_type\":\"image\",\"md5\":\"7h8i9j\",\"raw\":\"/9j/4AAQSkZJRgABAQEJVBERi0xLjMKJd\",\"sha1\":\"1k2l3m\",\"sha256\":\"4n5o6p\",\"size\":204800},{\"content_id\":\"efg789\",\"content_transfer_encoding\":\"quoted-printable\",\"content_type\":\"text/plain\",\"file_extension\":\".txt\",\"file_name\":\"notes.txt\",\"file_type\":\"text\",\"md5\":\"1x2y3z\",\"raw\":\"SGVsbG8gdVsbG8gd29yb29ybGQhVsbG8gd29yb\",\"sha1\":\"4a5b6c\",\"sha256\":\"7d8e9f\",\"size\":5120}],\"headers\":{\"x_authenticated_domain\":{\"domain\":\"example.com\",\"punycode\":\"xn--example-d4a.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"sub\",\"tld\":\"com\",\"valid\":true},\"x_authenticated_sender\":{\"domain\":{\"domain\":\"example.com\",\"punycode\":\"example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"sub\",\"tld\":\"com\",\"valid\":true},\"email\":\"user@example.com\",\"local_part\":\"user\"},\"x_client_ip\":{\"ip\":\"1.128.0.0\"},\"x_originating_ip\":{\"ip\":\"1.128.0.0\"},\"x_secure_server_account\":\"account_value\",\"x_sender\":{\"domain\":{\"domain\":\"example.com\",\"punycode\":\"example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"sub\",\"tld\":\"com\",\"valid\":true},\"email\":\"user@example.com\",\"local_part\":\"user\"},\"return_path\":{\"domain\":{\"domain\":\"example.com\",\"punycode\":\"xn--example-d4a.com\",\"root_domain\":\"example\",\"sld\":\"example\",\"subdomain\":\"sub\",\"tld\":\"com\",\"valid\":true},\"email\":\"user@example.com\",\"local_part\":\"user\"},\"references\":[\"test1\",\"test2\"],\"auth_summary\":{\"dmarc\":{\"details\":{\"action\":\"quarantine\",\"disposition\":\"quarantine\",\"from\":{\"domain\":\"example.com\",\"punycode\":\"example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"example\",\"tld\":\"com\",\"valid\":true},\"policy\":\"reject\",\"sub_policy\":\"none\",\"verdict\":\"pass\",\"version\":\"1.0\"},\"pass\":true,\"received_hop\":1},\"spf\":{\"details\":{\"client_ip\":{\"ip\":\"1.128.0.0\"},\"description\":\"SPF record found\",\"designator\":\"pass\",\"helo\":{\"domain\":\"example.com\",\"punycode\":\"example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"example\",\"tld\":\"com\",\"valid\":true},\"server\":{\"domain\":\"mail.example.com\",\"punycode\":\"mail.example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"mail\",\"tld\":\"com\",\"valid\":true},\"verdict\":\"pass\"},\"error\":\"true\",\"pass\":true,\"received_hop\":2}},\"date\":\"2019-10-21T18:23:24Z\",\"date_original_offset\":\"-4\",\"hops\":[{\"index\":0,\"fields\":[{\"name\":\"To\",\"value\":\"user@example.com\",\"position\":0},{\"name\":\"Subject\",\"value\":\"Sublime-Security-Standard-Test-String\",\"position\":1},{\"name\":\"Date\",\"value\":\"Mon, 21 Oct 2019 14:23:24 -0400\",\"position\":2},{\"name\":\"From\",\"value\":\"Sublime Security Test \",\"position\":3}],\"authentication_results\":{\"compauth\":{\"verdict\":\"pass\",\"reason\":\"reason_value\"},\"dkim\":\"pass\",\"dkim_details\":{\"algorithm\":\"rsa-sha256\",\"body_hash\":\"abcdefg\",\"domain\":\"example.com\",\"headers\":\"from, to, subject\",\"instance\":\"example.com\",\"selector\":\"abcdefg\",\"signature\":\"abcdefg\",\"type\":\"dkim\",\"version\":\"1.0\"},\"dmarc\":\"pass\",\"dmarc_details\":{\"action\":\"quarantine\",\"disposition\":\"quarantine\",\"from\":{\"domain\":\"example.com\",\"punycode\":\"example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"example\",\"tld\":\"com\",\"valid\":true},\"policy\":\"reject\",\"sub_policy\":\"none\",\"verdict\":\"pass\",\"version\":\"1.0\"},\"instance\":\"example.com\",\"server\":{\"domain\":\"mail.example.com\",\"punycode\":\"mail.example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"mail\",\"tld\":\"com\",\"valid\":true},\"spf\":\"pass\",\"spf_details\":{\"client_ip\":{\"ip\":\"1.128.0.0\"},\"description\":\"SPF record found\",\"designator\":\"pass\",\"helo\":{\"domain\":\"example.com\",\"punycode\":\"example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"example\",\"tld\":\"com\",\"valid\":true},\"server\":{\"domain\":\"mail.example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"mail\",\"tld\":\"com\",\"valid\":true},\"verdict\":\"pass\"},\"type\":\"spf\"},\"received\":{\"additional\":{\"raw\":\"Authentication successful\"},\"id\":{\"raw\":\"msg-12345\"},\"link\":{\"raw\":\"https://mail.example.com/message/12345\"},\"mailbox\":{\"raw\":\"user@example.com\"},\"protocol\":{\"raw\":\"IMAP\"},\"server\":{\"raw\":\"imap.example.com\"},\"source\":{\"raw\":\"81.2.69.144\"},\"time\":\"2019-10-21T18:23:24Z\",\"zone_offset\":\"+00:00\"},\"received_spf\":{\"client_ip\":{\"ip\":\"1.128.0.0\"},\"description\":\"SPF record found\",\"designator\":\"pass\",\"helo\":{\"domain\":\"example.com\",\"punycode\":\"example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"example\",\"tld\":\"com\",\"valid\":true},\"server\":{\"domain\":\"mail.example.com\",\"punycode\":\"mail.example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"mail\",\"tld\":\"com\",\"valid\":true},\"verdict\":\"pass\"},\"signature\":{\"algorithm\":\"rsa-sha256\",\"body_hash\":\"b9c4a3f9d93d9a38bdf8c47a8f2d2c79ec1d8b1f\",\"domain\":\"example.com\",\"headers\":\"from:to:subject:date\",\"instance\":\"123456\",\"selector\":\"default\",\"signature\":\"d2abf9d6c8f4b8d68d8f3f7b6f9d3b8e6a8c2b3a9f4b8d7b9d3b6a8f9c3b4e5f\",\"type\":\"spf\",\"version\":\"1\"}}],\"in_reply_to\":\"in_reply_to_value\",\"delivered_to\":{\"domain\":{\"domain\":\"example.com\",\"subdomain\":\"example\",\"tld\":\"com\",\"email\":\"testing@sublimesecurity.com\",\"punycode\":\"example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"valid\":true},\"email\":\"testing@sublimesecurity.com\",\"local_part\":\"testing\"},\"ips\":[{\"ip\":\"1.128.0.0\"}],\"mailer\":\"MyCustomMailer\",\"message_id\":\"2fe271830bbad5fe3a70abbe7a8c0bfe7refe3ffe\",\"domains\":[{\"domain\":\"test.com\",\"subdomain\":\"test\",\"tld\":\"com\",\"punycode\":\"test.com\",\"root_domain\":\"test.com\",\"sld\":\"test\",\"valid\":true},{\"domain\":\"example.com\",\"subdomain\":\"example\",\"tld\":\"com\",\"punycode\":\"example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"valid\":true}],\"reply_to\":[{\"email\":{\"email\":\"user@example.com\",\"local_part\":\"user\",\"domain\":{\"domain\":\"example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"tld\":\"com\",\"valid\":true}}},{\"display_name\":\"Example Display Name\",\"email\":{\"domain\":{\"punycode\":\"example.com\",\"subdomain\":\"sub.example\"}}},{\"display_name\":\"Another Display Name\",\"email\":{\"domain\":{\"punycode\":\"anotherexample.com\",\"subdomain\":\"sub.anotherexample\"}}}]},\"type\":{\"outbound\":true},\"mailbox\":{\"email\":{\"email\":\"user@example.com\",\"local_part\":\"user\",\"domain\":{\"domain\":\"example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"tld\":\"com\",\"valid\":true,\"punycode\":\"xn--example-d4a.com\",\"subdomain\":\"sub\"}}},\"recipients\":{\"to\":[{\"display_name\":\"Alice Johnson\",\"email\":{\"email\":\"user@example.com\",\"local_part\":\"user\",\"domain\":{\"domain\":\"example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"tld\":\"com\",\"valid\":true,\"punycode\":\"xn--example-d4a.net\",\"subdomain\":\"sub\"}}}],\"bcc\":[{\"display_name\":\"John Doe\",\"email\":{\"domain\":{\"domain\":\"example.com\",\"punycode\":\"xn--example-d4a.com\",\"root_domain\":\"example\",\"sld\":\"example\",\"subdomain\":\"sub\",\"tld\":\"com\",\"valid\":true},\"email\":\"john.doe@example.com\",\"local_part\":\"john.doe\"}}],\"cc\":[{\"display_name\":\"Jane Smith\",\"email\":{\"domain\":{\"domain\":\"example.org\",\"punycode\":\"xn--example-d4a.org\",\"root_domain\":\"example\",\"sld\":\"example\",\"subdomain\":\"sub\",\"tld\":\"org\",\"valid\":true},\"email\":\"jane.smith@example.org\",\"local_part\":\"jane.smith\"}}]},\"sender\":{\"display_name\":\"Sublime Security Test\",\"email\":{\"email\":\"testing@sublimesecurity.com\",\"local_part\":\"testing\",\"domain\":{\"domain\":\"sublimesecurity.com\",\"root_domain\":\"sublimesecurity.com\",\"sld\":\"sublimesecurity\",\"tld\":\"com\",\"valid\":true,\"punycode\":\"xn--example-d4a.com\",\"subdomain\":\"sub\"}}},\"subject\":{\"subject\":\"Sublime-Security-Standard-Test-String\"},\"_meta\":{\"id\":\"01911208-633c-7f03-b303-e594d92cf818\",\"canonical_id\":\"2fe271830bbad5fe3a70abbe7a8c0bfe79eb208a76cde267930d19f0e8cea81c\",\"created_at\":\"2024-08-02T07:40:25.135939305Z\",\"effective_at\":\"2024-08-02T07:40:25.135939305Z\"},\"_errors\":[{\"field\":\"Mime-Version\",\"message\":\"No Mime-Version defined in headers\",\"type\":\"missing_header_field\"}]}",
+ "type": [
+ "info"
+ ]
+ },
+ "input": {
+ "type": "aws-s3"
+ },
+ "log": {
+ "file": {
+ "path": "https://elastic-package-sublime-security-bucket-33881.s3.us-east-1.amazonaws.com/email-message.log"
+ },
+ "offset": 0
+ },
+ "observer": {
+ "product": "Sublime Security",
+ "vendor": "Sublime Security"
+ },
+ "related": {
+ "hash": [
+ "1a2b3c",
+ "7h8i9j",
+ "1x2y3z",
+ "4d5e6f",
+ "1k2l3m",
+ "4a5b6c",
+ "7g8h9i",
+ "4n5o6p",
+ "7d8e9f",
+ "abcdefg"
+ ],
+ "hosts": [
+ "example.com",
+ "mail.example.com",
+ "test.com",
+ "example",
+ "example.org",
+ "sublimesecurity.com"
+ ],
+ "ip": [
+ "1.128.0.0"
+ ],
+ "user": [
+ "test",
+ "user@example.com",
+ "john.doe@example.com",
+ "jane.smith@example.org",
+ "testing@sublimesecurity.com"
+ ]
+ },
+ "source": {
+ "domain": "sublimesecurity.com",
+ "ip": "1.128.0.0",
+ "subdomain": "sub",
+ "top_level_domain": "com"
+ },
+ "sublime_security": {
+ "email_message": {
+ "attachments": [
+ {
+ "content": {
+ "id": "abc123",
+ "transfer_encoding": "base64"
+ },
+ "file": {
+ "type": "document"
+ },
+ "raw": "JVBERi0xLjMKJcfs4AAQSkZjRgABAQE"
+ },
+ {
+ "content": {
+ "id": "xyz456",
+ "transfer_encoding": "7bit"
+ },
+ "file": {
+ "type": "image"
+ },
+ "raw": "/9j/4AAQSkZJRgABAQEJVBERi0xLjMKJd"
+ },
+ {
+ "content": {
+ "id": "efg789",
+ "transfer_encoding": "quoted-printable"
+ },
+ "file": {
+ "type": "text"
+ },
+ "raw": "SGVsbG8gdVsbG8gd29yb29ybGQhVsbG8gd29yb"
+ }
+ ],
+ "body": {
+ "current_thread": {
+ "text": "Sublime Security test message."
+ },
+ "html": {
+ "charset": "utf-8",
+ "content_transfer_encoding": "base64",
+ "display_text": "Sublime Security test message.",
+ "inner_text": "Sublime Security test message.
",
+ "raw": "Sublime Security test message.
"
+ },
+ "ips": [
+ {
+ "ip": "1.128.0.0"
+ }
+ ],
+ "links": [
+ {
+ "display_text": "Click here!",
+ "display_url": {
+ "domain": {
+ "domain": "example.com",
+ "punycode": "demo",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "example",
+ "tld": "com",
+ "valid": true
+ },
+ "fragment": "search",
+ "password": "pass123",
+ "path": "/test",
+ "port": 80,
+ "query_params": "q=elasticsearch",
+ "rewrite": {
+ "encoders": [
+ "base64"
+ ],
+ "original": "demo"
+ },
+ "scheme": "https",
+ "url": "https://example.com/test?q=elasticsearch#search",
+ "username": "test"
+ },
+ "mismatched": true
+ },
+ {
+ "href_url": {
+ "domain": {
+ "punycode": "demo",
+ "root_domain": "example.com",
+ "sld": "example",
+ "valid": true
+ },
+ "rewrite": {
+ "encoders": [
+ "base64"
+ ],
+ "original": "demo"
+ }
+ }
+ }
+ ],
+ "plain": {
+ "charset": "utf-8",
+ "content_transfer_encoding": "base64",
+ "raw": "Sublime Security test message.\n"
+ }
+ },
+ "errors": [
+ {
+ "field": "Mime-Version",
+ "message": "No Mime-Version defined in headers",
+ "type": "missing_header_field"
+ }
+ ],
+ "external": {
+ "message_id": "2fe271830bbad5fe3a70abbe7a8c0bfe7refe3ffe",
+ "route_type": "sent",
+ "spam": false,
+ "spam_folder": true,
+ "thread_id": "sample_data"
+ },
+ "headers": {
+ "auth_summary": {
+ "dmarc": {
+ "details": {
+ "action": "quarantine",
+ "disposition": "quarantine",
+ "from": {
+ "domain": "example.com",
+ "punycode": "example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "example",
+ "tld": "com",
+ "valid": true
+ },
+ "policy": "reject",
+ "sub_policy": "none",
+ "verdict": "pass",
+ "version": "1.0"
+ },
+ "pass": true,
+ "received_hop": 1
+ },
+ "spf": {
+ "details": {
+ "client_ip": {
+ "ip": "1.128.0.0"
+ },
+ "description": "SPF record found",
+ "designator": "pass",
+ "helo": {
+ "domain": "example.com",
+ "punycode": "example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "example",
+ "tld": "com",
+ "valid": true
+ },
+ "server": {
+ "domain": "mail.example.com",
+ "punycode": "mail.example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "mail",
+ "tld": "com",
+ "valid": true
+ },
+ "verdict": "pass"
+ },
+ "error": true,
+ "pass": true,
+ "received_hop": 2
+ }
+ },
+ "date": "2019-10-21T18:23:24.000Z",
+ "date_original_offset": "-4",
+ "delivered_to": {
+ "domain": {
+ "punycode": "example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "valid": true
+ },
+ "email": "testing@sublimesecurity.com",
+ "local_part": "testing"
+ },
+ "domains": [
+ {
+ "domain": "test.com",
+ "punycode": "test.com",
+ "root_domain": "test.com",
+ "sld": "test",
+ "subdomain": "test",
+ "tld": "com",
+ "valid": true
+ },
+ {
+ "domain": "example.com",
+ "punycode": "example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "example",
+ "tld": "com",
+ "valid": true
+ }
+ ],
+ "hops": [
+ {
+ "authentication_results": {
+ "compauth": {
+ "reason": "reason_value",
+ "verdict": "pass"
+ },
+ "dkim": "pass",
+ "dkim_details": {
+ "algorithm": "rsa-sha256",
+ "body_hash": "abcdefg",
+ "domain": "example.com",
+ "headers": "from, to, subject",
+ "instance": "example.com",
+ "selector": "abcdefg",
+ "signature": "abcdefg",
+ "type": "dkim",
+ "version": "1.0"
+ },
+ "dmarc": "pass",
+ "dmarc_details": {
+ "action": "quarantine",
+ "disposition": "quarantine",
+ "from": {
+ "domain": "example.com",
+ "punycode": "example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "example",
+ "tld": "com",
+ "valid": true
+ },
+ "policy": "reject",
+ "sub_policy": "none",
+ "verdict": "pass",
+ "version": "1.0"
+ },
+ "instance": "example.com",
+ "server": {
+ "domain": "mail.example.com",
+ "punycode": "mail.example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "mail",
+ "tld": "com",
+ "valid": true
+ },
+ "spf": "pass",
+ "spf_details": {
+ "client_ip": {
+ "ip": "1.128.0.0"
+ },
+ "description": "SPF record found",
+ "designator": "pass",
+ "helo": {
+ "domain": "example.com",
+ "punycode": "example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "example",
+ "tld": "com",
+ "valid": true
+ },
+ "server": {
+ "domain": "mail.example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "mail",
+ "tld": "com",
+ "valid": true
+ },
+ "verdict": "pass"
+ },
+ "type": "spf"
+ },
+ "fields": [
+ {
+ "name": "To",
+ "position": 0,
+ "to": "user@example.com",
+ "value": "user@example.com"
+ },
+ {
+ "name": "Subject",
+ "position": 1,
+ "subject": "Sublime-Security-Standard-Test-String",
+ "value": "Sublime-Security-Standard-Test-String"
+ },
+ {
+ "date": "Mon, 21 Oct 2019 14:23:24 -0400",
+ "name": "Date",
+ "position": 2,
+ "value": "Mon, 21 Oct 2019 14:23:24 -0400"
+ },
+ {
+ "from": "Sublime Security Test ",
+ "name": "From",
+ "position": 3,
+ "value": "Sublime Security Test "
+ }
+ ],
+ "index": 0,
+ "received": {
+ "additional": {
+ "raw": "Authentication successful"
+ },
+ "id": {
+ "raw": "msg-12345"
+ },
+ "link": {
+ "raw": "https://mail.example.com/message/12345"
+ },
+ "mailbox": {
+ "raw": "user@example.com"
+ },
+ "protocol": {
+ "raw": "IMAP"
+ },
+ "server": {
+ "raw": "imap.example.com"
+ },
+ "source": {
+ "raw": "81.2.69.144"
+ },
+ "time": "2019-10-21T18:23:24.000Z",
+ "zone_offset": "+00:00"
+ },
+ "received_spf": {
+ "client_ip": {
+ "ip": "1.128.0.0"
+ },
+ "description": "SPF record found",
+ "designator": "pass",
+ "helo": {
+ "domain": "example.com",
+ "punycode": "example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "example",
+ "tld": "com",
+ "valid": true
+ },
+ "server": {
+ "domain": "mail.example.com",
+ "punycode": "mail.example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "mail",
+ "tld": "com",
+ "valid": true
+ },
+ "verdict": "pass"
+ },
+ "signature": {
+ "algorithm": "rsa-sha256",
+ "body_hash": "b9c4a3f9d93d9a38bdf8c47a8f2d2c79ec1d8b1f",
+ "domain": "example.com",
+ "headers": "from:to:subject:date",
+ "instance": "123456",
+ "selector": "default",
+ "signature": "d2abf9d6c8f4b8d68d8f3f7b6f9d3b8e6a8c2b3a9f4b8d7b9d3b6a8f9c3b4e5f",
+ "type": "spf",
+ "version": "1"
+ }
+ }
+ ],
+ "in_reply_to": "in_reply_to_value",
+ "ips": [
+ {
+ "ip": "1.128.0.0"
+ }
+ ],
+ "references": [
+ "test1",
+ "test2"
+ ],
+ "reply_to": [
+ {
+ "email": {
+ "domain": {
+ "domain": "example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "tld": "com",
+ "valid": true
+ },
+ "local_part": "user"
+ }
+ },
+ {
+ "display_name": "Example Display Name",
+ "email": {
+ "domain": {
+ "punycode": "example.com",
+ "subdomain": "sub.example"
+ }
+ }
+ },
+ {
+ "display_name": "Another Display Name",
+ "email": {
+ "domain": {
+ "punycode": "anotherexample.com",
+ "subdomain": "sub.anotherexample"
+ }
+ }
+ }
+ ],
+ "return_path": {
+ "domain": {
+ "domain": "example.com",
+ "punycode": "xn--example-d4a.com",
+ "root_domain": "example",
+ "sld": "example",
+ "subdomain": "sub",
+ "tld": "com",
+ "valid": true
+ },
+ "email": "user@example.com",
+ "local_part": "user"
+ },
+ "x_authenticated_domain": {
+ "domain": "example.com",
+ "punycode": "xn--example-d4a.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "sub",
+ "tld": "com",
+ "valid": true
+ },
+ "x_authenticated_sender": {
+ "domain": {
+ "domain": "example.com",
+ "punycode": "example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "sub",
+ "tld": "com",
+ "valid": true
+ },
+ "email": "user@example.com",
+ "local_part": "user"
+ },
+ "x_originating_ip": {
+ "ip": "1.128.0.0"
+ },
+ "x_secure_server_account": "account_value",
+ "x_sender": {
+ "domain": {
+ "domain": "example.com",
+ "punycode": "example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "sub",
+ "tld": "com",
+ "valid": true
+ },
+ "email": "user@example.com",
+ "local_part": "user"
+ }
+ },
+ "mailbox": {
+ "email": {
+ "domain": {
+ "domain": "example.com",
+ "punycode": "xn--example-d4a.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "sub",
+ "tld": "com",
+ "valid": true
+ },
+ "local_part": "user",
+ "value": "user@example.com"
+ }
+ },
+ "meta": {
+ "canonical_id": "2fe271830bbad5fe3a70abbe7a8c0bfe79eb208a76cde267930d19f0e8cea81c",
+ "effective_at": "2024-08-02T07:40:25.135Z"
+ },
+ "recipients": {
+ "bcc": [
+ {
+ "display_name": "John Doe",
+ "email": {
+ "domain": {
+ "domain": "example.com",
+ "punycode": "xn--example-d4a.com",
+ "root_domain": "example",
+ "sld": "example",
+ "subdomain": "sub",
+ "tld": "com",
+ "valid": true
+ },
+ "local_part": "john.doe"
+ }
+ }
+ ],
+ "cc": [
+ {
+ "display_name": "Jane Smith",
+ "email": {
+ "domain": {
+ "domain": "example.org",
+ "punycode": "xn--example-d4a.org",
+ "root_domain": "example",
+ "sld": "example",
+ "subdomain": "sub",
+ "tld": "org",
+ "valid": true
+ },
+ "local_part": "jane.smith"
+ }
+ }
+ ],
+ "to": [
+ {
+ "display_name": "Alice Johnson",
+ "email": {
+ "domain": {
+ "domain": "example.com",
+ "punycode": "xn--example-d4a.net",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "sub",
+ "tld": "com",
+ "valid": true
+ },
+ "local_part": "user"
+ }
+ }
+ ]
+ },
+ "sender": {
+ "display_name": "Sublime Security Test",
+ "email": {
+ "domain": {
+ "punycode": "xn--example-d4a.com",
+ "root_domain": "sublimesecurity.com",
+ "sld": "sublimesecurity",
+ "valid": true
+ },
+ "local_part": "testing"
+ }
+ },
+ "type": {
+ "outbound": true
+ }
+ }
+ },
+ "tags": [
+ "collect_sqs_logs",
+ "preserve_original_event",
+ "forwarded",
+ "sublime_security-email_message"
+ ],
+ "url": [
+ {
+ "domain": "example.com",
+ "fragment": "search",
+ "full": "https://example.com/test?q=elasticsearch#search",
+ "password": "pass123",
+ "path": "/test",
+ "port": 80,
+ "query": "q=elasticsearch",
+ "scheme": "https",
+ "subdomain": "example",
+ "top_level_domain": "com",
+ "username": "test"
+ }
+ ],
+ "user_agent": {
+ "device": {
+ "name": "Other"
+ },
+ "name": "Other",
+ "original": "MyCustomMailer"
+ }
+}
\ No newline at end of file
diff --git a/packages/sublime_security/data_stream/message_event/_dev/deploy/docker/docker-compose.yml b/packages/sublime_security/data_stream/message_event/_dev/deploy/docker/docker-compose.yml
new file mode 100644
index 00000000000..979573f79b3
--- /dev/null
+++ b/packages/sublime_security/data_stream/message_event/_dev/deploy/docker/docker-compose.yml
@@ -0,0 +1,15 @@
+version: '2.3'
+services:
+ sublime_security:
+ image: docker.elastic.co/observability/stream:v0.15.0
+ hostname: sublime_security
+ ports:
+ - 8090
+ volumes:
+ - ./files:/files:ro
+ environment:
+ PORT: '8090'
+ command:
+ - http-server
+ - --addr=:8090
+ - --config=/files/config.yml
diff --git a/packages/sublime_security/data_stream/message_event/_dev/deploy/docker/files/config.yml b/packages/sublime_security/data_stream/message_event/_dev/deploy/docker/files/config.yml
new file mode 100644
index 00000000000..190051bb6d2
--- /dev/null
+++ b/packages/sublime_security/data_stream/message_event/_dev/deploy/docker/files/config.yml
@@ -0,0 +1,160 @@
+rules:
+ - path: /v0/message-groups
+ methods: ['GET']
+ query_params:
+ created_at__gte: "{created_at__gte:.*}"
+ created_at__lt: "{created_at__lt:.*}"
+ flagged: "{flagged:.*}"
+ limit: 1
+ offset: 0
+ request_headers:
+ Authorization:
+ - "Bearer xxxx"
+ responses:
+ - status_code: 200
+ headers:
+ Content-Type:
+ - 'application/json'
+ body: |-
+ {{ minify_json `
+ {
+ "message_groups": [
+ {
+ "messages": [
+ {
+ "id": "9c426680-5cdf-4283-adbd-d79ba0e52434"
+ },
+ {
+ "id": "26bf7e5c-4b46-4042-90de-eacb22dc1b3d"
+ }
+ ]
+ }
+ ],
+ "count": 1,
+ "total": 1,
+ "stats_limit_exceeded": false
+ }
+ `}}
+ - path: /v0/message-groups
+ methods: ['GET']
+ query_params:
+ created_at__gte: "{created_at__gte:.*}"
+ created_at__lt: "{created_at__lt:.*}"
+ flagged: "{flagged:.*}"
+ limit: 1
+ offset: 1
+ request_headers:
+ Authorization:
+ - "Bearer xxxx"
+ responses:
+ - status_code: 200
+ headers:
+ Content-Type:
+ - 'application/json'
+ body: |-
+ {{ minify_json `
+ {
+ "message_groups": [],
+ "count": 0,
+ "total": 1,
+ "stats_limit_exceeded": false
+ }
+ `}}
+ - path: /v0/messages/9c426680-5cdf-4283-adbd-d79ba0e52434
+ methods: ['GET']
+ request_headers:
+ Authorization:
+ - "Bearer xxxx"
+ responses:
+ - status_code: 200
+ headers:
+ Content-Type:
+ - 'application/json'
+ body: |-
+ {{ minify_json `
+ {
+ "id": "9c426680-5cdf-4283-adbd-d79ba0e52434",
+ "canonical_id": "dd97dc82731ff7e82edfccaef59826cccd271bd4423e09d1e150ade83037cb37",
+ "created_at": "2024-07-12T05:15:08.221838Z",
+ "external_id": "7a2dfbeb-1310-48fc-9ed9-f480608a0306",
+ "message_source_id": "257982a1-f106-4c68-bc64-ff032914ed5f",
+ "mailbox": {
+ "id": "433fe142-e2e5-4372-84ea-480279543a9b",
+ "external_id": null,
+ "email": "demo@example.com"
+ },
+ "subject": "Urgent: Wire transfer",
+ "sender": {
+ "email": "bob.demo@gmail.com",
+ "display_name": "Bob Doe"
+ },
+ "landed_in_spam": false,
+ "read_at": null,
+ "replied_at": null,
+ "forwarded_at": null,
+ "forward_recipients": [],
+ "recipients": [
+ {
+ "email": "xyz@example.com"
+ },
+ {
+ "email": "user12@example.com"
+ },
+ {
+ "email": "user@example.com"
+ },
+ {
+ "email": "leon12@example.com"
+ }
+ ]
+ }
+ `}}
+ - path: /v0/messages/26bf7e5c-4b46-4042-90de-eacb22dc1b3d
+ methods: ['GET']
+ request_headers:
+ Authorization:
+ - "Bearer xxxx"
+ responses:
+ - status_code: 200
+ headers:
+ Content-Type:
+ - 'application/json'
+ body: |-
+ {{ minify_json `
+ {
+ "id": "26bf7e5c-4b46-4042-90de-eacb22dc1b3d",
+ "canonical_id": "dd97dc82731ff7e82edfccaef59826cccd271bd4423e09d1e150ade83037cb37",
+ "created_at": "2024-07-12T05:15:10.447703Z",
+ "external_id": "88557fd9-0dee-4171-998e-9a949f01e1f5",
+ "message_source_id": "257982a1-f106-4c68-bc64-ff032914ed5f",
+ "mailbox": {
+ "id": "aae02fa3-5693-4ca5-80d0-15e082eff3bc",
+ "external_id": null,
+ "email": "user@example.com"
+ },
+ "subject": "Urgent: Wire transfer",
+ "sender": {
+ "email": "alice.demo@example.com",
+ "display_name": "Alice Doe"
+ },
+ "landed_in_spam": false,
+ "read_at": null,
+ "replied_at": null,
+ "forwarded_at": null,
+ "forward_recipients": [],
+ "recipients": [
+ {
+ "email": "abc@example.com"
+ },
+ {
+ "email": "xyz@example.com"
+ },
+ {
+ "email": "john@example.com"
+ },
+ {
+ "email": "leon@example.com"
+ }
+ ]
+ }
+ `}}
\ No newline at end of file
diff --git a/packages/sublime_security/data_stream/message_event/_dev/test/pipeline/test-common-config.yml b/packages/sublime_security/data_stream/message_event/_dev/test/pipeline/test-common-config.yml
new file mode 100644
index 00000000000..37e8fa225fd
--- /dev/null
+++ b/packages/sublime_security/data_stream/message_event/_dev/test/pipeline/test-common-config.yml
@@ -0,0 +1,3 @@
+fields:
+ tags:
+ - preserve_duplicate_custom_fields
diff --git a/packages/sublime_security/data_stream/message_event/_dev/test/pipeline/test-message-event.log b/packages/sublime_security/data_stream/message_event/_dev/test/pipeline/test-message-event.log
new file mode 100644
index 00000000000..52c0081ecc9
--- /dev/null
+++ b/packages/sublime_security/data_stream/message_event/_dev/test/pipeline/test-message-event.log
@@ -0,0 +1,2 @@
+{"id":"ef875384-6868-4e60-819a-e392f3fc1344","canonical_id":"ae608db67f666a7c92729c4a018e24362caea4c3b4b9fa00534a838dc989bab3","created_at":"2024-07-12T05:15:19.061701Z","external_id":"811a4cb9-aa1c-4e81-a0d1-21e163872c08","message_source_id":"257982a1-f106-4c68-bc64-ff032914ed5f","mailbox":{"id":"433fe142-e2e5-4372-84ea-480279543a9b","external_id":null,"email":"alice@example.com"},"subject":"Available?","sender":{"email":"alice@example.com","display_name":"Alice"},"landed_in_spam":false,"read_at":null,"replied_at":null,"forwarded_at":null,"forward_recipients":[],"recipients":[{"email":"bob@example.com"},{"email":"john@example.com"}]}
+{"created_at":"2023-05-04T01:06:50.73801Z","data":{"flagged_rules":[{"id":"958ad820-767f-4c83-ac44-94032151574f","name":"Test rule1","severity":"high","tags":["Testing"]},{"id":"2483da42-6905-4eca-bc8e-a5475ab906a4","name":"Test rule2","severity":"high","tags":["Testing"]},{"id":"9f95f7bb-b1f1-465a-a7a4-23266792c000","name":"Test rule3","severity":"low","tags":["Testing"]},{"id":"862b4f5b-c0f7-4e36-89b2-3091f9ac492b","name":"Test rule4","severity":"medium","tags":["Testing"]}],"message":{"canonical_id":"8fdb3acd8441b18478b7e80927c732f44e9086dcf7cfa6c1186ed21637427ef8","external_id":"187e44c2288f2e8d","id":"089b2e97-2107-4d1e-83e1-1920314dbb80","mailbox":{"external_id":"100712120249161713725","id":"3142d2f8-ac0d-4e37-bb1f-d5e4ff5f7f96"},"message_source_id":"d76ce576-4687-4182-b8e3-a220d6878b21"},"triggered_actions":[{"id":"9f95f7bb-b1f1-465a-a7a4-23266792c000","name":"test","type":"alert"},{"id":"9f95f7bb-b1f1-465a-a7a4-23266792c001","name":"test 1","type":"rule"}]},"type":"message.flagged"}
diff --git a/packages/sublime_security/data_stream/message_event/_dev/test/pipeline/test-message-event.log-expected.json b/packages/sublime_security/data_stream/message_event/_dev/test/pipeline/test-message-event.log-expected.json
new file mode 100644
index 00000000000..8aa37d5d26b
--- /dev/null
+++ b/packages/sublime_security/data_stream/message_event/_dev/test/pipeline/test-message-event.log-expected.json
@@ -0,0 +1,182 @@
+{
+ "expected": [
+ {
+ "@timestamp": "2024-07-12T05:15:19.061Z",
+ "ecs": {
+ "version": "8.11.0"
+ },
+ "email": {
+ "from": {
+ "address": [
+ "alice@example.com"
+ ]
+ },
+ "subject": "Available?",
+ "to": {
+ "address": [
+ "bob@example.com",
+ "john@example.com"
+ ]
+ }
+ },
+ "event": {
+ "category": [
+ "email"
+ ],
+ "id": "ef875384-6868-4e60-819a-e392f3fc1344",
+ "kind": "event",
+ "original": "{\"id\":\"ef875384-6868-4e60-819a-e392f3fc1344\",\"canonical_id\":\"ae608db67f666a7c92729c4a018e24362caea4c3b4b9fa00534a838dc989bab3\",\"created_at\":\"2024-07-12T05:15:19.061701Z\",\"external_id\":\"811a4cb9-aa1c-4e81-a0d1-21e163872c08\",\"message_source_id\":\"257982a1-f106-4c68-bc64-ff032914ed5f\",\"mailbox\":{\"id\":\"433fe142-e2e5-4372-84ea-480279543a9b\",\"external_id\":null,\"email\":\"alice@example.com\"},\"subject\":\"Available?\",\"sender\":{\"email\":\"alice@example.com\",\"display_name\":\"Alice\"},\"landed_in_spam\":false,\"read_at\":null,\"replied_at\":null,\"forwarded_at\":null,\"forward_recipients\":[],\"recipients\":[{\"email\":\"bob@example.com\"},{\"email\":\"john@example.com\"}]}",
+ "type": [
+ "info"
+ ]
+ },
+ "observer": {
+ "product": "Sublime Security",
+ "vendor": "Sublime Security"
+ },
+ "related": {
+ "user": [
+ "bob@example.com",
+ "john@example.com",
+ "Alice",
+ "alice@example.com"
+ ]
+ },
+ "source": {
+ "user": {
+ "name": "Alice"
+ }
+ },
+ "sublime_security": {
+ "message_event": {
+ "canonical_id": "ae608db67f666a7c92729c4a018e24362caea4c3b4b9fa00534a838dc989bab3",
+ "created_at": "2024-07-12T05:15:19.061Z",
+ "external_id": "811a4cb9-aa1c-4e81-a0d1-21e163872c08",
+ "id": "ef875384-6868-4e60-819a-e392f3fc1344",
+ "landed_in_spam": false,
+ "mailbox": {
+ "email": "alice@example.com",
+ "id": "433fe142-e2e5-4372-84ea-480279543a9b"
+ },
+ "message_source_id": "257982a1-f106-4c68-bc64-ff032914ed5f",
+ "recipients": [
+ {
+ "email": "bob@example.com"
+ },
+ {
+ "email": "john@example.com"
+ }
+ ],
+ "sender": {
+ "display_name": "Alice",
+ "email": "alice@example.com"
+ },
+ "subject": "Available?"
+ }
+ },
+ "tags": [
+ "preserve_duplicate_custom_fields"
+ ]
+ },
+ {
+ "@timestamp": "2023-05-04T01:06:50.738Z",
+ "ecs": {
+ "version": "8.11.0"
+ },
+ "event": {
+ "category": [
+ "email"
+ ],
+ "id": "089b2e97-2107-4d1e-83e1-1920314dbb80",
+ "kind": "event",
+ "original": "{\"created_at\":\"2023-05-04T01:06:50.73801Z\",\"data\":{\"flagged_rules\":[{\"id\":\"958ad820-767f-4c83-ac44-94032151574f\",\"name\":\"Test rule1\",\"severity\":\"high\",\"tags\":[\"Testing\"]},{\"id\":\"2483da42-6905-4eca-bc8e-a5475ab906a4\",\"name\":\"Test rule2\",\"severity\":\"high\",\"tags\":[\"Testing\"]},{\"id\":\"9f95f7bb-b1f1-465a-a7a4-23266792c000\",\"name\":\"Test rule3\",\"severity\":\"low\",\"tags\":[\"Testing\"]},{\"id\":\"862b4f5b-c0f7-4e36-89b2-3091f9ac492b\",\"name\":\"Test rule4\",\"severity\":\"medium\",\"tags\":[\"Testing\"]}],\"message\":{\"canonical_id\":\"8fdb3acd8441b18478b7e80927c732f44e9086dcf7cfa6c1186ed21637427ef8\",\"external_id\":\"187e44c2288f2e8d\",\"id\":\"089b2e97-2107-4d1e-83e1-1920314dbb80\",\"mailbox\":{\"external_id\":\"100712120249161713725\",\"id\":\"3142d2f8-ac0d-4e37-bb1f-d5e4ff5f7f96\"},\"message_source_id\":\"d76ce576-4687-4182-b8e3-a220d6878b21\"},\"triggered_actions\":[{\"id\":\"9f95f7bb-b1f1-465a-a7a4-23266792c000\",\"name\":\"test\",\"type\":\"alert\"},{\"id\":\"9f95f7bb-b1f1-465a-a7a4-23266792c001\",\"name\":\"test 1\",\"type\":\"rule\"}]},\"type\":\"message.flagged\"}",
+ "type": [
+ "info"
+ ]
+ },
+ "observer": {
+ "product": "Sublime Security",
+ "vendor": "Sublime Security"
+ },
+ "rule": {
+ "id": [
+ "958ad820-767f-4c83-ac44-94032151574f",
+ "2483da42-6905-4eca-bc8e-a5475ab906a4",
+ "9f95f7bb-b1f1-465a-a7a4-23266792c000",
+ "862b4f5b-c0f7-4e36-89b2-3091f9ac492b"
+ ],
+ "name": [
+ "Test rule1",
+ "Test rule2",
+ "Test rule3",
+ "Test rule4"
+ ]
+ },
+ "sublime_security": {
+ "message_event": {
+ "canonical_id": "8fdb3acd8441b18478b7e80927c732f44e9086dcf7cfa6c1186ed21637427ef8",
+ "created_at": "2023-05-04T01:06:50.738Z",
+ "data": {
+ "flagged_rules": [
+ {
+ "id": "958ad820-767f-4c83-ac44-94032151574f",
+ "name": "Test rule1",
+ "severity": "high",
+ "tags": [
+ "Testing"
+ ]
+ },
+ {
+ "id": "2483da42-6905-4eca-bc8e-a5475ab906a4",
+ "name": "Test rule2",
+ "severity": "high",
+ "tags": [
+ "Testing"
+ ]
+ },
+ {
+ "id": "9f95f7bb-b1f1-465a-a7a4-23266792c000",
+ "name": "Test rule3",
+ "severity": "low",
+ "tags": [
+ "Testing"
+ ]
+ },
+ {
+ "id": "862b4f5b-c0f7-4e36-89b2-3091f9ac492b",
+ "name": "Test rule4",
+ "severity": "medium",
+ "tags": [
+ "Testing"
+ ]
+ }
+ ],
+ "triggered_actions": [
+ {
+ "id": "9f95f7bb-b1f1-465a-a7a4-23266792c000",
+ "name": "test",
+ "type": "alert"
+ },
+ {
+ "id": "9f95f7bb-b1f1-465a-a7a4-23266792c001",
+ "name": "test 1",
+ "type": "rule"
+ }
+ ]
+ },
+ "external_id": "187e44c2288f2e8d",
+ "id": "089b2e97-2107-4d1e-83e1-1920314dbb80",
+ "mailbox": {
+ "external_id": "100712120249161713725",
+ "id": "3142d2f8-ac0d-4e37-bb1f-d5e4ff5f7f96"
+ },
+ "message_source_id": "d76ce576-4687-4182-b8e3-a220d6878b21",
+ "type": "message.flagged"
+ }
+ },
+ "tags": [
+ "preserve_duplicate_custom_fields"
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/packages/sublime_security/data_stream/message_event/_dev/test/system/test-cel-config.yml b/packages/sublime_security/data_stream/message_event/_dev/test/system/test-cel-config.yml
new file mode 100644
index 00000000000..6d2105a4317
--- /dev/null
+++ b/packages/sublime_security/data_stream/message_event/_dev/test/system/test-cel-config.yml
@@ -0,0 +1,14 @@
+input: cel
+service: sublime_security
+vars:
+ url: http://{{Hostname}}:{{Port}}
+ api_key: xxxx
+data_stream:
+ vars:
+ interval: 5m
+ initial_interval: 24h
+ page_size: 1
+ preserve_original_event: true
+ preserve_duplicate_custom_fields: true
+assert:
+ hit_count: 2
diff --git a/packages/sublime_security/data_stream/message_event/agent/stream/aws-s3.yml.hbs b/packages/sublime_security/data_stream/message_event/agent/stream/aws-s3.yml.hbs
new file mode 100644
index 00000000000..7bf0e86682e
--- /dev/null
+++ b/packages/sublime_security/data_stream/message_event/agent/stream/aws-s3.yml.hbs
@@ -0,0 +1,97 @@
+{{#if collect_s3_logs}}
+
+{{#if bucket_arn}}
+bucket_arn: {{bucket_arn}}
+{{/if}}
+{{#if number_of_workers}}
+number_of_workers: {{number_of_workers}}
+{{/if}}
+{{#if interval}}
+bucket_list_interval: {{interval}}
+{{/if}}
+{{#if bucket_list_prefix}}
+bucket_list_prefix: {{bucket_list_prefix}}
+{{/if}}
+
+{{else}}
+
+{{#if queue_url}}
+queue_url: {{queue_url}}
+{{/if}}
+{{#if region}}
+region: {{region}}
+{{/if}}
+{{#if visibility_timeout}}
+visibility_timeout: {{visibility_timeout}}
+{{/if}}
+{{#if api_timeout}}
+api_timeout: {{api_timeout}}
+{{/if}}
+{{#if max_number_of_messages}}
+max_number_of_messages: {{max_number_of_messages}}
+{{/if}}
+{{#if file_selectors}}
+file_selectors:
+{{file_selectors}}
+{{/if}}
+
+{{/if}}
+
+expand_event_list_from_field: events
+content_type: application/json
+{{#if access_key_id}}
+access_key_id: {{access_key_id}}
+{{/if}}
+{{#if secret_access_key}}
+secret_access_key: {{secret_access_key}}
+{{/if}}
+{{#if session_token}}
+session_token: {{session_token}}
+{{/if}}
+{{#if shared_credential_file}}
+shared_credential_file: {{shared_credential_file}}
+{{/if}}
+{{#if credential_profile_name}}
+credential_profile_name: {{credential_profile_name}}
+{{/if}}
+{{#if role_arn}}
+role_arn: {{role_arn}}
+{{/if}}
+{{#if external_id}}
+external_id: {{external_id}}
+{{/if}}
+{{#if default_region}}
+default_region: {{default_region}}
+{{/if}}
+
+{{#if fips_enabled}}
+fips_enabled: {{fips_enabled}}
+{{/if}}
+{{#if proxy_url}}
+proxy_url: {{proxy_url}}
+{{/if}}
+{{#if ssl}}
+ssl: {{ssl}}
+{{/if}}
+tags:
+{{#if collect_s3_logs}}
+ - collect_s3_logs
+{{else}}
+ - collect_sqs_logs
+{{/if}}
+{{#if preserve_original_event}}
+ - preserve_original_event
+{{/if}}
+{{#if preserve_duplicate_custom_fields}}
+ - preserve_duplicate_custom_fields
+{{/if}}
+{{#each tags as |tag|}}
+ - {{tag}}
+{{/each}}
+{{#contains "forwarded" tags}}
+publisher_pipeline.disable_host: true
+{{/contains}}
+{{#if processors}}
+processors:
+{{processors}}
+{{/if}}
diff --git a/packages/sublime_security/data_stream/message_event/agent/stream/cel.yml.hbs b/packages/sublime_security/data_stream/message_event/agent/stream/cel.yml.hbs
new file mode 100644
index 00000000000..38a2113a64d
--- /dev/null
+++ b/packages/sublime_security/data_stream/message_event/agent/stream/cel.yml.hbs
@@ -0,0 +1,148 @@
+config_version: 2
+interval: {{interval}}
+{{#if enable_request_tracer}}
+resource.tracer.filename: "../../logs/cel/http-request-trace-*.ndjson"
+resource.tracer.maxbackups: 5
+{{/if}}
+{{#if proxy_url}}
+resource.proxy_url: {{proxy_url}}
+{{/if}}
+{{#if ssl}}
+resource.ssl: {{ssl}}
+{{/if}}
+{{#if http_client_timeout}}
+resource.timeout: {{http_client_timeout}}
+{{/if}}
+resource.url: {{url}}
+state:
+ page_size: {{page_size}}
+ offset: 0
+ initial_interval: {{initial_interval}}
+ api_key: {{api_key}}
+redact:
+ fields:
+ - api_key
+program: |
+ (
+ has(state.worklist) && size(state.worklist) > 0 ?
+ state
+ :
+ (
+ state.?want_more.orValue(false) ?
+ state
+ :
+ state.with({
+ "start_time": state.?cursor.last_timestamp.orValue((now - duration(state.initial_interval)).format(time_layout.RFC3339)),
+ "end_time": now.format(time_layout.RFC3339),
+ })
+ ).as(state, state.with(
+ request(
+ "GET",
+ state.url.trim_right("/") + "/v0/message-groups?" + {
+ "created_at__gte": [state.start_time],
+ "created_at__lt": [state.end_time],
+ "flagged": ["true"],
+ "limit": [string(state.page_size)],
+ "offset": [string(state.offset)]
+ }.format_query()
+ ).with({
+ "Header": {
+ "Authorization": ["Bearer " + state.api_key],
+ },
+ }).do_request().as(resp, resp.StatusCode == 200 ?
+ (
+ bytes(resp.Body).decode_json().as(body,{
+ "worklist": size(body.message_groups) > 0 ?
+ body.message_groups.map(group,
+ has(group.messages) && size(group.messages) > 0 ? group.messages.map(e, e.id) : []
+ ).flatten()
+ :
+ [],
+ "next": 0,
+ })
+ )
+ :
+ {
+ "events": {
+ "error": {
+ "code": string(resp.StatusCode),
+ "id": string(resp.Status),
+ "message": "GET:"+(
+ size(resp.Body) != 0 ?
+ string(resp.Body)
+ :
+ string(resp.Status) + ' (' + string(resp.StatusCode) + ')'
+ ),
+ },
+ },
+ "want_more": false,
+ }
+ )
+ ))
+ ).as(state, state.with(
+ !has(state.worklist) ? state :
+ int(state.next) < size(state.worklist) ?
+ request(
+ "GET",
+ state.url.trim_right("/") + "/v0/messages/" + state.worklist[state.next]
+ ).with({
+ "Header": {
+ "Authorization": ["Bearer " + string(state.api_key)],
+ },
+ }).do_request().as(resp,resp.StatusCode == 200 ?
+ bytes(resp.Body).decode_json().as(body,{
+ "events": [{
+ "message": body.encode_json(),
+ }],
+ "cursor": {
+ "last_timestamp": state.end_time
+ },
+ "worklist": (int(state.next) + 1) < size(state.worklist) ? state.worklist : [],
+ "next": (int(state.next) + 1) < size(state.worklist) ? (int(state.next) + 1 ) : 0,
+ "offset": (int(state.next) + 1) < size(state.worklist) ? state.offset : int(state.offset) + int(state.page_size),
+ "want_more": true,
+ })
+ :
+ {
+ "events": {
+ "error": {
+ "code": string(resp.StatusCode),
+ "id": string(resp.Status),
+ "message": "GET:"+(
+ size(resp.Body) != 0 ?
+ string(resp.Body)
+ :
+ string(resp.Status) + ' (' + string(resp.StatusCode) + ')'
+ ),
+ },
+ },
+ "want_more": false,
+ }
+ )
+ :
+ {
+ "events": [],
+ "want_more": false,
+ "offset": 0,
+ "cursor": {
+ "last_timestamp": state.end_time
+ },
+ }
+ ))
+tags:
+{{#if preserve_original_event}}
+ - preserve_original_event
+{{/if}}
+{{#if preserve_duplicate_custom_fields}}
+ - preserve_duplicate_custom_fields
+{{/if}}
+{{#each tags as |tag|}}
+ - {{tag}}
+{{/each}}
+{{#contains "forwarded" tags}}
+publisher_pipeline.disable_host: true
+{{/contains}}
+{{#if processors}}
+processors:
+{{processors}}
+{{/if}}
\ No newline at end of file
diff --git a/packages/sublime_security/data_stream/message_event/elasticsearch/ingest_pipeline/default.yml b/packages/sublime_security/data_stream/message_event/elasticsearch/ingest_pipeline/default.yml
new file mode 100644
index 00000000000..78c906df39f
--- /dev/null
+++ b/packages/sublime_security/data_stream/message_event/elasticsearch/ingest_pipeline/default.yml
@@ -0,0 +1,362 @@
+---
+description: Pipeline for processing message_event logs.
+processors:
+ - set:
+ field: ecs.version
+ tag: set_ecs_version
+ value: 8.11.0
+ - fail:
+ tag: data_collection_error
+ if: ctx.error?.message != null && ctx.message == null && ctx.event?.original == null
+ message: error message set and no data to process.
+ - rename:
+ field: message
+ tag: rename_message_to_event_original
+ target_field: event.original
+ ignore_missing: true
+ description: Renames the original `message` field to `event.original` to store a copy of the original message. The `event.original` field is not touched if the document already has one; it may happen when Logstash sends the document.
+ if: ctx.event?.original == null
+ - remove:
+ field: message
+ tag: remove_message
+ ignore_missing: true
+ description: The `message` field is no longer required if the document has an `event.original` field.
+ if: ctx.event?.original != null
+ - json:
+ field: event.original
+ tag: json_event_original
+ target_field: json
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - set:
+ field: event.kind
+ tag: set_event_kind_to_event
+ value: event
+ - append:
+ field: event.category
+ tag: append_email_into_event_category
+ value: email
+ - append:
+ field: event.type
+ tag: append_info_into_event_type
+ value: info
+ - set:
+ field: observer.vendor
+ tag: set_observer_vendor
+ value: Sublime Security
+ - set:
+ field: observer.product
+ tag: set_observer_product
+ value: Sublime Security
+ - rename:
+ field: json.data.message.canonical_id
+ tag: rename_data_message_canonicalid
+ target_field: sublime_security.message_event.canonical_id
+ ignore_missing: true
+ - rename:
+ field: json.canonical_id
+ tag: rename_canonical_id
+ target_field: sublime_security.message_event.canonical_id
+ ignore_missing: true
+ - date:
+ field: json.created_at
+ tag: date_created_at
+ target_field: sublime_security.message_event.created_at
+ formats:
+ - ISO8601
+ if: ctx.json?.created_at != null && ctx.json.created_at != ''
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - set:
+ field: '@timestamp'
+ tag: set_@timestamp_from_message_event_created_at
+ copy_from: sublime_security.message_event.created_at
+ ignore_empty_value: true
+ - foreach:
+ field: json.data.flagged_rules
+ if: ctx.json?.data?.flagged_rules instanceof List
+ processor:
+ append:
+ field: rule.id
+ tag: append_data_flagged_rules_id_into_rule_id
+ value: '{{{_ingest._value.id}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.data.flagged_rules
+ if: ctx.json?.data?.flagged_rules instanceof List
+ processor:
+ append:
+ field: rule.name
+ tag: append_data_flagged_rules_name_into_rule_name
+ value: '{{{_ingest._value.name}}}'
+ allow_duplicates: false
+ - rename:
+ field: json.data.flagged_rules
+ tag: rename_data_flagged_rules
+ target_field: sublime_security.message_event.data.flagged_rules
+ ignore_missing: true
+ - foreach:
+ field: sublime_security.message_event.data.flagged_rules
+ tag: foreach_sublime_security_message_event_data_flagged_rules_to_remove_id_and_name
+ if: ctx.sublime_security?.message_event?.data?.flagged_rules instanceof List
+ processor:
+ remove:
+ field:
+ - _ingest._value.id
+ - _ingest._value.name
+ tag: remove_duplicate_custom_fields_from_data_flagged_rules_array
+ ignore_missing: true
+ if: ctx.tags == null || !(ctx.tags.contains('preserve_duplicate_custom_fields'))
+ - rename:
+ field: json.data.triggered_actions
+ tag: rename_data_triggered_actions
+ target_field: sublime_security.message_event.data.triggered_actions
+ ignore_missing: true
+ - rename:
+ field: json.data.message.external_id
+ tag: rename_data_message_external_id
+ target_field: sublime_security.message_event.external_id
+ ignore_missing: true
+ - rename:
+ field: json.external_id
+ tag: rename_external_id
+ target_field: sublime_security.message_event.external_id
+ ignore_missing: true
+ - rename:
+ field: json.forward_recipients
+ tag: rename_forward_recipients
+ target_field: sublime_security.message_event.forward_recipients
+ ignore_missing: true
+ - date:
+ field: json.forwarded_at
+ tag: date_forwarded_at
+ target_field: sublime_security.message_event.forwarded_at
+ formats:
+ - ISO8601
+ if: ctx.json?.forwarded_at != null && ctx.json.forwarded_at != ''
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - rename:
+ field: json.data.message.id
+ tag: rename_data_message_id
+ target_field: sublime_security.message_event.id
+ ignore_missing: true
+ - rename:
+ field: json.id
+ tag: rename_id
+ target_field: sublime_security.message_event.id
+ ignore_missing: true
+ - set:
+ field: event.id
+ tag: set_event_id_from_message_event_id
+ copy_from: sublime_security.message_event.id
+ ignore_empty_value: true
+ - convert:
+ field: json.landed_in_spam
+ tag: convert_landed_in_spam_to_boolean
+ target_field: sublime_security.message_event.landed_in_spam
+ type: boolean
+ ignore_missing: true
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - rename:
+ field: json.mailbox.email
+ tag: rename_mailbox_email
+ target_field: sublime_security.message_event.mailbox.email
+ ignore_missing: true
+ - rename:
+ field: json.data.message.mailbox.external_id
+ tag: rename_data_message_mailbox_external_id
+ target_field: sublime_security.message_event.mailbox.external_id
+ ignore_missing: true
+ - rename:
+ field: json.mailbox.external_id
+ tag: rename_mailbox_external_id
+ target_field: sublime_security.message_event.mailbox.external_id
+ ignore_missing: true
+ - rename:
+ field: json.data.message.mailbox.id
+ tag: rename_data_message_mailbox_id
+ target_field: sublime_security.message_event.mailbox.id
+ ignore_missing: true
+ - rename:
+ field: json.mailbox.id
+ tag: rename_mailbox_id
+ target_field: sublime_security.message_event.mailbox.id
+ ignore_missing: true
+ - rename:
+ field: json.data.message.message_source_id
+ tag: rename_data_message_message_source_id
+ target_field: sublime_security.message_event.message_source_id
+ ignore_missing: true
+ - rename:
+ field: json.message_source_id
+ tag: rename_message_source_id
+ target_field: sublime_security.message_event.message_source_id
+ ignore_missing: true
+ - date:
+ field: json.read_at
+ tag: date_read_at
+ target_field: sublime_security.message_event.read_at
+ formats:
+ - ISO8601
+ if: ctx.json?.read_at != null && ctx.json.read_at != ''
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - foreach:
+ field: json.recipients
+ if: ctx.json?.recipients instanceof List
+ processor:
+ append:
+ field: email.to.address
+ tag: append_recipients_email_into_email_to_address
+ value: '{{{_ingest._value.email}}}'
+ allow_duplicates: false
+ - foreach:
+ field: json.recipients
+ if: ctx.json?.recipients instanceof List
+ processor:
+ append:
+ field: related.user
+ tag: append_recipients_email_into_related.user
+ value: '{{{_ingest._value.email}}}'
+ allow_duplicates: false
+ - rename:
+ field: json.recipients
+ tag: rename_recipients
+ target_field: sublime_security.message_event.recipients
+ ignore_missing: true
+ - date:
+ field: json.replied_at
+ tag: date_replied_at
+ target_field: sublime_security.message_event.replied_at
+ formats:
+ - ISO8601
+ if: ctx.json?.replied_at != null && ctx.json.replied_at != ''
+ on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - rename:
+ field: json.sender.display_name
+ tag: rename_sender_display_name
+ target_field: sublime_security.message_event.sender.display_name
+ ignore_missing: true
+ - set:
+ field: source.user.name
+ tag: set_source_user_name_from_message_event_sender_display_name
+ copy_from: sublime_security.message_event.sender.display_name
+ ignore_empty_value: true
+ - append:
+ field: related.user
+ tag: append_sublime_security_message_event_sender_display_name_into_related_user
+ value: '{{{sublime_security.message_event.sender.display_name}}}'
+ allow_duplicates: false
+ if: ctx.sublime_security?.message_event?.sender?.display_name != null
+ - rename:
+ field: json.sender.email
+ tag: rename_sender_email
+ target_field: sublime_security.message_event.sender.email
+ ignore_missing: true
+ - append:
+ field: email.from.address
+ tag: append_sublime_security_message_event_sender_email_into_email_from_address
+ value: '{{{sublime_security.message_event.sender.email}}}'
+ allow_duplicates: false
+ if: ctx.sublime_security?.message_event?.sender?.email != null
+ - append:
+ field: related.user
+ tag: append_sublime_security_message_event_sender_email_into_related_user
+ value: '{{{sublime_security.message_event.sender.email}}}'
+ allow_duplicates: false
+ if: ctx.sublime_security?.message_event?.sender?.email != null
+ - rename:
+ field: json.subject
+ tag: rename_subject
+ target_field: sublime_security.message_event.subject
+ ignore_missing: true
+ - set:
+ field: email.subject
+ tag: set_email_subject_from_message_event_subject
+ copy_from: sublime_security.message_event.subject
+ ignore_empty_value: true
+ - rename:
+ field: json.type
+ tag: rename_type
+ target_field: sublime_security.message_event.type
+ ignore_missing: true
+ - foreach:
+ field: sublime_security.message_event.data.flagged_rules
+ if: ctx.sublime_security?.message_event?.data?.flagged_rules instanceof List
+ processor:
+ remove:
+ field:
+ - _ingest._value.id
+ - _ingest._value.name
+ tag: remove_custom_duplicate_fields_from_sublime_security_message_event_data_flagged_rules
+ ignore_missing: true
+ if: ctx.tags == null || !(ctx.tags.contains('preserve_duplicate_custom_fields'))
+ - foreach:
+ field: sublime_security.message_event.recipients
+ if: ctx.sublime_security?.message_event?.recipients instanceof List
+ processor:
+ remove:
+ field: _ingest._value.email
+ tag: remove_custom_duplicate_fields_from_sublime_security_message_event_recipients
+ ignore_missing: true
+ if: ctx.tags == null || !(ctx.tags.contains('preserve_duplicate_custom_fields'))
+ - remove:
+ field:
+ - sublime_security.message_event.created_at
+ - sublime_security.message_event.id
+ - sublime_security.message_event.sender.display_name
+ - sublime_security.message_event.sender.email
+ - sublime_security.message_event.subject
+ tag: remove_custom_duplicate_fields
+ ignore_missing: true
+ if: ctx.tags == null || !(ctx.tags.contains('preserve_duplicate_custom_fields'))
+ - remove:
+ field: json
+ tag: remove_json
+ ignore_missing: true
+ - script:
+ lang: painless
+ description: Drops null/empty values recursively.
+ tag: painless_remove_null
+ source: |-
+ boolean drop(Object object) {
+ if (object == null || object == '') {
+ return true;
+ } else if (object instanceof Map) {
+ ((Map) object).values().removeIf(v -> drop(v));
+ return (((Map) object).size() == 0);
+ } else if (object instanceof List) {
+ ((List) object).removeIf(v -> drop(v));
+ return (((List) object).length == 0);
+ }
+ return false;
+ }
+ drop(ctx);
+ - set:
+ field: event.kind
+ value: pipeline_error
+ tag: set_pipeline_error_into_event_kind
+ if: ctx.error?.message != null
+on_failure:
+ - append:
+ field: error.message
+ value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}'
+ - set:
+ field: event.kind
+ tag: set_pipeline_error_to_event_kind
+ value: pipeline_error
diff --git a/packages/sublime_security/data_stream/message_event/fields/base-fields.yml b/packages/sublime_security/data_stream/message_event/fields/base-fields.yml
new file mode 100644
index 00000000000..99f454dd95b
--- /dev/null
+++ b/packages/sublime_security/data_stream/message_event/fields/base-fields.yml
@@ -0,0 +1,20 @@
+- name: data_stream.type
+ type: constant_keyword
+ description: Data stream type.
+- name: data_stream.dataset
+ type: constant_keyword
+ description: Data stream dataset.
+- name: data_stream.namespace
+ type: constant_keyword
+ description: Data stream namespace.
+- name: event.module
+ type: constant_keyword
+ description: Event module.
+ value: sublime_security
+- name: event.dataset
+ type: constant_keyword
+ description: Event dataset.
+ value: sublime_security.message_event
+- name: '@timestamp'
+ type: date
+ description: Event timestamp.
diff --git a/packages/sublime_security/data_stream/message_event/fields/beats.yml b/packages/sublime_security/data_stream/message_event/fields/beats.yml
new file mode 100644
index 00000000000..4084f1dc7f5
--- /dev/null
+++ b/packages/sublime_security/data_stream/message_event/fields/beats.yml
@@ -0,0 +1,6 @@
+- name: input.type
+ type: keyword
+ description: Type of filebeat input.
+- name: log.offset
+ type: long
+ description: Log offset.
diff --git a/packages/sublime_security/data_stream/message_event/fields/fields.yml b/packages/sublime_security/data_stream/message_event/fields/fields.yml
new file mode 100644
index 00000000000..842ba38b1d8
--- /dev/null
+++ b/packages/sublime_security/data_stream/message_event/fields/fields.yml
@@ -0,0 +1,95 @@
+- name: sublime_security
+ type: group
+ fields:
+ - name: message_event
+ type: group
+ fields:
+ - name: canonical_id
+ type: keyword
+ description: Canonical ID of the message.
+ - name: created_at
+ type: date
+ description: Time this message was added to sublime_security.
+ - name: data
+ type: group
+ fields:
+ - name: flagged_rules
+ type: group
+ fields:
+ - name: id
+ type: keyword
+ description: ID of the flagged rule.
+ - name: name
+ type: keyword
+ description: Name of the flagged rule.
+ - name: severity
+ type: keyword
+ description: Severity of the flagged rule.
+ - name: tags
+ type: keyword
+ description: List of tags for the flagged rule.
+ - name: triggered_actions
+ type: group
+ fields:
+ - name: id
+ type: keyword
+ - name: name
+ type: keyword
+ - name: type
+ type: keyword
+ - name: external_id
+ type: keyword
+ description: ID of the message in the source system (e.g., Office 365 or Google Workspace).
+ - name: forward_recipients
+ type: keyword
+ description: Email addresses this message was forwarded to by the recipient mailbox.
+ - name: forwarded_at
+ type: date
+ description: Time this message was forwarded by the recipient mailbox. A null value indicates that it has not yet been forwarded.
+ - name: id
+ type: keyword
+ description: Message ID.
+ - name: landed_in_spam
+ type: boolean
+ description: Whether the message landed in the recipient's spam folder.
+ - name: mailbox
+ type: group
+ fields:
+ - name: email
+ type: keyword
+ description: Mailbox email address.
+ - name: external_id
+ type: keyword
+ description: ID of the mailbox in the source system (e.g., Office 365 or Google Workspace).
+ - name: id
+ type: keyword
+ description: Mailbox ID.
+ - name: message_source_id
+ type: keyword
+ description: ID of the message source of the message.
+ - name: read_at
+ type: date
+ description: Time this message was read in the user's mailbox. A null value indicates that it has not yet been marked read.
+ - name: recipients
+ type: group
+ fields:
+ - name: email
+ type: keyword
+ description: Email address.
+ - name: replied_at
+ type: date
+ description: Time that this message was replied to by the recipient mailbox. A null value indicates that it has not yet been replied to by the recipient.
+ - name: sender
+ type: group
+ fields:
+ - name: display_name
+ type: keyword
+ description: Display name.
+ - name: email
+ type: keyword
+ description: Email address.
+ - name: subject
+ type: keyword
+ description: Subject of the message.
+ - name: type
+ type: keyword
diff --git a/packages/sublime_security/data_stream/message_event/manifest.yml b/packages/sublime_security/data_stream/message_event/manifest.yml
new file mode 100644
index 00000000000..316eff85db9
--- /dev/null
+++ b/packages/sublime_security/data_stream/message_event/manifest.yml
@@ -0,0 +1,196 @@
+title: Sublime Security Message Event logs
+type: logs
+streams:
+ - input: cel
+ title: Sublime Security Message Event logs
+ description: Collecting Sublime Security Message Event logs via API.
+ enabled: false
+ template_path: cel.yml.hbs
+ vars:
+ - name: initial_interval
+ type: text
+ title: Initial Interval
+ multi: false
+ required: true
+ show_user: true
+ default: 24h
+ description: How far back to pull the Message Event logs from Sublime Security API. Supported units for this parameter are h/m/s.
+ - name: interval
+ type: text
+ title: Interval
+ description: Duration between requests to the Sublime Security API. Supported units for this parameter are h/m/s.
+ default: 1h
+ multi: false
+ required: true
+ show_user: true
+ - name: page_size
+ type: text
+ title: Page Size
+ multi: false
+ required: true
+ show_user: false
+ description: Page size for the response of the Sublime Security API.
+ default: 500
+ - name: http_client_timeout
+ type: text
+ title: HTTP Client Timeout
+ description: Duration before declaring that the HTTP client connection has timed out. Supported time units are ns, us, ms, s, m, h.
+ multi: false
+ required: true
+ show_user: false
+ default: 30s
+ - name: enable_request_tracer
+ type: bool
+ title: Enable request tracing
+ multi: false
+ required: false
+ show_user: false
+ description: >-
+ The request tracer logs requests and responses to the agent's local file-system for debugging configurations. Enabling this request tracing compromises security and should only be used for debugging. See [documentation](https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-input-cel.html#_resource_tracer_filename) for details.
+ - name: tags
+ type: text
+ title: Tags
+ multi: true
+ required: true
+ show_user: false
+ default:
+ - forwarded
+ - sublime_security-message_event
+ - name: preserve_original_event
+ required: false
+ show_user: true
+ title: Preserve original event
+ description: Preserves a raw copy of the original event, added to the field `event.original`.
+ type: bool
+ multi: false
+ default: false
+ - name: preserve_duplicate_custom_fields
+ required: false
+ show_user: false
+ title: Preserve duplicate custom fields
+ description: Preserve sublime_security.message_event fields that were copied to Elastic Common Schema (ECS) fields.
+ type: bool
+ multi: false
+ default: false
+ - name: processors
+ type: yaml
+ title: Processors
+ multi: false
+ required: false
+ show_user: false
+ description: >-
+ Processors are used to reduce the number of fields in the exported event or to enhance the event with metadata. This executes in the agent before the logs are parsed.
+ - input: aws-s3
+ template_path: aws-s3.yml.hbs
+ title: Sublime Security Message Event logs via AWS S3 or SQS
+ description: Collecting Sublime Security Message Event logs via AWS S3 or SQS input.
+ enabled: false
+ vars:
+ - name: bucket_arn
+ type: text
+ title: '[S3] Bucket ARN'
+ multi: false
+ required: false
+ show_user: true
+ description: ARN of the AWS S3 bucket that will be polled for list operation. It is a required parameter for collecting logs via the AWS S3.
+ - name: bucket_list_prefix
+ type: text
+ title: '[S3] Bucket Prefix'
+ multi: false
+ required: false
+ show_user: true
+ description: Prefix to apply for the list request to the S3 bucket.
+ - name: interval
+ type: text
+ title: '[S3] Interval'
+ multi: false
+ required: false
+ show_user: true
+ default: 120s
+ description: Listing of the S3 bucket will be polled according to the time interval defined by bucket_list_interval config. Default value is 120 secs. Supported units for this parameter are h/m/s.
+ - name: number_of_workers
+ type: integer
+ title: '[S3] Number of Workers'
+ multi: false
+ required: false
+ show_user: true
+ default: 5
+ description: Number of workers that will process the S3 objects listed.
+ - name: queue_url
+ type: text
+ title: '[SQS] Queue URL'
+ multi: false
+ required: false
+ show_user: true
+ description: URL of the AWS SQS queue that messages will be received from. It is a required parameter for collecting logs via the AWS SQS.
+ - name: visibility_timeout
+ type: text
+ title: '[SQS] Visibility Timeout'
+ multi: false
+ required: false
+ show_user: true
+ default: 300s
+ description: The duration that the received messages are hidden from subsequent retrieve requests after being retrieved by a ReceiveMessage request. The maximum is 12 hours. Supported units for this parameter are h/m/s.
+ - name: api_timeout
+ type: text
+ title: '[SQS] API Timeout'
+ multi: false
+ required: false
+ show_user: true
+ default: 120s
+ description: The maximum duration of AWS API can take. The maximum is half of the visibility timeout value. Supported units for this parameter are h/m/s.
+ - name: max_number_of_messages
+ type: integer
+ title: '[SQS] Maximum Concurrent SQS Messages'
+ required: false
+ show_user: true
+ default: 5
+ description: The maximum number of SQS messages that can be inflight at any time.
+ - name: file_selectors
+ type: yaml
+ title: '[SQS] File Selectors'
+ multi: false
+ required: false
+ show_user: false
+ description: >-
+ If the SQS queue will have events that correspond to files that this integration shouldn’t process, file_selectors can be used to limit the files that are downloaded. This is a list of selectors which are made up of regex and expand_event_list_from_field options. The regex should match the S3 object key in the SQS message, and the optional expand_event_list_from_field is the same as the global setting. If file_selectors is given, then any global expand_event_list_from_field value is ignored in favor of the ones specified in the file_selectors. Regexes use [RE2 syntax](https://pkg.go.dev/regexp/syntax). Files that do not match one of the regexes will not be processed.
+ - name: external_id
+ type: text
+ title: External ID
+ multi: false
+ required: false
+ show_user: false
+ description: External ID to use when assuming a role in another account.
+ - name: tags
+ type: text
+ title: Tags
+ multi: true
+ required: true
+ show_user: false
+ default:
+ - forwarded
+ - sublime_security-message_event
+ - name: preserve_original_event
+ required: false
+ show_user: true
+ title: Preserve original event
+ description: Preserves a raw copy of the original event, added to the field `event.original`.
+ type: bool
+ multi: false
+ default: false
+ - name: preserve_duplicate_custom_fields
+ required: true
+ show_user: false
+ title: Preserve duplicate custom fields
+ description: Preserve sublime_security.message_event fields that were mapped to Elastic Common Schema (ECS) fields.
+ type: bool
+ multi: false
+ default: false
+ - name: processors
+ type: yaml
+ title: Processors
+ multi: false
+ required: false
+ show_user: false
+ description: >-
+ Processors are used to reduce the number of fields in the exported event or to enhance the event with metadata. This executes in the agent before the logs are parsed. See [Processors](https://www.elastic.co/guide/en/beats/filebeat/current/filtering-and-enhancing-data.html) for details.
diff --git a/packages/sublime_security/data_stream/message_event/sample_event.json b/packages/sublime_security/data_stream/message_event/sample_event.json
new file mode 100644
index 00000000000..8e2abc970d2
--- /dev/null
+++ b/packages/sublime_security/data_stream/message_event/sample_event.json
@@ -0,0 +1,114 @@
+{
+ "@timestamp": "2024-07-12T05:15:08.221Z",
+ "agent": {
+ "ephemeral_id": "384edc61-b94b-40cf-9cc6-86d5418d35e5",
+ "id": "5f3fcbb9-1a97-4ff3-857f-167af6664464",
+ "name": "docker-fleet-agent",
+ "type": "filebeat",
+ "version": "8.13.0"
+ },
+ "data_stream": {
+ "dataset": "sublime_security.message_event",
+ "namespace": "17638",
+ "type": "logs"
+ },
+ "ecs": {
+ "version": "8.11.0"
+ },
+ "elastic_agent": {
+ "id": "5f3fcbb9-1a97-4ff3-857f-167af6664464",
+ "snapshot": false,
+ "version": "8.13.0"
+ },
+ "email": {
+ "from": {
+ "address": [
+ "bob.demo@gmail.com"
+ ]
+ },
+ "subject": "Urgent: Wire transfer",
+ "to": {
+ "address": [
+ "xyz@example.com",
+ "user12@example.com",
+ "user@example.com",
+ "leon12@example.com"
+ ]
+ }
+ },
+ "event": {
+ "agent_id_status": "verified",
+ "category": [
+ "email"
+ ],
+ "dataset": "sublime_security.message_event",
+ "id": "9c426680-5cdf-4283-adbd-d79ba0e52434",
+ "ingested": "2024-08-28T10:36:57Z",
+ "kind": "event",
+ "original": "{\"canonical_id\":\"dd97dc82731ff7e82edfccaef59826cccd271bd4423e09d1e150ade83037cb37\",\"created_at\":\"2024-07-12T05:15:08.221838Z\",\"external_id\":\"7a2dfbeb-1310-48fc-9ed9-f480608a0306\",\"forward_recipients\":[],\"forwarded_at\":null,\"id\":\"9c426680-5cdf-4283-adbd-d79ba0e52434\",\"landed_in_spam\":false,\"mailbox\":{\"email\":\"demo@example.com\",\"external_id\":null,\"id\":\"433fe142-e2e5-4372-84ea-480279543a9b\"},\"message_source_id\":\"257982a1-f106-4c68-bc64-ff032914ed5f\",\"read_at\":null,\"recipients\":[{\"email\":\"xyz@example.com\"},{\"email\":\"user12@example.com\"},{\"email\":\"user@example.com\"},{\"email\":\"leon12@example.com\"}],\"replied_at\":null,\"sender\":{\"display_name\":\"Bob Doe\",\"email\":\"bob.demo@gmail.com\"},\"subject\":\"Urgent: Wire transfer\"}",
+ "type": [
+ "info"
+ ]
+ },
+ "input": {
+ "type": "cel"
+ },
+ "observer": {
+ "product": "Sublime Security",
+ "vendor": "Sublime Security"
+ },
+ "related": {
+ "user": [
+ "xyz@example.com",
+ "user12@example.com",
+ "user@example.com",
+ "leon12@example.com",
+ "Bob Doe",
+ "bob.demo@gmail.com"
+ ]
+ },
+ "source": {
+ "user": {
+ "name": "Bob Doe"
+ }
+ },
+ "sublime_security": {
+ "message_event": {
+ "canonical_id": "dd97dc82731ff7e82edfccaef59826cccd271bd4423e09d1e150ade83037cb37",
+ "created_at": "2024-07-12T05:15:08.221Z",
+ "external_id": "7a2dfbeb-1310-48fc-9ed9-f480608a0306",
+ "id": "9c426680-5cdf-4283-adbd-d79ba0e52434",
+ "landed_in_spam": false,
+ "mailbox": {
+ "email": "demo@example.com",
+ "id": "433fe142-e2e5-4372-84ea-480279543a9b"
+ },
+ "message_source_id": "257982a1-f106-4c68-bc64-ff032914ed5f",
+ "recipients": [
+ {
+ "email": "xyz@example.com"
+ },
+ {
+ "email": "user12@example.com"
+ },
+ {
+ "email": "user@example.com"
+ },
+ {
+ "email": "leon12@example.com"
+ }
+ ],
+ "sender": {
+ "display_name": "Bob Doe",
+ "email": "bob.demo@gmail.com"
+ },
+ "subject": "Urgent: Wire transfer"
+ }
+ },
+ "tags": [
+ "preserve_original_event",
+ "preserve_duplicate_custom_fields",
+ "forwarded",
+ "sublime_security-message_event"
+ ]
+}
\ No newline at end of file
diff --git a/packages/sublime_security/docs/README.md b/packages/sublime_security/docs/README.md
new file mode 100644
index 00000000000..509daaa6bdf
--- /dev/null
+++ b/packages/sublime_security/docs/README.md
@@ -0,0 +1,1537 @@
+# Sublime Security
+
+Sublime Security is a programmable, AI-powered, cloud email security platform for Microsoft 365 and Google Workspace environments. It is used to block email attacks such as phishing, BEC, malware, threat hunt, and auto-triage user reports.
+
+The Sublime Security integration collects data for Audit, Email Message(MDM Schema) and Message Event logs using REST API and AWS-S3 or AWS-SQS:
+
+- REST API mode - Sublime Security integration collects and parses data from the Sublime Security REST APIs.
+- AWS S3 polling mode - Sublime Security writes data to S3 and Elastic Agent polls the S3 bucket by listing its contents and reading new files.
+- AWS S3 SQS mode - Sublime Security writes data to S3, S3 pushes a new object notification to SQS, Elastic Agent receives the notification from SQS, and then reads the S3 object. Multiple Agents can be used in this mode.
+
+## Data streams
+
+The Sublime Security integration collects three types of logs:
+
+**[Audit](https://docs.sublime.security/reference/listeventsinauditlog)** - Captures detailed records of all significant actions and changes within the platform, including changes to email security policies, user access to email data, and modifications to email configurations, ensuring traceability and compliance for all operations.
+
+**[Email Message](https://docs.sublime.security/docs/export-message-mdms)** - Represents the flow of individual emails through the platform, including sender and recipient details, spam filtering outcomes, and overall email disposition, helping to secure and analyze email communication.
+
+**[Message Event](https://docs.sublime.security/reference/getmessage-1)** - Represents document specific actions taken on emails, like spam detection or rule applications, providing detailed insights into how the platform processes and protects email communications.
+
+## Requirements
+
+Elastic Agent must be installed. For more information, refer to the link [here](https://www.elastic.co/guide/en/fleet/current/elastic-agent-installation.html).
+
+### Installing and managing an Elastic Agent:
+
+You have a few options for installing and managing an Elastic Agent:
+
+### Install a Fleet-managed Elastic Agent (recommended):
+
+With this approach, you install Elastic Agent and use Fleet in Kibana to define, configure, and manage your agents in a central location. We recommend using Fleet management because it makes the management and upgrade of your agents considerably easier.
+
+### Install Elastic Agent in standalone mode (advanced users):
+
+With this approach, you install Elastic Agent and manually configure the agent locally on the system where it’s installed. You are responsible for managing and upgrading the agents. This approach is reserved for advanced users only.
+
+### Install Elastic Agent in a containerized environment:
+
+You can run Elastic Agent inside a container, either with Fleet Server or standalone. Docker images for all versions of Elastic Agent are available from the Elastic Docker registry, and we provide deployment manifests for running on Kubernetes.
+
+There are some minimum requirements for running Elastic Agent and for more information, refer to the link [here](https://www.elastic.co/guide/en/fleet/current/elastic-agent-installation.html#_minimum_requirements).
+
+## Setup
+
+### To collect data from the Sublime Security API:
+
+#### Step 1: Go to Platform
+- Visit the [Sublime Security Platform](https://platform.sublime.security/) and select `API` in Developers section.
+
+#### Step 2: Generating the API Key
+- Retrieve your `API Key`. This key will be used further in the Elastic integration setup to authenticate and access different Sublime Security Logs.
+- `Base URL` of Sublime Security is also required for configuring integration.
+
+**Note**: Users with the `Admin` role are allowed to access `Audit` logs. For more information, refer [here](https://docs.sublime.security/docs/role-based-access-control-rbac).
+
+### To collect data from AWS S3 Bucket or AWS SQS:
+
+#### For AWS S3 Bucket, follow the below steps:
+- Create an Amazon S3 bucket. Refer to the link [here](https://docs.aws.amazon.com/AmazonS3/latest/userguide/create-bucket-overview.html).
+- User can set the parameter "Bucket List Prefix" according to the requirement.
+
+#### For AWS SQS, follow the below steps:
+1. If data forwarding to an AWS S3 Bucket hasn't been configured, then first set up an AWS S3 Bucket as mentioned in the above documentation.
+2. To set up an SQS queue, follow "Step 1: Create an Amazon SQS queue" mentioned in the [Documentation](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ways-to-add-notification-config-to-bucket.html).
+ - While creating an SQS Queue, please provide the same bucket ARN that has been generated after creating an AWS S3 Bucket.
+3. Set up event notifications for a S3 bucket. Follow this [link](https://docs.aws.amazon.com/AmazonS3/latest/userguide/enable-event-notifications.html).
+ - Users have to set the prefix parameter the same as the S3 Bucket List Prefix as created earlier. (for example, `exports/sublime_platform_audit_log/` for a audit data stream).
+ - Select the event type as s3:ObjectCreated:*, select the destination type SQS Queue, and select the queue that has been created in Step 2.
+
+**Note**:
+ - Credentials for the above AWS S3 and SQS input types should be configured using the [link](https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-input-aws-s3.html#aws-credentials-config).
+ - Data collection via AWS S3 Bucket and AWS SQS are mutually exclusive in this case.
+ - You can configure a global SQS queue for all data streams or a local SQS queue for each data stream. Configuring data stream specific SQS queues will enable better performance and scalability. Data stream specific SQS queues will always override any global queue definitions for that specific data stream.
+
+### Enabling the integration in Elastic:
+
+1. In Kibana go to Management > Integrations.
+2. In "Search for integrations" search bar, type Sublime Security.
+3. Click on the "Sublime Security" integration from the search results.
+4. Click on the "Add Sublime Security" button to add the integration.
+5. Enable the Integration to collect logs via AWS S3 or API input.
+6. Under the AWS S3 input, there are two types of inputs: using AWS S3 Bucket or using SQS.
+7. Add all the required integration configuration parameters, including API Key, Interval, Initial Interval and Page Size for API input and Access Key, Secret Key and Session Token for AWS input type to enable data collection.
+8. Click on "Save and continue" to save the integration.
+
+**Note**:
+- The Base URL for Sublime Security cloud customers is `https://api.platform.sublimesecurity.com`. Depending on your type of deployment, yours may be different.
+- For SSO users, in addition to access key ID and secret access key, the session token is required to configure integration. For IAM users, the session token is optional and not required.
+
+## Logs reference
+
+### Audit
+
+This is the `audit` dataset.
+
+#### Example
+
+An example event for `audit` looks as following:
+
+```json
+{
+ "@timestamp": "2024-08-12T06:04:03.714Z",
+ "agent": {
+ "ephemeral_id": "390c3f2d-c9eb-4229-9992-0f4fc2436f51",
+ "id": "5f3fcbb9-1a97-4ff3-857f-167af6664464",
+ "name": "docker-fleet-agent",
+ "type": "filebeat",
+ "version": "8.13.0"
+ },
+ "data_stream": {
+ "dataset": "sublime_security.audit",
+ "namespace": "99243",
+ "type": "logs"
+ },
+ "ecs": {
+ "version": "8.11.0"
+ },
+ "elastic_agent": {
+ "id": "5f3fcbb9-1a97-4ff3-857f-167af6664464",
+ "snapshot": false,
+ "version": "8.13.0"
+ },
+ "event": {
+ "action": "search",
+ "agent_id_status": "verified",
+ "dataset": "sublime_security.audit",
+ "id": "bd49af79-0cfb-4184-bd18-b0401d69ac61",
+ "ingested": "2024-08-28T10:35:52Z",
+ "kind": "event",
+ "original": "{\"created_at\":\"2024-08-12T06:04:03.714126Z\",\"created_by\":{\"active\":true,\"created_at\":\"2024-07-12T05:13:47.879426Z\",\"email_address\":\"demo@example.com\",\"first_name\":\"Demo\",\"google_oauth_user_id\":\"d83rb8et4-refe-fe7t4f8efe\",\"id\":\"6e6eca05-4fea-406b-86d4-b40177e25474\",\"is_enrolled\":true,\"last_name\":\"User\",\"microsoft_oauth_user_id\":\"fhe7t4bgf8-freu-ebfur94ref\",\"phone_number\":null,\"role\":\"admin\",\"updated_at\":\"2024-07-12T05:13:47.879426Z\"},\"data\":{\"request\":{\"api_key_name\":\"demo mode local\",\"authentication_method\":\"api_key\",\"body\":\"\",\"id\":\"6ad202de-0def-423d-a0f2-549402e1a9c9\",\"ip\":\"1.128.0.0\",\"method\":\"GET\",\"path\":\"/v0/message-groups\",\"user_agent\":\"Go-http-client/1.1\"}},\"id\":\"bd49af79-0cfb-4184-bd18-b0401d69ac61\",\"type\":\"message_group.search\"}",
+ "type": [
+ "info"
+ ]
+ },
+ "http": {
+ "request": {
+ "id": "6ad202de-0def-423d-a0f2-549402e1a9c9",
+ "method": "GET"
+ }
+ },
+ "input": {
+ "type": "cel"
+ },
+ "observer": {
+ "product": "Sublime Security",
+ "vendor": "Sublime Security"
+ },
+ "related": {
+ "ip": [
+ "1.128.0.0"
+ ],
+ "user": [
+ "demo@example.com",
+ "Demo",
+ "d83rb8et4-refe-fe7t4f8efe",
+ "6e6eca05-4fea-406b-86d4-b40177e25474",
+ "fhe7t4bgf8-freu-ebfur94ref"
+ ]
+ },
+ "source": {
+ "ip": "1.128.0.0"
+ },
+ "sublime_security": {
+ "audit": {
+ "created_at": "2024-08-12T06:04:03.714Z",
+ "created_by": {
+ "active": true,
+ "created_at": "2024-07-12T05:13:47.879Z",
+ "email_address": "demo@example.com",
+ "first_name": "Demo",
+ "google_oauth_user_id": "d83rb8et4-refe-fe7t4f8efe",
+ "id": "6e6eca05-4fea-406b-86d4-b40177e25474",
+ "is_enrolled": true,
+ "last_name": "User",
+ "microsoft_oauth_user_id": "fhe7t4bgf8-freu-ebfur94ref",
+ "role": "admin",
+ "updated_at": "2024-07-12T05:13:47.879Z"
+ },
+ "data": {
+ "request": {
+ "api_key_name": "demo mode local",
+ "authentication_method": "api_key",
+ "id": "6ad202de-0def-423d-a0f2-549402e1a9c9",
+ "ip": "1.128.0.0",
+ "method": "GET",
+ "path": "/v0/message-groups",
+ "user_agent": "Go-http-client/1.1"
+ }
+ },
+ "id": "bd49af79-0cfb-4184-bd18-b0401d69ac61",
+ "type": "message_group.search"
+ }
+ },
+ "tags": [
+ "preserve_original_event",
+ "preserve_duplicate_custom_fields",
+ "forwarded",
+ "sublime_security-audit"
+ ],
+ "url": {
+ "path": "/v0/message-groups"
+ },
+ "user": {
+ "domain": "example.com",
+ "email": "demo@example.com",
+ "full_name": "Demo User",
+ "id": "6e6eca05-4fea-406b-86d4-b40177e25474",
+ "name": "demo",
+ "roles": [
+ "admin"
+ ]
+ },
+ "user_agent": {
+ "device": {
+ "name": "Other"
+ },
+ "name": "Go-http-client",
+ "original": "Go-http-client/1.1",
+ "version": "1.1"
+ }
+}
+```
+
+**Exported fields**
+
+| Field | Description | Type |
+|---|---|---|
+| @timestamp | Event timestamp. | date |
+| data_stream.dataset | Data stream dataset. | constant_keyword |
+| data_stream.namespace | Data stream namespace. | constant_keyword |
+| data_stream.type | Data stream type. | constant_keyword |
+| event.dataset | Event dataset. | constant_keyword |
+| event.module | Event module. | constant_keyword |
+| input.type | Type of filebeat input. | keyword |
+| log.offset | Log offset. | long |
+| sublime_security.audit.created_at | Event creation time. | date |
+| sublime_security.audit.created_by.active | | boolean |
+| sublime_security.audit.created_by.created_at | User creation time. | date |
+| sublime_security.audit.created_by.deleted_at | User deletion time. | date |
+| sublime_security.audit.created_by.email_address | Email address. | keyword |
+| sublime_security.audit.created_by.first_name | First name. | keyword |
+| sublime_security.audit.created_by.google_oauth_user_id | The user's Google user ID, if it exists. | keyword |
+| sublime_security.audit.created_by.id | User ID. | keyword |
+| sublime_security.audit.created_by.is_enrolled | Whether the user has begun using the system (e.g. accepted an invitation or logged in at least once). | boolean |
+| sublime_security.audit.created_by.last_name | Last name. | keyword |
+| sublime_security.audit.created_by.microsoft_oauth_user_id | The user's Microsoft user ID, if it exists. | keyword |
+| sublime_security.audit.created_by.phone_number | Phone number. | keyword |
+| sublime_security.audit.created_by.role | Role assumed by the user. | keyword |
+| sublime_security.audit.created_by.updated_at | User last updated time. | date |
+| sublime_security.audit.data.message.id | Message ID. | keyword |
+| sublime_security.audit.data.message_group.id | Message Group ID. | keyword |
+| sublime_security.audit.data.request.api_key_name | Name of API key if an API key was used. | keyword |
+| sublime_security.audit.data.request.authentication_method | Description of how request was authenticated. | keyword |
+| sublime_security.audit.data.request.body | Request body. | keyword |
+| sublime_security.audit.data.request.id | API request ID. | keyword |
+| sublime_security.audit.data.request.ip | IP address of requester, if available. | ip |
+| sublime_security.audit.data.request.method | HTTP method. | keyword |
+| sublime_security.audit.data.request.path | URL path. | keyword |
+| sublime_security.audit.data.request.query | Query parameters. | object |
+| sublime_security.audit.data.request.user_agent | User agent of requester, if available. | keyword |
+| sublime_security.audit.id | Event ID. | keyword |
+| sublime_security.audit.type | Event type. | keyword |
+
+
+### Email Message
+
+This is the `email_message` dataset.
+
+#### Example
+
+An example event for `email_message` looks as following:
+
+```json
+{
+ "@timestamp": "2024-08-02T07:40:25.135Z",
+ "agent": {
+ "ephemeral_id": "832ebf28-565e-4f38-a67e-ee5ea9f51e89",
+ "id": "5f3fcbb9-1a97-4ff3-857f-167af6664464",
+ "name": "docker-fleet-agent",
+ "type": "filebeat",
+ "version": "8.13.0"
+ },
+ "aws": {
+ "s3": {
+ "bucket": {
+ "arn": "arn:aws:s3:::elastic-package-sublime-security-bucket-33881",
+ "name": "elastic-package-sublime-security-bucket-33881"
+ },
+ "object": {
+ "key": "email-message.log"
+ }
+ }
+ },
+ "cloud": {
+ "region": "us-east-1"
+ },
+ "data_stream": {
+ "dataset": "sublime_security.email_message",
+ "namespace": "57022",
+ "type": "logs"
+ },
+ "destination": {
+ "domain": "example.com",
+ "subdomain": "example",
+ "top_level_domain": "com"
+ },
+ "ecs": {
+ "version": "8.11.0"
+ },
+ "elastic_agent": {
+ "id": "5f3fcbb9-1a97-4ff3-857f-167af6664464",
+ "snapshot": false,
+ "version": "8.13.0"
+ },
+ "email": {
+ "attachments": [
+ {
+ "file": {
+ "extension": "pdf",
+ "hash": {
+ "md5": "1a2b3c",
+ "sha1": "4d5e6f",
+ "sha256": "7g8h9i"
+ },
+ "mime_type": "application/pdf",
+ "name": "sample_document.pdf",
+ "size": 102400
+ }
+ },
+ {
+ "file": {
+ "extension": "jpg",
+ "hash": {
+ "md5": "7h8i9j",
+ "sha1": "1k2l3m",
+ "sha256": "4n5o6p"
+ },
+ "mime_type": "image/jpeg",
+ "name": "image_photo.jpg",
+ "size": 204800
+ }
+ },
+ {
+ "file": {
+ "extension": "txt",
+ "hash": {
+ "md5": "1x2y3z",
+ "sha1": "4a5b6c",
+ "sha256": "7d8e9f"
+ },
+ "mime_type": "text/plain",
+ "name": "notes.txt",
+ "size": 5120
+ }
+ }
+ ],
+ "bcc": {
+ "address": [
+ "john.doe@example.com"
+ ]
+ },
+ "cc": {
+ "address": [
+ "jane.smith@example.org"
+ ]
+ },
+ "direction": "outbound",
+ "from": {
+ "address": [
+ "testing@sublimesecurity.com"
+ ]
+ },
+ "message_id": "2fe271830bbad5fe3a70abbe7a8c0bfe7refe3ffe",
+ "origination_timestamp": "2024-08-02T07:40:25.135Z",
+ "reply_to": {
+ "address": [
+ "user@example.com"
+ ]
+ },
+ "subject": "Sublime-Security-Standard-Test-String",
+ "to": {
+ "address": [
+ "user@example.com"
+ ]
+ },
+ "x_mailer": "MyCustomMailer"
+ },
+ "event": {
+ "agent_id_status": "verified",
+ "category": [
+ "email"
+ ],
+ "dataset": "sublime_security.email_message",
+ "id": "01911208-633c-7f03-b303-e594d92cf818",
+ "ingested": "2024-08-28T10:59:37Z",
+ "kind": "event",
+ "original": "{\"body\":{\"plain\":{\"raw\":\"Sublime Security test message.\\n\",\"charset\":\"utf-8\",\"content_transfer_encoding\":\"base64\"},\"current_thread\":{\"text\":\"Sublime Security test message.\"},\"html\":{\"charset\":\"utf-8\",\"content_transfer_encoding\":\"base64\",\"display_text\":\"Sublime Security test message.\",\"raw\":\"Sublime Security test message.
\",\"inner_text\":\"Sublime Security test message.
\"},\"ips\":[{\"ip\":\"1.128.0.0\"}],\"links\":[{\"display_text\":\"Click here!\",\"mismatched\":true,\"display_url\":{\"fragment\":\"search\",\"password\":\"pass123\",\"path\":\"/test\",\"port\":80,\"query_params\":\"q=elasticsearch\",\"rewrite\":{\"encoders\":[\"base64\"],\"original\":\"demo\"},\"scheme\":\"https\",\"url\":\"https://example.com/test?q=elasticsearch#search\",\"username\":\"test\",\"domain\":{\"domain\":\"example.com\",\"punycode\":\"demo\",\"root_domain\":\"example.com\",\"subdomain\":\"example\",\"tld\":\"com\",\"valid\":true,\"sld\":\"example\"}}},{\"href_url\":{\"fragment\":\"search\",\"password\":\"pass123\",\"path\":\"/test\",\"port\":80,\"query_params\":\"q=elasticsearch\",\"rewrite\":{\"encoders\":[\"base64\"],\"original\":\"demo\"},\"scheme\":\"https\",\"url\":\"https://example.com/test?q=elasticsearch#search\",\"username\":\"test\",\"domain\":{\"domain\":\"example.com\",\"punycode\":\"demo\",\"root_domain\":\"example.com\",\"subdomain\":\"example\",\"tld\":\"com\",\"valid\":true,\"sld\":\"example\"}}}]},\"external\":{\"created_at\":\"2024-08-02T07:40:25.135939305Z\",\"message_id\":\"2fe271830bbad5fe3a70abbe7a8c0bfe7refe3ffe\",\"route_type\":\"sent\",\"spam\":false,\"spam_folder\":true,\"thread_id\":\"sample_data\"},\"attachments\":[{\"content_id\":\"abc123\",\"content_transfer_encoding\":\"base64\",\"content_type\":\"application/pdf\",\"file_extension\":\".pdf\",\"file_name\":\"sample_document.pdf\",\"file_type\":\"document\",\"md5\":\"1a2b3c\",\"raw\":\"JVBERi0xLjMKJcfs4AAQSkZjRgABAQE\",\"sha1\":\"4d5e6f\",\"sha256\":\"7g8h9i\",\"size\":102400},{\"content_id\":\"xyz456\",\"content_transfer_encoding\":\"7bit\",\"content_type\":\"image/jpeg\",\"file_extension\":\".jpg\",\"file_name\":\"image_photo.jpg\",\"file_type\":\"image\",\"md5\":\"7h8i9j\",\"raw\":\"/9j/4AAQSkZJRgABAQEJVBERi0xLjMKJd\",\"sha1\":\"1k2l3m\",\"sha256\":\"4n5o6p\",\"size\":204800},{\"content_id\":\"efg789\",\"content_transfer_encoding\":\"quoted-printable\",\"content_type\":\"text/plain\",\"file_extension\":\".txt\",\"file_name\":\"notes.txt\",\"file_type\":\"text\",\"md5\":\"1x2y3z\",\"raw\":\"SGVsbG8gdVsbG8gd29yb29ybGQhVsbG8gd29yb\",\"sha1\":\"4a5b6c\",\"sha256\":\"7d8e9f\",\"size\":5120}],\"headers\":{\"x_authenticated_domain\":{\"domain\":\"example.com\",\"punycode\":\"xn--example-d4a.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"sub\",\"tld\":\"com\",\"valid\":true},\"x_authenticated_sender\":{\"domain\":{\"domain\":\"example.com\",\"punycode\":\"example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"sub\",\"tld\":\"com\",\"valid\":true},\"email\":\"user@example.com\",\"local_part\":\"user\"},\"x_client_ip\":{\"ip\":\"1.128.0.0\"},\"x_originating_ip\":{\"ip\":\"1.128.0.0\"},\"x_secure_server_account\":\"account_value\",\"x_sender\":{\"domain\":{\"domain\":\"example.com\",\"punycode\":\"example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"sub\",\"tld\":\"com\",\"valid\":true},\"email\":\"user@example.com\",\"local_part\":\"user\"},\"return_path\":{\"domain\":{\"domain\":\"example.com\",\"punycode\":\"xn--example-d4a.com\",\"root_domain\":\"example\",\"sld\":\"example\",\"subdomain\":\"sub\",\"tld\":\"com\",\"valid\":true},\"email\":\"user@example.com\",\"local_part\":\"user\"},\"references\":[\"test1\",\"test2\"],\"auth_summary\":{\"dmarc\":{\"details\":{\"action\":\"quarantine\",\"disposition\":\"quarantine\",\"from\":{\"domain\":\"example.com\",\"punycode\":\"example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"example\",\"tld\":\"com\",\"valid\":true},\"policy\":\"reject\",\"sub_policy\":\"none\",\"verdict\":\"pass\",\"version\":\"1.0\"},\"pass\":true,\"received_hop\":1},\"spf\":{\"details\":{\"client_ip\":{\"ip\":\"1.128.0.0\"},\"description\":\"SPF record found\",\"designator\":\"pass\",\"helo\":{\"domain\":\"example.com\",\"punycode\":\"example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"example\",\"tld\":\"com\",\"valid\":true},\"server\":{\"domain\":\"mail.example.com\",\"punycode\":\"mail.example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"mail\",\"tld\":\"com\",\"valid\":true},\"verdict\":\"pass\"},\"error\":\"true\",\"pass\":true,\"received_hop\":2}},\"date\":\"2019-10-21T18:23:24Z\",\"date_original_offset\":\"-4\",\"hops\":[{\"index\":0,\"fields\":[{\"name\":\"To\",\"value\":\"user@example.com\",\"position\":0},{\"name\":\"Subject\",\"value\":\"Sublime-Security-Standard-Test-String\",\"position\":1},{\"name\":\"Date\",\"value\":\"Mon, 21 Oct 2019 14:23:24 -0400\",\"position\":2},{\"name\":\"From\",\"value\":\"Sublime Security Test \",\"position\":3}],\"authentication_results\":{\"compauth\":{\"verdict\":\"pass\",\"reason\":\"reason_value\"},\"dkim\":\"pass\",\"dkim_details\":{\"algorithm\":\"rsa-sha256\",\"body_hash\":\"abcdefg\",\"domain\":\"example.com\",\"headers\":\"from, to, subject\",\"instance\":\"example.com\",\"selector\":\"abcdefg\",\"signature\":\"abcdefg\",\"type\":\"dkim\",\"version\":\"1.0\"},\"dmarc\":\"pass\",\"dmarc_details\":{\"action\":\"quarantine\",\"disposition\":\"quarantine\",\"from\":{\"domain\":\"example.com\",\"punycode\":\"example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"example\",\"tld\":\"com\",\"valid\":true},\"policy\":\"reject\",\"sub_policy\":\"none\",\"verdict\":\"pass\",\"version\":\"1.0\"},\"instance\":\"example.com\",\"server\":{\"domain\":\"mail.example.com\",\"punycode\":\"mail.example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"mail\",\"tld\":\"com\",\"valid\":true},\"spf\":\"pass\",\"spf_details\":{\"client_ip\":{\"ip\":\"1.128.0.0\"},\"description\":\"SPF record found\",\"designator\":\"pass\",\"helo\":{\"domain\":\"example.com\",\"punycode\":\"example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"example\",\"tld\":\"com\",\"valid\":true},\"server\":{\"domain\":\"mail.example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"mail\",\"tld\":\"com\",\"valid\":true},\"verdict\":\"pass\"},\"type\":\"spf\"},\"received\":{\"additional\":{\"raw\":\"Authentication successful\"},\"id\":{\"raw\":\"msg-12345\"},\"link\":{\"raw\":\"https://mail.example.com/message/12345\"},\"mailbox\":{\"raw\":\"user@example.com\"},\"protocol\":{\"raw\":\"IMAP\"},\"server\":{\"raw\":\"imap.example.com\"},\"source\":{\"raw\":\"81.2.69.144\"},\"time\":\"2019-10-21T18:23:24Z\",\"zone_offset\":\"+00:00\"},\"received_spf\":{\"client_ip\":{\"ip\":\"1.128.0.0\"},\"description\":\"SPF record found\",\"designator\":\"pass\",\"helo\":{\"domain\":\"example.com\",\"punycode\":\"example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"example\",\"tld\":\"com\",\"valid\":true},\"server\":{\"domain\":\"mail.example.com\",\"punycode\":\"mail.example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"subdomain\":\"mail\",\"tld\":\"com\",\"valid\":true},\"verdict\":\"pass\"},\"signature\":{\"algorithm\":\"rsa-sha256\",\"body_hash\":\"b9c4a3f9d93d9a38bdf8c47a8f2d2c79ec1d8b1f\",\"domain\":\"example.com\",\"headers\":\"from:to:subject:date\",\"instance\":\"123456\",\"selector\":\"default\",\"signature\":\"d2abf9d6c8f4b8d68d8f3f7b6f9d3b8e6a8c2b3a9f4b8d7b9d3b6a8f9c3b4e5f\",\"type\":\"spf\",\"version\":\"1\"}}],\"in_reply_to\":\"in_reply_to_value\",\"delivered_to\":{\"domain\":{\"domain\":\"example.com\",\"subdomain\":\"example\",\"tld\":\"com\",\"email\":\"testing@sublimesecurity.com\",\"punycode\":\"example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"valid\":true},\"email\":\"testing@sublimesecurity.com\",\"local_part\":\"testing\"},\"ips\":[{\"ip\":\"1.128.0.0\"}],\"mailer\":\"MyCustomMailer\",\"message_id\":\"2fe271830bbad5fe3a70abbe7a8c0bfe7refe3ffe\",\"domains\":[{\"domain\":\"test.com\",\"subdomain\":\"test\",\"tld\":\"com\",\"punycode\":\"test.com\",\"root_domain\":\"test.com\",\"sld\":\"test\",\"valid\":true},{\"domain\":\"example.com\",\"subdomain\":\"example\",\"tld\":\"com\",\"punycode\":\"example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"valid\":true}],\"reply_to\":[{\"email\":{\"email\":\"user@example.com\",\"local_part\":\"user\",\"domain\":{\"domain\":\"example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"tld\":\"com\",\"valid\":true}}},{\"display_name\":\"Example Display Name\",\"email\":{\"domain\":{\"punycode\":\"example.com\",\"subdomain\":\"sub.example\"}}},{\"display_name\":\"Another Display Name\",\"email\":{\"domain\":{\"punycode\":\"anotherexample.com\",\"subdomain\":\"sub.anotherexample\"}}}]},\"type\":{\"outbound\":true},\"mailbox\":{\"email\":{\"email\":\"user@example.com\",\"local_part\":\"user\",\"domain\":{\"domain\":\"example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"tld\":\"com\",\"valid\":true,\"punycode\":\"xn--example-d4a.com\",\"subdomain\":\"sub\"}}},\"recipients\":{\"to\":[{\"display_name\":\"Alice Johnson\",\"email\":{\"email\":\"user@example.com\",\"local_part\":\"user\",\"domain\":{\"domain\":\"example.com\",\"root_domain\":\"example.com\",\"sld\":\"example\",\"tld\":\"com\",\"valid\":true,\"punycode\":\"xn--example-d4a.net\",\"subdomain\":\"sub\"}}}],\"bcc\":[{\"display_name\":\"John Doe\",\"email\":{\"domain\":{\"domain\":\"example.com\",\"punycode\":\"xn--example-d4a.com\",\"root_domain\":\"example\",\"sld\":\"example\",\"subdomain\":\"sub\",\"tld\":\"com\",\"valid\":true},\"email\":\"john.doe@example.com\",\"local_part\":\"john.doe\"}}],\"cc\":[{\"display_name\":\"Jane Smith\",\"email\":{\"domain\":{\"domain\":\"example.org\",\"punycode\":\"xn--example-d4a.org\",\"root_domain\":\"example\",\"sld\":\"example\",\"subdomain\":\"sub\",\"tld\":\"org\",\"valid\":true},\"email\":\"jane.smith@example.org\",\"local_part\":\"jane.smith\"}}]},\"sender\":{\"display_name\":\"Sublime Security Test\",\"email\":{\"email\":\"testing@sublimesecurity.com\",\"local_part\":\"testing\",\"domain\":{\"domain\":\"sublimesecurity.com\",\"root_domain\":\"sublimesecurity.com\",\"sld\":\"sublimesecurity\",\"tld\":\"com\",\"valid\":true,\"punycode\":\"xn--example-d4a.com\",\"subdomain\":\"sub\"}}},\"subject\":{\"subject\":\"Sublime-Security-Standard-Test-String\"},\"_meta\":{\"id\":\"01911208-633c-7f03-b303-e594d92cf818\",\"canonical_id\":\"2fe271830bbad5fe3a70abbe7a8c0bfe79eb208a76cde267930d19f0e8cea81c\",\"created_at\":\"2024-08-02T07:40:25.135939305Z\",\"effective_at\":\"2024-08-02T07:40:25.135939305Z\"},\"_errors\":[{\"field\":\"Mime-Version\",\"message\":\"No Mime-Version defined in headers\",\"type\":\"missing_header_field\"}]}",
+ "type": [
+ "info"
+ ]
+ },
+ "input": {
+ "type": "aws-s3"
+ },
+ "log": {
+ "file": {
+ "path": "https://elastic-package-sublime-security-bucket-33881.s3.us-east-1.amazonaws.com/email-message.log"
+ },
+ "offset": 0
+ },
+ "observer": {
+ "product": "Sublime Security",
+ "vendor": "Sublime Security"
+ },
+ "related": {
+ "hash": [
+ "1a2b3c",
+ "7h8i9j",
+ "1x2y3z",
+ "4d5e6f",
+ "1k2l3m",
+ "4a5b6c",
+ "7g8h9i",
+ "4n5o6p",
+ "7d8e9f",
+ "abcdefg"
+ ],
+ "hosts": [
+ "example.com",
+ "mail.example.com",
+ "test.com",
+ "example",
+ "example.org",
+ "sublimesecurity.com"
+ ],
+ "ip": [
+ "1.128.0.0"
+ ],
+ "user": [
+ "test",
+ "user@example.com",
+ "john.doe@example.com",
+ "jane.smith@example.org",
+ "testing@sublimesecurity.com"
+ ]
+ },
+ "source": {
+ "domain": "sublimesecurity.com",
+ "ip": "1.128.0.0",
+ "subdomain": "sub",
+ "top_level_domain": "com"
+ },
+ "sublime_security": {
+ "email_message": {
+ "attachments": [
+ {
+ "content": {
+ "id": "abc123",
+ "transfer_encoding": "base64"
+ },
+ "file": {
+ "type": "document"
+ },
+ "raw": "JVBERi0xLjMKJcfs4AAQSkZjRgABAQE"
+ },
+ {
+ "content": {
+ "id": "xyz456",
+ "transfer_encoding": "7bit"
+ },
+ "file": {
+ "type": "image"
+ },
+ "raw": "/9j/4AAQSkZJRgABAQEJVBERi0xLjMKJd"
+ },
+ {
+ "content": {
+ "id": "efg789",
+ "transfer_encoding": "quoted-printable"
+ },
+ "file": {
+ "type": "text"
+ },
+ "raw": "SGVsbG8gdVsbG8gd29yb29ybGQhVsbG8gd29yb"
+ }
+ ],
+ "body": {
+ "current_thread": {
+ "text": "Sublime Security test message."
+ },
+ "html": {
+ "charset": "utf-8",
+ "content_transfer_encoding": "base64",
+ "display_text": "Sublime Security test message.",
+ "inner_text": "Sublime Security test message.
",
+ "raw": "Sublime Security test message.
"
+ },
+ "ips": [
+ {
+ "ip": "1.128.0.0"
+ }
+ ],
+ "links": [
+ {
+ "display_text": "Click here!",
+ "display_url": {
+ "domain": {
+ "domain": "example.com",
+ "punycode": "demo",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "example",
+ "tld": "com",
+ "valid": true
+ },
+ "fragment": "search",
+ "password": "pass123",
+ "path": "/test",
+ "port": 80,
+ "query_params": "q=elasticsearch",
+ "rewrite": {
+ "encoders": [
+ "base64"
+ ],
+ "original": "demo"
+ },
+ "scheme": "https",
+ "url": "https://example.com/test?q=elasticsearch#search",
+ "username": "test"
+ },
+ "mismatched": true
+ },
+ {
+ "href_url": {
+ "domain": {
+ "punycode": "demo",
+ "root_domain": "example.com",
+ "sld": "example",
+ "valid": true
+ },
+ "rewrite": {
+ "encoders": [
+ "base64"
+ ],
+ "original": "demo"
+ }
+ }
+ }
+ ],
+ "plain": {
+ "charset": "utf-8",
+ "content_transfer_encoding": "base64",
+ "raw": "Sublime Security test message.\n"
+ }
+ },
+ "errors": [
+ {
+ "field": "Mime-Version",
+ "message": "No Mime-Version defined in headers",
+ "type": "missing_header_field"
+ }
+ ],
+ "external": {
+ "message_id": "2fe271830bbad5fe3a70abbe7a8c0bfe7refe3ffe",
+ "route_type": "sent",
+ "spam": false,
+ "spam_folder": true,
+ "thread_id": "sample_data"
+ },
+ "headers": {
+ "auth_summary": {
+ "dmarc": {
+ "details": {
+ "action": "quarantine",
+ "disposition": "quarantine",
+ "from": {
+ "domain": "example.com",
+ "punycode": "example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "example",
+ "tld": "com",
+ "valid": true
+ },
+ "policy": "reject",
+ "sub_policy": "none",
+ "verdict": "pass",
+ "version": "1.0"
+ },
+ "pass": true,
+ "received_hop": 1
+ },
+ "spf": {
+ "details": {
+ "client_ip": {
+ "ip": "1.128.0.0"
+ },
+ "description": "SPF record found",
+ "designator": "pass",
+ "helo": {
+ "domain": "example.com",
+ "punycode": "example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "example",
+ "tld": "com",
+ "valid": true
+ },
+ "server": {
+ "domain": "mail.example.com",
+ "punycode": "mail.example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "mail",
+ "tld": "com",
+ "valid": true
+ },
+ "verdict": "pass"
+ },
+ "error": true,
+ "pass": true,
+ "received_hop": 2
+ }
+ },
+ "date": "2019-10-21T18:23:24.000Z",
+ "date_original_offset": "-4",
+ "delivered_to": {
+ "domain": {
+ "punycode": "example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "valid": true
+ },
+ "email": "testing@sublimesecurity.com",
+ "local_part": "testing"
+ },
+ "domains": [
+ {
+ "domain": "test.com",
+ "punycode": "test.com",
+ "root_domain": "test.com",
+ "sld": "test",
+ "subdomain": "test",
+ "tld": "com",
+ "valid": true
+ },
+ {
+ "domain": "example.com",
+ "punycode": "example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "example",
+ "tld": "com",
+ "valid": true
+ }
+ ],
+ "hops": [
+ {
+ "authentication_results": {
+ "compauth": {
+ "reason": "reason_value",
+ "verdict": "pass"
+ },
+ "dkim": "pass",
+ "dkim_details": {
+ "algorithm": "rsa-sha256",
+ "body_hash": "abcdefg",
+ "domain": "example.com",
+ "headers": "from, to, subject",
+ "instance": "example.com",
+ "selector": "abcdefg",
+ "signature": "abcdefg",
+ "type": "dkim",
+ "version": "1.0"
+ },
+ "dmarc": "pass",
+ "dmarc_details": {
+ "action": "quarantine",
+ "disposition": "quarantine",
+ "from": {
+ "domain": "example.com",
+ "punycode": "example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "example",
+ "tld": "com",
+ "valid": true
+ },
+ "policy": "reject",
+ "sub_policy": "none",
+ "verdict": "pass",
+ "version": "1.0"
+ },
+ "instance": "example.com",
+ "server": {
+ "domain": "mail.example.com",
+ "punycode": "mail.example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "mail",
+ "tld": "com",
+ "valid": true
+ },
+ "spf": "pass",
+ "spf_details": {
+ "client_ip": {
+ "ip": "1.128.0.0"
+ },
+ "description": "SPF record found",
+ "designator": "pass",
+ "helo": {
+ "domain": "example.com",
+ "punycode": "example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "example",
+ "tld": "com",
+ "valid": true
+ },
+ "server": {
+ "domain": "mail.example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "mail",
+ "tld": "com",
+ "valid": true
+ },
+ "verdict": "pass"
+ },
+ "type": "spf"
+ },
+ "fields": [
+ {
+ "name": "To",
+ "position": 0,
+ "to": "user@example.com",
+ "value": "user@example.com"
+ },
+ {
+ "name": "Subject",
+ "position": 1,
+ "subject": "Sublime-Security-Standard-Test-String",
+ "value": "Sublime-Security-Standard-Test-String"
+ },
+ {
+ "date": "Mon, 21 Oct 2019 14:23:24 -0400",
+ "name": "Date",
+ "position": 2,
+ "value": "Mon, 21 Oct 2019 14:23:24 -0400"
+ },
+ {
+ "from": "Sublime Security Test ",
+ "name": "From",
+ "position": 3,
+ "value": "Sublime Security Test "
+ }
+ ],
+ "index": 0,
+ "received": {
+ "additional": {
+ "raw": "Authentication successful"
+ },
+ "id": {
+ "raw": "msg-12345"
+ },
+ "link": {
+ "raw": "https://mail.example.com/message/12345"
+ },
+ "mailbox": {
+ "raw": "user@example.com"
+ },
+ "protocol": {
+ "raw": "IMAP"
+ },
+ "server": {
+ "raw": "imap.example.com"
+ },
+ "source": {
+ "raw": "81.2.69.144"
+ },
+ "time": "2019-10-21T18:23:24.000Z",
+ "zone_offset": "+00:00"
+ },
+ "received_spf": {
+ "client_ip": {
+ "ip": "1.128.0.0"
+ },
+ "description": "SPF record found",
+ "designator": "pass",
+ "helo": {
+ "domain": "example.com",
+ "punycode": "example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "example",
+ "tld": "com",
+ "valid": true
+ },
+ "server": {
+ "domain": "mail.example.com",
+ "punycode": "mail.example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "mail",
+ "tld": "com",
+ "valid": true
+ },
+ "verdict": "pass"
+ },
+ "signature": {
+ "algorithm": "rsa-sha256",
+ "body_hash": "b9c4a3f9d93d9a38bdf8c47a8f2d2c79ec1d8b1f",
+ "domain": "example.com",
+ "headers": "from:to:subject:date",
+ "instance": "123456",
+ "selector": "default",
+ "signature": "d2abf9d6c8f4b8d68d8f3f7b6f9d3b8e6a8c2b3a9f4b8d7b9d3b6a8f9c3b4e5f",
+ "type": "spf",
+ "version": "1"
+ }
+ }
+ ],
+ "in_reply_to": "in_reply_to_value",
+ "ips": [
+ {
+ "ip": "1.128.0.0"
+ }
+ ],
+ "references": [
+ "test1",
+ "test2"
+ ],
+ "reply_to": [
+ {
+ "email": {
+ "domain": {
+ "domain": "example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "tld": "com",
+ "valid": true
+ },
+ "local_part": "user"
+ }
+ },
+ {
+ "display_name": "Example Display Name",
+ "email": {
+ "domain": {
+ "punycode": "example.com",
+ "subdomain": "sub.example"
+ }
+ }
+ },
+ {
+ "display_name": "Another Display Name",
+ "email": {
+ "domain": {
+ "punycode": "anotherexample.com",
+ "subdomain": "sub.anotherexample"
+ }
+ }
+ }
+ ],
+ "return_path": {
+ "domain": {
+ "domain": "example.com",
+ "punycode": "xn--example-d4a.com",
+ "root_domain": "example",
+ "sld": "example",
+ "subdomain": "sub",
+ "tld": "com",
+ "valid": true
+ },
+ "email": "user@example.com",
+ "local_part": "user"
+ },
+ "x_authenticated_domain": {
+ "domain": "example.com",
+ "punycode": "xn--example-d4a.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "sub",
+ "tld": "com",
+ "valid": true
+ },
+ "x_authenticated_sender": {
+ "domain": {
+ "domain": "example.com",
+ "punycode": "example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "sub",
+ "tld": "com",
+ "valid": true
+ },
+ "email": "user@example.com",
+ "local_part": "user"
+ },
+ "x_originating_ip": {
+ "ip": "1.128.0.0"
+ },
+ "x_secure_server_account": "account_value",
+ "x_sender": {
+ "domain": {
+ "domain": "example.com",
+ "punycode": "example.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "sub",
+ "tld": "com",
+ "valid": true
+ },
+ "email": "user@example.com",
+ "local_part": "user"
+ }
+ },
+ "mailbox": {
+ "email": {
+ "domain": {
+ "domain": "example.com",
+ "punycode": "xn--example-d4a.com",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "sub",
+ "tld": "com",
+ "valid": true
+ },
+ "local_part": "user",
+ "value": "user@example.com"
+ }
+ },
+ "meta": {
+ "canonical_id": "2fe271830bbad5fe3a70abbe7a8c0bfe79eb208a76cde267930d19f0e8cea81c",
+ "effective_at": "2024-08-02T07:40:25.135Z"
+ },
+ "recipients": {
+ "bcc": [
+ {
+ "display_name": "John Doe",
+ "email": {
+ "domain": {
+ "domain": "example.com",
+ "punycode": "xn--example-d4a.com",
+ "root_domain": "example",
+ "sld": "example",
+ "subdomain": "sub",
+ "tld": "com",
+ "valid": true
+ },
+ "local_part": "john.doe"
+ }
+ }
+ ],
+ "cc": [
+ {
+ "display_name": "Jane Smith",
+ "email": {
+ "domain": {
+ "domain": "example.org",
+ "punycode": "xn--example-d4a.org",
+ "root_domain": "example",
+ "sld": "example",
+ "subdomain": "sub",
+ "tld": "org",
+ "valid": true
+ },
+ "local_part": "jane.smith"
+ }
+ }
+ ],
+ "to": [
+ {
+ "display_name": "Alice Johnson",
+ "email": {
+ "domain": {
+ "domain": "example.com",
+ "punycode": "xn--example-d4a.net",
+ "root_domain": "example.com",
+ "sld": "example",
+ "subdomain": "sub",
+ "tld": "com",
+ "valid": true
+ },
+ "local_part": "user"
+ }
+ }
+ ]
+ },
+ "sender": {
+ "display_name": "Sublime Security Test",
+ "email": {
+ "domain": {
+ "punycode": "xn--example-d4a.com",
+ "root_domain": "sublimesecurity.com",
+ "sld": "sublimesecurity",
+ "valid": true
+ },
+ "local_part": "testing"
+ }
+ },
+ "type": {
+ "outbound": true
+ }
+ }
+ },
+ "tags": [
+ "collect_sqs_logs",
+ "preserve_original_event",
+ "forwarded",
+ "sublime_security-email_message"
+ ],
+ "url": [
+ {
+ "domain": "example.com",
+ "fragment": "search",
+ "full": "https://example.com/test?q=elasticsearch#search",
+ "password": "pass123",
+ "path": "/test",
+ "port": 80,
+ "query": "q=elasticsearch",
+ "scheme": "https",
+ "subdomain": "example",
+ "top_level_domain": "com",
+ "username": "test"
+ }
+ ],
+ "user_agent": {
+ "device": {
+ "name": "Other"
+ },
+ "name": "Other",
+ "original": "MyCustomMailer"
+ }
+}
+```
+
+**Exported fields**
+
+| Field | Description | Type |
+|---|---|---|
+| @timestamp | Event timestamp. | date |
+| aws.s3.bucket.arn | The AWS S3 bucket ARN. | keyword |
+| aws.s3.bucket.name | The AWS S3 bucket name. | keyword |
+| aws.s3.object.key | The AWS S3 Object key. | keyword |
+| data_stream.dataset | Data stream dataset. | constant_keyword |
+| data_stream.namespace | Data stream namespace. | constant_keyword |
+| data_stream.type | Data stream type. | constant_keyword |
+| event.dataset | Event dataset. | constant_keyword |
+| event.module | Event module. | constant_keyword |
+| input.type | Type of filebeat input. | keyword |
+| log.offset | Log offset. | long |
+| sublime_security.email_message.attachments.content.id | Content-ID extracted from the MIME payload. | keyword |
+| sublime_security.email_message.attachments.content.transfer_encoding | Content-Transfer-Encoding extracted from the MIME payload. | keyword |
+| sublime_security.email_message.attachments.content.type | Content-Type extracted from the MIME payload. | keyword |
+| sublime_security.email_message.attachments.file.extension | File extension from context such as headers. | keyword |
+| sublime_security.email_message.attachments.file.name | File name. | keyword |
+| sublime_security.email_message.attachments.file.type | File type determined by looking at the magic bytes in the file. | keyword |
+| sublime_security.email_message.attachments.md5 | MD5 hash of the raw contents. | keyword |
+| sublime_security.email_message.attachments.raw | Base64 encoded source of the file. | keyword |
+| sublime_security.email_message.attachments.sha1 | SHA1 hash of the raw contents. | keyword |
+| sublime_security.email_message.attachments.sha256 | SHA256 hash of the raw contents. | keyword |
+| sublime_security.email_message.attachments.size | Size of the file in bytes. | long |
+| sublime_security.email_message.body.current_thread.text | The text content from the latest reply/forward in a message thread. This typically excludes content from forwarded messages and warning banners. | keyword |
+| sublime_security.email_message.body.html.charset | charset of the text/[subtype]. | keyword |
+| sublime_security.email_message.body.html.content_transfer_encoding | Content-Transfer-Encoding of the text/[subtype]. | keyword |
+| sublime_security.email_message.body.html.display_text | Visible text of the HTML document, with invisible characters removed and non-ASCII characters converted to ASCII spaces. | keyword |
+| sublime_security.email_message.body.html.inner_text | Inner text of the HTML document that doesn't include HTML tags. | keyword |
+| sublime_security.email_message.body.html.raw | Decoded raw content of a body text type (text/[subtype] section). | keyword |
+| sublime_security.email_message.body.ips.ip | The raw IP. | ip |
+| sublime_security.email_message.body.links.display_text | The text of a hyperlink, if it's not a URL. | keyword |
+| sublime_security.email_message.body.links.display_url.domain.domain | The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar. | keyword |
+| sublime_security.email_message.body.links.display_url.domain.punycode | Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com. | keyword |
+| sublime_security.email_message.body.links.display_url.domain.root_domain | The root domain, including the TLD. | keyword |
+| sublime_security.email_message.body.links.display_url.domain.sld | Second-level domain, e.g. 'windows' for the domain 'windows.net'. | keyword |
+| sublime_security.email_message.body.links.display_url.domain.subdomain | Subdomain, e.g. 'drive' for the domain 'drive.google.com'. | keyword |
+| sublime_security.email_message.body.links.display_url.domain.tld | The domain's top-level domain. E.g. the TLD of google.com is 'com'. | keyword |
+| sublime_security.email_message.body.links.display_url.domain.valid | Whether the domain is valid. | boolean |
+| sublime_security.email_message.body.links.display_url.fragment | Fragment identifier; the text following the # in the href_url (also called the anchor tag). | keyword |
+| sublime_security.email_message.body.links.display_url.password | The password specified before the domain name. | keyword |
+| sublime_security.email_message.body.links.display_url.path | Everything after the TLD and before the query parameters. | keyword |
+| sublime_security.email_message.body.links.display_url.port | The port used for the href_url. If no explicit port is set, the port will be inferred from the protocol. | long |
+| sublime_security.email_message.body.links.display_url.query_params | The query parameters of the href_url. | keyword |
+| sublime_security.email_message.body.links.display_url.rewrite.encoders | List of detected URL rewrite encoders while unraveling the URL. | keyword |
+| sublime_security.email_message.body.links.display_url.rewrite.original | Original URL without any unraveling URL rewrites. | keyword |
+| sublime_security.email_message.body.links.display_url.scheme | Protocol for the href_url request, e.g. http. | keyword |
+| sublime_security.email_message.body.links.display_url.url | Full URL. | keyword |
+| sublime_security.email_message.body.links.display_url.username | The username specified before the domain name of the href_url. | keyword |
+| sublime_security.email_message.body.links.href_url.domain.domain | The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar. | keyword |
+| sublime_security.email_message.body.links.href_url.domain.punycode | Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com. | keyword |
+| sublime_security.email_message.body.links.href_url.domain.root_domain | The root domain, including the TLD. | keyword |
+| sublime_security.email_message.body.links.href_url.domain.sld | Second-level domain, e.g. 'windows' for the domain 'windows.net'. | keyword |
+| sublime_security.email_message.body.links.href_url.domain.subdomain | Subdomain, e.g. 'drive' for the domain 'drive.google.com'. | keyword |
+| sublime_security.email_message.body.links.href_url.domain.tld | The domain's top-level domain. E.g. the TLD of google.com is 'com'. | keyword |
+| sublime_security.email_message.body.links.href_url.domain.valid | Whether the domain is valid. | boolean |
+| sublime_security.email_message.body.links.href_url.fragment | Fragment identifier; the text following the # in the href_url (also called the anchor tag). | keyword |
+| sublime_security.email_message.body.links.href_url.password | The password specified before the domain name. | keyword |
+| sublime_security.email_message.body.links.href_url.path | Everything after the TLD and before the query parameters. | keyword |
+| sublime_security.email_message.body.links.href_url.port | The port used for the href_url. If no explicit port is set, the port will be inferred from the protocol. | long |
+| sublime_security.email_message.body.links.href_url.query_params | The query parameters of the href_url. | keyword |
+| sublime_security.email_message.body.links.href_url.rewrite.encoders | List of detected URL rewrite encoders while unraveling the URL. | keyword |
+| sublime_security.email_message.body.links.href_url.rewrite.original | Original URL without any unraveling URL rewrites. | keyword |
+| sublime_security.email_message.body.links.href_url.scheme | Protocol for the href_url request, e.g. http. | keyword |
+| sublime_security.email_message.body.links.href_url.url | Full URL. | keyword |
+| sublime_security.email_message.body.links.href_url.username | The username specified before the domain name of the href_url. | keyword |
+| sublime_security.email_message.body.links.mismatched | Whether the display URL and href URL root domains are mismatched (i.e. .href_url.domain.root_domain != .display_url.domain.root_domain, where both are not null and valid domains). | boolean |
+| sublime_security.email_message.body.plain.charset | charset of the text/[subtype]. | keyword |
+| sublime_security.email_message.body.plain.content_transfer_encoding | Content-Transfer-Encoding of the text/[subtype]. | keyword |
+| sublime_security.email_message.body.plain.raw | Decoded raw content of a body text type (text/[subtype] section). | keyword |
+| sublime_security.email_message.errors | Non-fatal errors while parsing MDM. | object |
+| sublime_security.email_message.external.created_at | The created time of the message as provided by the cloud API (G Suite or Office 365) or other external source. This is typically the time the external source received the message. | date |
+| sublime_security.email_message.external.message_id | The message ID as provided by the cloud API (G Suite or Office 365) or other external source. | keyword |
+| sublime_security.email_message.external.route_type | whether the message was sent or received. | keyword |
+| sublime_security.email_message.external.spam | The upstream mail gateway determined the message to be spam. For cloud API providers, this will be the same as spam_folder. For other implementation methods like transport rules, this will be determined by message header values (e.g. X-SPAM) if supported. | boolean |
+| sublime_security.email_message.external.spam_folder | The message arrived in the user's spam folder. This only applies to cloud APIs (G Suite or Office 365). | boolean |
+| sublime_security.email_message.external.thread_id | The thread/conversation's unique ID as provided by the cloud API (G Suite or Office 365). | keyword |
+| sublime_security.email_message.headers.auth_summary.dmarc.details.action | Indicates the action taken by the spam filter based on the results of the DMARC check. For more information see https://docs.microsoft.com/en-us/microsoft-365/security/office-365-security/anti-spam-message-headers?view=o365-worldwide#authentication-results-message-header-fields. | keyword |
+| sublime_security.email_message.headers.auth_summary.dmarc.details.disposition | Gmail-applied policy. | keyword |
+| sublime_security.email_message.headers.auth_summary.dmarc.details.from.domain | The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar. | keyword |
+| sublime_security.email_message.headers.auth_summary.dmarc.details.from.punycode | Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com. | keyword |
+| sublime_security.email_message.headers.auth_summary.dmarc.details.from.root_domain | The root domain, including the TLD. | keyword |
+| sublime_security.email_message.headers.auth_summary.dmarc.details.from.sld | Second-level domain, e.g. 'windows' for the domain 'windows.net'. | keyword |
+| sublime_security.email_message.headers.auth_summary.dmarc.details.from.subdomain | Subdomain, e.g. 'drive' for the domain 'drive.google.com'. | keyword |
+| sublime_security.email_message.headers.auth_summary.dmarc.details.from.tld | The domain's top-level domain. E.g. the TLD of google.com is 'com'. | keyword |
+| sublime_security.email_message.headers.auth_summary.dmarc.details.from.valid | Whether the domain is valid. | boolean |
+| sublime_security.email_message.headers.auth_summary.dmarc.details.policy | Policy for the organizational domain. | keyword |
+| sublime_security.email_message.headers.auth_summary.dmarc.details.sub_policy | Policy for the subdomain of the organizational domain. | keyword |
+| sublime_security.email_message.headers.auth_summary.dmarc.details.verdict | Describes the results of the DMARC check for the message. | keyword |
+| sublime_security.email_message.headers.auth_summary.dmarc.details.version | DMARC version. | keyword |
+| sublime_security.email_message.headers.auth_summary.dmarc.pass | Whether the DMARC check passed. | boolean |
+| sublime_security.email_message.headers.auth_summary.dmarc.received_hop | The lowest hop at which the DMARC check was made. | long |
+| sublime_security.email_message.headers.auth_summary.spf.details.client_ip.ip | The raw IP. | ip |
+| sublime_security.email_message.headers.auth_summary.spf.details.description | Verbose description of the SPF verdict. | keyword |
+| sublime_security.email_message.headers.auth_summary.spf.details.designator | Email or domain of the designating body. | keyword |
+| sublime_security.email_message.headers.auth_summary.spf.details.helo.domain | The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar. | keyword |
+| sublime_security.email_message.headers.auth_summary.spf.details.helo.punycode | Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com. | keyword |
+| sublime_security.email_message.headers.auth_summary.spf.details.helo.root_domain | The root domain, including the TLD. | keyword |
+| sublime_security.email_message.headers.auth_summary.spf.details.helo.sld | Second-level domain, e.g. 'windows' for the domain 'windows.net'. | keyword |
+| sublime_security.email_message.headers.auth_summary.spf.details.helo.subdomain | Subdomain, e.g. 'drive' for the domain 'drive.google.com'. | keyword |
+| sublime_security.email_message.headers.auth_summary.spf.details.helo.tld | The domain's top-level domain. E.g. the TLD of google.com is 'com'. | keyword |
+| sublime_security.email_message.headers.auth_summary.spf.details.helo.valid | Whether the domain is valid. | boolean |
+| sublime_security.email_message.headers.auth_summary.spf.details.server.domain | The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar. | keyword |
+| sublime_security.email_message.headers.auth_summary.spf.details.server.punycode | Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com. | keyword |
+| sublime_security.email_message.headers.auth_summary.spf.details.server.root_domain | The root domain, including the TLD. | keyword |
+| sublime_security.email_message.headers.auth_summary.spf.details.server.sld | Second-level domain, e.g. 'windows' for the domain 'windows.net'. | keyword |
+| sublime_security.email_message.headers.auth_summary.spf.details.server.subdomain | Subdomain, e.g. 'drive' for the domain 'drive.google.com'. | keyword |
+| sublime_security.email_message.headers.auth_summary.spf.details.server.tld | The domain's top-level domain. E.g. the TLD of google.com is 'com'. | keyword |
+| sublime_security.email_message.headers.auth_summary.spf.details.server.valid | Whether the domain is valid. | boolean |
+| sublime_security.email_message.headers.auth_summary.spf.details.verdict | Verdict of the SPF. | keyword |
+| sublime_security.email_message.headers.auth_summary.spf.error | Whether the SPF check errored. | boolean |
+| sublime_security.email_message.headers.auth_summary.spf.pass | Whether the SPF check passed. | boolean |
+| sublime_security.email_message.headers.auth_summary.spf.received_hop | The lowest hop at which the SPF check was made. | long |
+| sublime_security.email_message.headers.date | Date the email was sent in UTC. | date |
+| sublime_security.email_message.headers.date_original_offset | UTC timezone offset of the sender. | keyword |
+| sublime_security.email_message.headers.delivered_to.domain.domain | The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar. | keyword |
+| sublime_security.email_message.headers.delivered_to.domain.punycode | Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com. | keyword |
+| sublime_security.email_message.headers.delivered_to.domain.root_domain | The root domain, including the TLD. | keyword |
+| sublime_security.email_message.headers.delivered_to.domain.sld | Second-level domain, e.g. 'windows' for the domain 'windows.net'. | keyword |
+| sublime_security.email_message.headers.delivered_to.domain.subdomain | Subdomain, e.g. 'drive' for the domain 'drive.google.com'. | keyword |
+| sublime_security.email_message.headers.delivered_to.domain.tld | The domain's top-level domain. E.g. the TLD of google.com is 'com'. | keyword |
+| sublime_security.email_message.headers.delivered_to.domain.valid | Whether the domain is valid. | boolean |
+| sublime_security.email_message.headers.delivered_to.email | Full email address. | keyword |
+| sublime_security.email_message.headers.delivered_to.local_part | Local-part, i.e. before the @. | keyword |
+| sublime_security.email_message.headers.domains.domain | The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar. | keyword |
+| sublime_security.email_message.headers.domains.punycode | Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com. | keyword |
+| sublime_security.email_message.headers.domains.root_domain | The root domain, including the TLD. | keyword |
+| sublime_security.email_message.headers.domains.sld | Second-level domain, e.g. 'windows' for the domain 'windows.net'. | keyword |
+| sublime_security.email_message.headers.domains.subdomain | Subdomain, e.g. 'drive' for the domain 'drive.google.com'. | keyword |
+| sublime_security.email_message.headers.domains.tld | The domain's top-level domain. E.g. the TLD of google.com is 'com'. | keyword |
+| sublime_security.email_message.headers.domains.valid | Whether the domain is valid. | boolean |
+| sublime_security.email_message.headers.hops.authentication_results.compauth.reason | Reason for the verdict. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.compauth.verdict | Verdict of the compauth. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.dkim | Verdict of the Domain Keys Identified Mail check. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.dkim_details.algorithm | Signing algorithm. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.dkim_details.body_hash | Body Hash. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.dkim_details.domain | Domain identified in the DKIM signature if any. This is the domain that's queried for the public key. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.dkim_details.headers | Header fields signed by the algorithm. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.dkim_details.instance | Instance number of this signature (if ARC). | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.dkim_details.selector | Selector. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.dkim_details.signature | Signature of headers and body. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.dkim_details.type | The type of signature, derived from the field name. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.dkim_details.version | Version. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.dmarc | Verdict of the Domain-based Message Authentication, Reporting & Conformance check. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.dmarc_details.action | Indicates the action taken by the spam filter based on the results of the DMARC check. For more information see https://docs.microsoft.com/en-us/microsoft-365/security/office-365-security/anti-spam-message-headers?view=o365-worldwide#authentication-results-message-header-fields. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.dmarc_details.disposition | Gmail-applied policy. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.dmarc_details.from.domain | The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.dmarc_details.from.punycode | Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.dmarc_details.from.root_domain | The root domain, including the TLD. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.dmarc_details.from.sld | Second-level domain, e.g. 'windows' for the domain 'windows.net'. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.dmarc_details.from.subdomain | Subdomain, e.g. 'drive' for the domain 'drive.google.com'. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.dmarc_details.from.tld | The domain's top-level domain. E.g. the TLD of google.com is 'com'. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.dmarc_details.from.valid | Whether the domain is valid. | boolean |
+| sublime_security.email_message.headers.hops.authentication_results.dmarc_details.policy | Policy for the organizational domain. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.dmarc_details.sub_policy | Policy for the subdomain of the organizational domain. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.dmarc_details.verdict | Describes the results of the DMARC check for the message. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.dmarc_details.version | DMARC version. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.instance | Instance number of this auth result (if ARC). | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.server.domain | The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.server.punycode | Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.server.root_domain | The root domain, including the TLD. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.server.sld | Second-level domain, e.g. 'windows' for the domain 'windows.net'. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.server.subdomain | Subdomain, e.g. 'drive' for the domain 'drive.google.com'. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.server.tld | The domain's top-level domain. E.g. the TLD of google.com is 'com'. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.server.valid | Whether the domain is valid. | boolean |
+| sublime_security.email_message.headers.hops.authentication_results.spf | Verdict of the Sender Policy Framework. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.spf_details.client_ip.ip | The raw IP. | ip |
+| sublime_security.email_message.headers.hops.authentication_results.spf_details.description | Verbose description of the SPF verdict. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.spf_details.designator | Email or domain of the designating body. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.spf_details.helo.domain | The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.spf_details.helo.punycode | Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.spf_details.helo.root_domain | The root domain, including the TLD. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.spf_details.helo.sld | Second-level domain, e.g. 'windows' for the domain 'windows.net'. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.spf_details.helo.subdomain | Subdomain, e.g. 'drive' for the domain 'drive.google.com'. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.spf_details.helo.tld | The domain's top-level domain. E.g. the TLD of google.com is 'com'. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.spf_details.helo.valid | Whether the domain is valid. | boolean |
+| sublime_security.email_message.headers.hops.authentication_results.spf_details.server.domain | The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.spf_details.server.punycode | Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.spf_details.server.root_domain | The root domain, including the TLD. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.spf_details.server.sld | Second-level domain, e.g. 'windows' for the domain 'windows.net'. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.spf_details.server.subdomain | Subdomain, e.g. 'drive' for the domain 'drive.google.com'. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.spf_details.server.tld | The domain's top-level domain. E.g. the TLD of google.com is 'com'. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.spf_details.server.valid | Whether the domain is valid. | boolean |
+| sublime_security.email_message.headers.hops.authentication_results.spf_details.verdict | Verdict of the SPF. | keyword |
+| sublime_security.email_message.headers.hops.authentication_results.type | The type of authentication result, derived from the field name. | keyword |
+| sublime_security.email_message.headers.hops.fields | | object |
+| sublime_security.email_message.headers.hops.index | Index indicates the order in which a hop occurred from sender to recipient. | long |
+| sublime_security.email_message.headers.hops.received.additional.raw | The raw string for remaining additional clauses, such as transport information. | keyword |
+| sublime_security.email_message.headers.hops.received.id.raw | The raw string of 'id' section. | keyword |
+| sublime_security.email_message.headers.hops.received.link.raw | The raw string of 'via' section. | keyword |
+| sublime_security.email_message.headers.hops.received.mailbox.raw | The raw string of 'for' section. | keyword |
+| sublime_security.email_message.headers.hops.received.protocol.raw | The raw string of 'with' section. | keyword |
+| sublime_security.email_message.headers.hops.received.server.raw | The raw string of 'by' section. | keyword |
+| sublime_security.email_message.headers.hops.received.source.raw | The raw string of 'from' section. | keyword |
+| sublime_security.email_message.headers.hops.received.time | Time parsed from the Received header. | date |
+| sublime_security.email_message.headers.hops.received.zone_offset | Timezone offset parsed from the Received header. | keyword |
+| sublime_security.email_message.headers.hops.received_spf.client_ip.ip | The raw IP. | ip |
+| sublime_security.email_message.headers.hops.received_spf.description | Verbose description of the SPF verdict. | keyword |
+| sublime_security.email_message.headers.hops.received_spf.designator | Email or domain of the designating body. | keyword |
+| sublime_security.email_message.headers.hops.received_spf.helo.domain | The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar. | keyword |
+| sublime_security.email_message.headers.hops.received_spf.helo.punycode | Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com. | keyword |
+| sublime_security.email_message.headers.hops.received_spf.helo.root_domain | The root domain, including the TLD. | keyword |
+| sublime_security.email_message.headers.hops.received_spf.helo.sld | Second-level domain, e.g. 'windows' for the domain 'windows.net'. | keyword |
+| sublime_security.email_message.headers.hops.received_spf.helo.subdomain | Subdomain, e.g. 'drive' for the domain 'drive.google.com'. | keyword |
+| sublime_security.email_message.headers.hops.received_spf.helo.tld | The domain's top-level domain. E.g. the TLD of google.com is 'com'. | keyword |
+| sublime_security.email_message.headers.hops.received_spf.helo.valid | Whether the domain is valid. | boolean |
+| sublime_security.email_message.headers.hops.received_spf.server.domain | The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar. | keyword |
+| sublime_security.email_message.headers.hops.received_spf.server.punycode | Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com. | keyword |
+| sublime_security.email_message.headers.hops.received_spf.server.root_domain | The root domain, including the TLD. | keyword |
+| sublime_security.email_message.headers.hops.received_spf.server.sld | Second-level domain, e.g. 'windows' for the domain 'windows.net'. | keyword |
+| sublime_security.email_message.headers.hops.received_spf.server.subdomain | Subdomain, e.g. 'drive' for the domain 'drive.google.com'. | keyword |
+| sublime_security.email_message.headers.hops.received_spf.server.tld | The domain's top-level domain. E.g. the TLD of google.com is 'com'. | keyword |
+| sublime_security.email_message.headers.hops.received_spf.server.valid | Whether the domain is valid. | boolean |
+| sublime_security.email_message.headers.hops.received_spf.verdict | Verdict of the SPF. | keyword |
+| sublime_security.email_message.headers.hops.signature.algorithm | Signing algorithm. | keyword |
+| sublime_security.email_message.headers.hops.signature.body_hash | Body Hash. | keyword |
+| sublime_security.email_message.headers.hops.signature.domain | Domain identified in the DKIM signature if any. This is the domain that's queried for the public key. | keyword |
+| sublime_security.email_message.headers.hops.signature.headers | Header fields signed by the algorithm. | keyword |
+| sublime_security.email_message.headers.hops.signature.instance | Instance number of this signature (if ARC). | keyword |
+| sublime_security.email_message.headers.hops.signature.selector | Selector. | keyword |
+| sublime_security.email_message.headers.hops.signature.signature | Signature of headers and body. | keyword |
+| sublime_security.email_message.headers.hops.signature.type | The type of signature, derived from the field name. | keyword |
+| sublime_security.email_message.headers.hops.signature.version | Version. | keyword |
+| sublime_security.email_message.headers.in_reply_to | In-Reply-To header value which identifies its parent message if exists. | keyword |
+| sublime_security.email_message.headers.ips.ip | The raw IP. | keyword |
+| sublime_security.email_message.headers.mailer | X-Mailer or User-Agent extracted from headers. | keyword |
+| sublime_security.email_message.headers.message_id | Message-ID extracted from the header. | keyword |
+| sublime_security.email_message.headers.references | The Message-IDs of the other messages within this chain. | keyword |
+| sublime_security.email_message.headers.reply_to.display_name | Display name. | keyword |
+| sublime_security.email_message.headers.reply_to.email.domain.domain | The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar. | keyword |
+| sublime_security.email_message.headers.reply_to.email.domain.punycode | Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com. | keyword |
+| sublime_security.email_message.headers.reply_to.email.domain.root_domain | The root domain, including the TLD. | keyword |
+| sublime_security.email_message.headers.reply_to.email.domain.sld | Second-level domain, e.g. 'windows' for the domain 'windows.net'. | keyword |
+| sublime_security.email_message.headers.reply_to.email.domain.subdomain | Subdomain, e.g. 'drive' for the domain 'drive.google.com'. | keyword |
+| sublime_security.email_message.headers.reply_to.email.domain.tld | The domain's top-level domain. E.g. the TLD of google.com is 'com'. | keyword |
+| sublime_security.email_message.headers.reply_to.email.domain.valid | Whether the domain is valid. | boolean |
+| sublime_security.email_message.headers.reply_to.email.local_part | Local-part, i.e. before the @. | keyword |
+| sublime_security.email_message.headers.reply_to.email.value | Full email address. | keyword |
+| sublime_security.email_message.headers.return_path.domain.domain | The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar. | keyword |
+| sublime_security.email_message.headers.return_path.domain.punycode | Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com. | keyword |
+| sublime_security.email_message.headers.return_path.domain.root_domain | The root domain, including the TLD. | keyword |
+| sublime_security.email_message.headers.return_path.domain.sld | Second-level domain, e.g. 'windows' for the domain 'windows.net'. | keyword |
+| sublime_security.email_message.headers.return_path.domain.subdomain | Subdomain, e.g. 'drive' for the domain 'drive.google.com'. | keyword |
+| sublime_security.email_message.headers.return_path.domain.tld | The domain's top-level domain. E.g. the TLD of google.com is 'com'. | keyword |
+| sublime_security.email_message.headers.return_path.domain.valid | Whether the domain is valid. | boolean |
+| sublime_security.email_message.headers.return_path.email | Full email address. | keyword |
+| sublime_security.email_message.headers.return_path.local_part | Local-part, i.e. before the @. | keyword |
+| sublime_security.email_message.headers.x_authenticated_domain.domain | The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar. | keyword |
+| sublime_security.email_message.headers.x_authenticated_domain.punycode | Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com. | keyword |
+| sublime_security.email_message.headers.x_authenticated_domain.root_domain | The root domain, including the TLD. | keyword |
+| sublime_security.email_message.headers.x_authenticated_domain.sld | Second-level domain, e.g. 'windows' for the domain 'windows.net'. | keyword |
+| sublime_security.email_message.headers.x_authenticated_domain.subdomain | Subdomain, e.g. 'drive' for the domain 'drive.google.com'. | keyword |
+| sublime_security.email_message.headers.x_authenticated_domain.tld | The domain's top-level domain. E.g. the TLD of google.com is 'com'. | keyword |
+| sublime_security.email_message.headers.x_authenticated_domain.valid | Whether the domain is valid. | boolean |
+| sublime_security.email_message.headers.x_authenticated_sender.domain.domain | The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar. | keyword |
+| sublime_security.email_message.headers.x_authenticated_sender.domain.punycode | Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com. | keyword |
+| sublime_security.email_message.headers.x_authenticated_sender.domain.root_domain | The root domain, including the TLD. | keyword |
+| sublime_security.email_message.headers.x_authenticated_sender.domain.sld | Second-level domain, e.g. 'windows' for the domain 'windows.net'. | keyword |
+| sublime_security.email_message.headers.x_authenticated_sender.domain.subdomain | Subdomain, e.g. 'drive' for the domain 'drive.google.com'. | keyword |
+| sublime_security.email_message.headers.x_authenticated_sender.domain.tld | The domain's top-level domain. E.g. the TLD of google.com is 'com'. | keyword |
+| sublime_security.email_message.headers.x_authenticated_sender.domain.valid | Whether the domain is valid. | boolean |
+| sublime_security.email_message.headers.x_authenticated_sender.email | Full email address. | keyword |
+| sublime_security.email_message.headers.x_authenticated_sender.local_part | Local-part, i.e. before the @. | keyword |
+| sublime_security.email_message.headers.x_client_ip.ip | The raw IP. | ip |
+| sublime_security.email_message.headers.x_originating_ip.ip | The raw IP. | ip |
+| sublime_security.email_message.headers.x_secure_server_account | X-SecureServer-Acct header, which represents a unique identifier associated with the sender's email account on a secure server and can be used to trace the email back to a specific account or user. | keyword |
+| sublime_security.email_message.headers.x_sender.domain.domain | The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar. | keyword |
+| sublime_security.email_message.headers.x_sender.domain.punycode | Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com. | keyword |
+| sublime_security.email_message.headers.x_sender.domain.root_domain | The root domain, including the TLD. | keyword |
+| sublime_security.email_message.headers.x_sender.domain.sld | Second-level domain, e.g. 'windows' for the domain 'windows.net'. | keyword |
+| sublime_security.email_message.headers.x_sender.domain.subdomain | Subdomain, e.g. 'drive' for the domain 'drive.google.com'. | keyword |
+| sublime_security.email_message.headers.x_sender.domain.tld | The domain's top-level domain. E.g. the TLD of google.com is 'com'. | keyword |
+| sublime_security.email_message.headers.x_sender.domain.valid | Whether the domain is valid. | boolean |
+| sublime_security.email_message.headers.x_sender.email | Full email address. | keyword |
+| sublime_security.email_message.headers.x_sender.local_part | Local-part, i.e. before the @. | keyword |
+| sublime_security.email_message.mailbox.display_name | Display name. | keyword |
+| sublime_security.email_message.mailbox.email.domain.domain | The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar. | keyword |
+| sublime_security.email_message.mailbox.email.domain.punycode | Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com. | keyword |
+| sublime_security.email_message.mailbox.email.domain.root_domain | The root domain, including the TLD. | keyword |
+| sublime_security.email_message.mailbox.email.domain.sld | Second-level domain, e.g. 'windows' for the domain 'windows.net'. | keyword |
+| sublime_security.email_message.mailbox.email.domain.subdomain | Subdomain, e.g. 'drive' for the domain 'drive.google.com'. | keyword |
+| sublime_security.email_message.mailbox.email.domain.tld | The domain's top-level domain. E.g. the TLD of google.com is 'com'. | keyword |
+| sublime_security.email_message.mailbox.email.domain.valid | Whether the domain is valid. | boolean |
+| sublime_security.email_message.mailbox.email.local_part | Local-part, i.e. before the @. | keyword |
+| sublime_security.email_message.mailbox.email.value | Full email address. | keyword |
+| sublime_security.email_message.meta.canonical_id | A deterministic ID, generated from metadata such as Attachments, Body, Subject, Sender and is used to group similar messages/campaigns together. | keyword |
+| sublime_security.email_message.meta.created_at | Creation time of the data model. | date |
+| sublime_security.email_message.meta.effective_at | Effective time of the data model, used for evaluation against lists and historical functions such as sender profiles or whois. | date |
+| sublime_security.email_message.meta.id | Message ID. | keyword |
+| sublime_security.email_message.recipients.bcc.display_name | Display name. | keyword |
+| sublime_security.email_message.recipients.bcc.email.domain.domain | The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar. | keyword |
+| sublime_security.email_message.recipients.bcc.email.domain.punycode | Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com. | keyword |
+| sublime_security.email_message.recipients.bcc.email.domain.root_domain | The root domain, including the TLD. | keyword |
+| sublime_security.email_message.recipients.bcc.email.domain.sld | Second-level domain, e.g. 'windows' for the domain 'windows.net'. | keyword |
+| sublime_security.email_message.recipients.bcc.email.domain.subdomain | Subdomain, e.g. 'drive' for the domain 'drive.google.com'. | keyword |
+| sublime_security.email_message.recipients.bcc.email.domain.tld | The domain's top-level domain. E.g. the TLD of google.com is 'com'. | keyword |
+| sublime_security.email_message.recipients.bcc.email.domain.valid | Whether the domain is valid. | boolean |
+| sublime_security.email_message.recipients.bcc.email.local_part | Local-part, i.e. before the @. | keyword |
+| sublime_security.email_message.recipients.bcc.email.value | Full email address. | keyword |
+| sublime_security.email_message.recipients.cc.display_name | Display name. | keyword |
+| sublime_security.email_message.recipients.cc.email.domain.domain | The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar. | keyword |
+| sublime_security.email_message.recipients.cc.email.domain.punycode | Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com. | keyword |
+| sublime_security.email_message.recipients.cc.email.domain.root_domain | The root domain, including the TLD. | keyword |
+| sublime_security.email_message.recipients.cc.email.domain.sld | Second-level domain, e.g. 'windows' for the domain 'windows.net'. | keyword |
+| sublime_security.email_message.recipients.cc.email.domain.subdomain | Subdomain, e.g. 'drive' for the domain 'drive.google.com'. | keyword |
+| sublime_security.email_message.recipients.cc.email.domain.tld | The domain's top-level domain. E.g. the TLD of google.com is 'com'. | keyword |
+| sublime_security.email_message.recipients.cc.email.domain.valid | Whether the domain is valid. | boolean |
+| sublime_security.email_message.recipients.cc.email.local_part | Local-part, i.e. before the @. | keyword |
+| sublime_security.email_message.recipients.cc.email.value | Full email address. | keyword |
+| sublime_security.email_message.recipients.to.display_name | Display name. | keyword |
+| sublime_security.email_message.recipients.to.email.domain.domain | The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar. | keyword |
+| sublime_security.email_message.recipients.to.email.domain.punycode | Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com. | keyword |
+| sublime_security.email_message.recipients.to.email.domain.root_domain | The root domain, including the TLD. | keyword |
+| sublime_security.email_message.recipients.to.email.domain.sld | Second-level domain, e.g. 'windows' for the domain 'windows.net'. | keyword |
+| sublime_security.email_message.recipients.to.email.domain.subdomain | Subdomain, e.g. 'drive' for the domain 'drive.google.com'. | keyword |
+| sublime_security.email_message.recipients.to.email.domain.tld | The domain's top-level domain. E.g. the TLD of google.com is 'com'. | keyword |
+| sublime_security.email_message.recipients.to.email.domain.valid | Whether the domain is valid. | boolean |
+| sublime_security.email_message.recipients.to.email.local_part | Local-part, i.e. before the @. | keyword |
+| sublime_security.email_message.recipients.to.email.value | Full email address. | keyword |
+| sublime_security.email_message.sender.display_name | Display name. | keyword |
+| sublime_security.email_message.sender.email.domain.domain | The fully qualified domain name (FQDN). This may not always be routable, e.g. when an email address contains a domain that is just a TLD with no SLD, e.g. foo@WIN-bar. | keyword |
+| sublime_security.email_message.sender.email.domain.punycode | Interpreted punycode if the domain starts with xn--. For example, if 'domain' is 'xn--ublimesecurity-4xc.com' then 'punycode' is śublimesecurity.com. | keyword |
+| sublime_security.email_message.sender.email.domain.root_domain | The root domain, including the TLD. | keyword |
+| sublime_security.email_message.sender.email.domain.sld | Second-level domain, e.g. 'windows' for the domain 'windows.net'. | keyword |
+| sublime_security.email_message.sender.email.domain.subdomain | Subdomain, e.g. 'drive' for the domain 'drive.google.com'. | keyword |
+| sublime_security.email_message.sender.email.domain.tld | The domain's top-level domain. E.g. the TLD of google.com is 'com'. | keyword |
+| sublime_security.email_message.sender.email.domain.valid | Whether the domain is valid. | boolean |
+| sublime_security.email_message.sender.email.local_part | Local-part, i.e. before the @. | keyword |
+| sublime_security.email_message.sender.email.value | Full email address. | keyword |
+| sublime_security.email_message.subject.subject | Subject of the email. | keyword |
+| sublime_security.email_message.type.inbound | Message was sent from someone outside your organization, to at least one recipient inside your organization. | boolean |
+| sublime_security.email_message.type.internal | Message was sent from someone inside your organization, to at least one recipient inside your organization. Messages must be authenticated by either SPF or DKIM to be treated as internal. | boolean |
+| sublime_security.email_message.type.outbound | Message was sent from someone inside your organization, to at least one recipient outside your organization. | boolean |
+
+
+### Message Event
+
+This is the `message_event` dataset.
+
+#### Example
+
+An example event for `message_event` looks as following:
+
+```json
+{
+ "@timestamp": "2024-07-12T05:15:08.221Z",
+ "agent": {
+ "ephemeral_id": "384edc61-b94b-40cf-9cc6-86d5418d35e5",
+ "id": "5f3fcbb9-1a97-4ff3-857f-167af6664464",
+ "name": "docker-fleet-agent",
+ "type": "filebeat",
+ "version": "8.13.0"
+ },
+ "data_stream": {
+ "dataset": "sublime_security.message_event",
+ "namespace": "17638",
+ "type": "logs"
+ },
+ "ecs": {
+ "version": "8.11.0"
+ },
+ "elastic_agent": {
+ "id": "5f3fcbb9-1a97-4ff3-857f-167af6664464",
+ "snapshot": false,
+ "version": "8.13.0"
+ },
+ "email": {
+ "from": {
+ "address": [
+ "bob.demo@gmail.com"
+ ]
+ },
+ "subject": "Urgent: Wire transfer",
+ "to": {
+ "address": [
+ "xyz@example.com",
+ "user12@example.com",
+ "user@example.com",
+ "leon12@example.com"
+ ]
+ }
+ },
+ "event": {
+ "agent_id_status": "verified",
+ "category": [
+ "email"
+ ],
+ "dataset": "sublime_security.message_event",
+ "id": "9c426680-5cdf-4283-adbd-d79ba0e52434",
+ "ingested": "2024-08-28T10:36:57Z",
+ "kind": "event",
+ "original": "{\"canonical_id\":\"dd97dc82731ff7e82edfccaef59826cccd271bd4423e09d1e150ade83037cb37\",\"created_at\":\"2024-07-12T05:15:08.221838Z\",\"external_id\":\"7a2dfbeb-1310-48fc-9ed9-f480608a0306\",\"forward_recipients\":[],\"forwarded_at\":null,\"id\":\"9c426680-5cdf-4283-adbd-d79ba0e52434\",\"landed_in_spam\":false,\"mailbox\":{\"email\":\"demo@example.com\",\"external_id\":null,\"id\":\"433fe142-e2e5-4372-84ea-480279543a9b\"},\"message_source_id\":\"257982a1-f106-4c68-bc64-ff032914ed5f\",\"read_at\":null,\"recipients\":[{\"email\":\"xyz@example.com\"},{\"email\":\"user12@example.com\"},{\"email\":\"user@example.com\"},{\"email\":\"leon12@example.com\"}],\"replied_at\":null,\"sender\":{\"display_name\":\"Bob Doe\",\"email\":\"bob.demo@gmail.com\"},\"subject\":\"Urgent: Wire transfer\"}",
+ "type": [
+ "info"
+ ]
+ },
+ "input": {
+ "type": "cel"
+ },
+ "observer": {
+ "product": "Sublime Security",
+ "vendor": "Sublime Security"
+ },
+ "related": {
+ "user": [
+ "xyz@example.com",
+ "user12@example.com",
+ "user@example.com",
+ "leon12@example.com",
+ "Bob Doe",
+ "bob.demo@gmail.com"
+ ]
+ },
+ "source": {
+ "user": {
+ "name": "Bob Doe"
+ }
+ },
+ "sublime_security": {
+ "message_event": {
+ "canonical_id": "dd97dc82731ff7e82edfccaef59826cccd271bd4423e09d1e150ade83037cb37",
+ "created_at": "2024-07-12T05:15:08.221Z",
+ "external_id": "7a2dfbeb-1310-48fc-9ed9-f480608a0306",
+ "id": "9c426680-5cdf-4283-adbd-d79ba0e52434",
+ "landed_in_spam": false,
+ "mailbox": {
+ "email": "demo@example.com",
+ "id": "433fe142-e2e5-4372-84ea-480279543a9b"
+ },
+ "message_source_id": "257982a1-f106-4c68-bc64-ff032914ed5f",
+ "recipients": [
+ {
+ "email": "xyz@example.com"
+ },
+ {
+ "email": "user12@example.com"
+ },
+ {
+ "email": "user@example.com"
+ },
+ {
+ "email": "leon12@example.com"
+ }
+ ],
+ "sender": {
+ "display_name": "Bob Doe",
+ "email": "bob.demo@gmail.com"
+ },
+ "subject": "Urgent: Wire transfer"
+ }
+ },
+ "tags": [
+ "preserve_original_event",
+ "preserve_duplicate_custom_fields",
+ "forwarded",
+ "sublime_security-message_event"
+ ]
+}
+```
+
+**Exported fields**
+
+| Field | Description | Type |
+|---|---|---|
+| @timestamp | Event timestamp. | date |
+| data_stream.dataset | Data stream dataset. | constant_keyword |
+| data_stream.namespace | Data stream namespace. | constant_keyword |
+| data_stream.type | Data stream type. | constant_keyword |
+| event.dataset | Event dataset. | constant_keyword |
+| event.module | Event module. | constant_keyword |
+| input.type | Type of filebeat input. | keyword |
+| log.offset | Log offset. | long |
+| sublime_security.message_event.canonical_id | Canonical ID of the message. | keyword |
+| sublime_security.message_event.created_at | Time this message was added to sublime_security. | date |
+| sublime_security.message_event.data.flagged_rules.id | ID of the flagged rule. | keyword |
+| sublime_security.message_event.data.flagged_rules.name | Name of the flagged rule. | keyword |
+| sublime_security.message_event.data.flagged_rules.severity | Severity of the flagged rule. | keyword |
+| sublime_security.message_event.data.flagged_rules.tags | List of tags for the flagged rule. | keyword |
+| sublime_security.message_event.data.triggered_actions.id | | keyword |
+| sublime_security.message_event.data.triggered_actions.name | | keyword |
+| sublime_security.message_event.data.triggered_actions.type | | keyword |
+| sublime_security.message_event.external_id | ID of the message in the source system (e.g., Office 365 or Google Workspace). | keyword |
+| sublime_security.message_event.forward_recipients | Email addresses this message was forwarded to by the recipient mailbox. | keyword |
+| sublime_security.message_event.forwarded_at | Time this message was forwarded by the recipient mailbox. A null value indicates that it has not yet been forwarded. | date |
+| sublime_security.message_event.id | Message ID. | keyword |
+| sublime_security.message_event.landed_in_spam | Whether the message landed in the recipient's spam folder. | boolean |
+| sublime_security.message_event.mailbox.email | Mailbox email address. | keyword |
+| sublime_security.message_event.mailbox.external_id | ID of the mailbox in the source system (e.g., Office 365 or Google Workspace). | keyword |
+| sublime_security.message_event.mailbox.id | Mailbox ID. | keyword |
+| sublime_security.message_event.message_source_id | ID of the message source of the message. | keyword |
+| sublime_security.message_event.read_at | Time this message was read in the user's mailbox. A null value indicates that it has not yet been marked read. | date |
+| sublime_security.message_event.recipients.email | Email address. | keyword |
+| sublime_security.message_event.replied_at | Time that this message was replied to by the recipient mailbox. A null value indicates that it has not yet been replied to by the recipient. | date |
+| sublime_security.message_event.sender.display_name | Display name. | keyword |
+| sublime_security.message_event.sender.email | Email address. | keyword |
+| sublime_security.message_event.subject | Subject of the message. | keyword |
+| sublime_security.message_event.type | | keyword |
+
diff --git a/packages/sublime_security/img/sublime_security-audit.png b/packages/sublime_security/img/sublime_security-audit.png
new file mode 100644
index 0000000000000000000000000000000000000000..dcd643bf146ff21b31c5178002eaaa6970a55629
GIT binary patch
literal 382287
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