Skip to content

Commit aebfd82

Browse files
committed
add support for minimal field retention
The fields were identified by running the following shell script in the the security_detection_engine/kibana/security_rule directory. for f in *; do jq 'select(.attributes.required_fields != null)|.attributes.required_fields|.[]|select(.name != null)|select(.name|contains("cloudtrail.flattened"))|.name'<$f done|sort|uniq The test for this is derived from the test-copy-object-json.log test case which includes one of the required fields and a number of other fields under cloudtrail.flattened. So comparing the test added here to that demonstrates whether is works.
1 parent 9030dc4 commit aebfd82

File tree

5 files changed

+216
-3
lines changed

5 files changed

+216
-3
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"eventVersion":"1.09","userIdentity":{"type":"IAMUser","principalId":"ACCESSKEYID","arn":"arn:aws:iam::000000000:user/test@elastic.co","accountId":"000000000","accessKeyId":"ACCESSKEYID","userName":"test@elastic.co"},"eventTime":"2024-10-08T12:24:16Z","eventSource":"s3.amazonaws.com","eventName":"CopyObject","awsRegion":"us-east-1","sourceIPAddress":"216.160.83.56","userAgent":"[aws-cli/2.17.60 md/awscrt#0.21.2 ua/2.0 os/macos#23.6.0 md/arch#x86_64 lang/python#3.12.6 md/pyimpl#CPython cfg/retry-mode#standard md/installer#exe md/prompt#off md/command#s3api.copy-object]","requestParameters":{"bucketName":"elastic-cspm-cloudtrail-test-bucket","Host":"elastic-cspm-cloudtrail-test-bucket.s3.us-east-1.amazonaws.com","x-amz-copy-source":"elastic-cspm-cloudtrail-test-bucket/test-copy-object/README.md","key":"test-copy-object/README-copy.md"},"responseElements":{"x-amz-server-side-encryption":"AES256"},"additionalEventData":{"SignatureVersion":"SigV4","CipherSuite":"TLS_AES_128_GCM_SHA256","bytesTransferredIn":0,"SSEApplied":"Default_SSE_S3","AuthenticationMethod":"AuthHeader","x-amz-id-2":"hFhfe14yINVvz+alr1rC5zPFufFU087OGEbVwf5HpD1BYs5D2llscEUSD7DUGjlSYkOEoay+oVk=","bytesTransferredOut":224},"requestID":"62A9N2AH4P4YKG2B","eventID":"0c06e2ff-5e88-44e6-a081-57871bbe770b","readOnly":false,"resources":[{"type":"AWS::S3::Object","ARN":"arn:aws:s3:::elastic-cspm-cloudtrail-test-bucket/test-copy-object/README-copy.md"},{"accountId":"000000000","type":"AWS::S3::Bucket","ARN":"arn:aws:s3:::elastic-cspm-cloudtrail-test-bucket"},{"type":"AWS::S3::Object","ARN":"arn:aws:s3:::elastic-cspm-cloudtrail-test-bucket/test-copy-object/README.md"}],"eventType":"AwsApiCall","recipientAccountId":"000000000","eventCategory":"Data","tlsDetails":{"tlsVersion":"TLSv1.3","cipherSuite":"TLS_AES_128_GCM_SHA256","clientProvidedHostHeader":"elastic-cspm-cloudtrail-test-bucket.s3.us-east-1.amazonaws.com"}}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
dynamic_fields:
2+
# This can be removed after ES 8.16.2 is set as the minimum version supported in the manifest.
3+
# Once removed, it requires to update pipeline tests to remove the trailing dot where required.
4+
# Relates: https://github.com/elastic/elasticsearch/pull/117213
5+
"user_agent.version": '^\d+\.\d+(\.|\..*)?$'
6+
fields:
7+
# Simulate @timestamp value from Filebeat.
8+
'@timestamp': '2021-11-11T01:02:03.123456789Z'
9+
tags:
10+
- preserve_original_event
11+
- actor_target_mapping
12+
_conf:
13+
retain: minimal
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
{
2+
"expected": [
3+
{
4+
"@timestamp": "2024-10-08T12:24:16.000Z",
5+
"actor": {
6+
"entity": {
7+
"id": [
8+
"arn:aws:iam::000000000:user/test@elastic.co"
9+
]
10+
}
11+
},
12+
"aws": {
13+
"cloudtrail": {
14+
"additional_eventdata": "{SignatureVersion=SigV4, CipherSuite=TLS_AES_128_GCM_SHA256, bytesTransferredIn=0, SSEApplied=Default_SSE_S3, AuthenticationMethod=AuthHeader, x-amz-id-2=hFhfe14yINVvz+alr1rC5zPFufFU087OGEbVwf5HpD1BYs5D2llscEUSD7DUGjlSYkOEoay+oVk=, bytesTransferredOut=224}",
15+
"event_category": "Data",
16+
"event_type": "AwsApiCall",
17+
"event_version": "1.09",
18+
"flattened": {
19+
"additional_eventdata": {
20+
"SSEApplied": "Default_SSE_S3"
21+
}
22+
},
23+
"read_only": false,
24+
"recipient_account_id": "000000000",
25+
"request_id": "62A9N2AH4P4YKG2B",
26+
"request_parameters": "{bucketName=elastic-cspm-cloudtrail-test-bucket, Host=elastic-cspm-cloudtrail-test-bucket.s3.us-east-1.amazonaws.com, x-amz-copy-source=elastic-cspm-cloudtrail-test-bucket/test-copy-object/README.md, key=test-copy-object/README-copy.md}",
27+
"resources": [
28+
{
29+
"arn": "arn:aws:s3:::elastic-cspm-cloudtrail-test-bucket/test-copy-object/README.md",
30+
"type": "AWS::S3::Object"
31+
},
32+
{
33+
"arn": "arn:aws:s3:::elastic-cspm-cloudtrail-test-bucket/test-copy-object/README-copy.md",
34+
"type": "AWS::S3::Object"
35+
},
36+
{
37+
"account_id": "000000000",
38+
"arn": "arn:aws:s3:::elastic-cspm-cloudtrail-test-bucket",
39+
"type": "AWS::S3::Bucket"
40+
}
41+
],
42+
"response_elements": "{x-amz-server-side-encryption=AES256}",
43+
"user_identity": {
44+
"access_key_id": "ACCESSKEYID",
45+
"arn": "arn:aws:iam::000000000:user/test@elastic.co",
46+
"type": "IAMUser"
47+
}
48+
}
49+
},
50+
"cloud": {
51+
"account": {
52+
"id": "000000000"
53+
},
54+
"region": "us-east-1"
55+
},
56+
"ecs": {
57+
"version": "8.11.0"
58+
},
59+
"event": {
60+
"action": "CopyObject",
61+
"created": "2021-11-11T01:02:03.123456789Z",
62+
"id": "0c06e2ff-5e88-44e6-a081-57871bbe770b",
63+
"kind": "event",
64+
"original": "{\"eventVersion\":\"1.09\",\"userIdentity\":{\"type\":\"IAMUser\",\"principalId\":\"ACCESSKEYID\",\"arn\":\"arn:aws:iam::000000000:user/test@elastic.co\",\"accountId\":\"000000000\",\"accessKeyId\":\"ACCESSKEYID\",\"userName\":\"test@elastic.co\"},\"eventTime\":\"2024-10-08T12:24:16Z\",\"eventSource\":\"s3.amazonaws.com\",\"eventName\":\"CopyObject\",\"awsRegion\":\"us-east-1\",\"sourceIPAddress\":\"216.160.83.56\",\"userAgent\":\"[aws-cli/2.17.60 md/awscrt#0.21.2 ua/2.0 os/macos#23.6.0 md/arch#x86_64 lang/python#3.12.6 md/pyimpl#CPython cfg/retry-mode#standard md/installer#exe md/prompt#off md/command#s3api.copy-object]\",\"requestParameters\":{\"bucketName\":\"elastic-cspm-cloudtrail-test-bucket\",\"Host\":\"elastic-cspm-cloudtrail-test-bucket.s3.us-east-1.amazonaws.com\",\"x-amz-copy-source\":\"elastic-cspm-cloudtrail-test-bucket/test-copy-object/README.md\",\"key\":\"test-copy-object/README-copy.md\"},\"responseElements\":{\"x-amz-server-side-encryption\":\"AES256\"},\"additionalEventData\":{\"SignatureVersion\":\"SigV4\",\"CipherSuite\":\"TLS_AES_128_GCM_SHA256\",\"bytesTransferredIn\":0,\"SSEApplied\":\"Default_SSE_S3\",\"AuthenticationMethod\":\"AuthHeader\",\"x-amz-id-2\":\"hFhfe14yINVvz+alr1rC5zPFufFU087OGEbVwf5HpD1BYs5D2llscEUSD7DUGjlSYkOEoay+oVk=\",\"bytesTransferredOut\":224},\"requestID\":\"62A9N2AH4P4YKG2B\",\"eventID\":\"0c06e2ff-5e88-44e6-a081-57871bbe770b\",\"readOnly\":false,\"resources\":[{\"type\":\"AWS::S3::Object\",\"ARN\":\"arn:aws:s3:::elastic-cspm-cloudtrail-test-bucket/test-copy-object/README-copy.md\"},{\"accountId\":\"000000000\",\"type\":\"AWS::S3::Bucket\",\"ARN\":\"arn:aws:s3:::elastic-cspm-cloudtrail-test-bucket\"},{\"type\":\"AWS::S3::Object\",\"ARN\":\"arn:aws:s3:::elastic-cspm-cloudtrail-test-bucket/test-copy-object/README.md\"}],\"eventType\":\"AwsApiCall\",\"recipientAccountId\":\"000000000\",\"eventCategory\":\"Data\",\"tlsDetails\":{\"tlsVersion\":\"TLSv1.3\",\"cipherSuite\":\"TLS_AES_128_GCM_SHA256\",\"clientProvidedHostHeader\":\"elastic-cspm-cloudtrail-test-bucket.s3.us-east-1.amazonaws.com\"}}",
65+
"outcome": "success",
66+
"provider": "s3.amazonaws.com",
67+
"type": [
68+
"info"
69+
]
70+
},
71+
"related": {
72+
"entity": [
73+
"arn:aws:s3:::elastic-cspm-cloudtrail-test-bucket",
74+
"test@elastic.co",
75+
"elastic-cspm-cloudtrail-test-bucket",
76+
"ACCESSKEYID",
77+
"arn:aws:iam::000000000:user/test@elastic.co",
78+
"arn:aws:s3:::elastic-cspm-cloudtrail-test-bucket/test-copy-object/README-copy.md",
79+
"arn:aws:s3:::elastic-cspm-cloudtrail-test-bucket/test-copy-object/README.md"
80+
],
81+
"user": [
82+
"ACCESSKEYID",
83+
"test@elastic.co"
84+
]
85+
},
86+
"source": {
87+
"address": "216.160.83.56",
88+
"as": {
89+
"number": 209
90+
},
91+
"geo": {
92+
"city_name": "Milton",
93+
"continent_name": "North America",
94+
"country_iso_code": "US",
95+
"country_name": "United States",
96+
"location": {
97+
"lat": 47.2513,
98+
"lon": -122.3149
99+
},
100+
"region_iso_code": "US-WA",
101+
"region_name": "Washington"
102+
},
103+
"ip": "216.160.83.56"
104+
},
105+
"tags": [
106+
"preserve_original_event",
107+
"actor_target_mapping"
108+
],
109+
"target": {
110+
"entity": {
111+
"id": [
112+
"arn:aws:s3:::elastic-cspm-cloudtrail-test-bucket",
113+
"arn:aws:s3:::elastic-cspm-cloudtrail-test-bucket/test-copy-object/README-copy.md",
114+
"arn:aws:s3:::elastic-cspm-cloudtrail-test-bucket/test-copy-object/README.md"
115+
]
116+
}
117+
},
118+
"tls": {
119+
"cipher": "TLS_AES_128_GCM_SHA256",
120+
"client": {
121+
"server_name": "elastic-cspm-cloudtrail-test-bucket.s3.us-east-1.amazonaws.com"
122+
},
123+
"version": "1.3",
124+
"version_protocol": "tls"
125+
},
126+
"user": {
127+
"email": "test@elastic.co",
128+
"id": "ACCESSKEYID",
129+
"name": "test@elastic.co"
130+
},
131+
"user_agent": {
132+
"device": {
133+
"name": "Other"
134+
},
135+
"name": "aws-cli",
136+
"original": "[aws-cli/2.17.60 md/awscrt#0.21.2 ua/2.0 os/macos#23.6.0 md/arch#x86_64 lang/python#3.12.6 md/pyimpl#CPython cfg/retry-mode#standard md/installer#exe md/prompt#off md/command#s3api.copy-object]",
137+
"version": "2.17.60"
138+
}
139+
},
140+
{
141+
"@timestamp": "2021-11-11T01:02:03.123456789Z",
142+
"ecs": {
143+
"version": "8.11.0"
144+
},
145+
"event": {
146+
"created": "2021-11-11T01:02:03.123456789Z",
147+
"kind": "event",
148+
"outcome": "success",
149+
"type": [
150+
"info"
151+
]
152+
},
153+
"tags": [
154+
"preserve_original_event",
155+
"actor_target_mapping"
156+
]
157+
}
158+
]
159+
}

packages/aws/data_stream/cloudtrail/elasticsearch/ingest_pipeline/default.yml

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1719,18 +1719,55 @@ processors:
17191719
# pipeline makes that non-trivial as both the flattened fields and the
17201720
# non-flattened origin fields are referred to throughout the pipeline,
17211721
# making it difficult to disentangle them. This the TODO to be done.
1722+
- script:
1723+
if: ctx._conf?.retain == 'minimal' && ctx.aws?.cloudtrail?.flattened != null
1724+
tag: script_retain_minimal_flattened
1725+
params:
1726+
# This list of fields is determined by enumerating all fields containing
1727+
# the string "cloudtrail.flattened" that are in .attributes.required_fields of the
1728+
# rules in security_detection_engine/kibana/security_rule.
1729+
# It must be kept up to date with the rules.
1730+
required_flattened_fields:
1731+
- aws.cloudtrail.flattened.additional_eventdata.SSEApplied
1732+
- aws.cloudtrail.flattened.request_parameters.cidrIp
1733+
- aws.cloudtrail.flattened.request_parameters.dryRun
1734+
- aws.cloudtrail.flattened.request_parameters.fromPort
1735+
- aws.cloudtrail.flattened.request_parameters.includeDeprecated
1736+
- aws.cloudtrail.flattened.request_parameters.policyArn
1737+
- aws.cloudtrail.flattened.request_parameters.serialNumber
1738+
- aws.cloudtrail.flattened.request_parameters.withDecryption
1739+
- aws.cloudtrail.flattened.request_parameters.x-amz-server-side-encryption-customer-algorithm
1740+
source: |-
1741+
def set(Map root, String path, def v) {
1742+
String[] elems = path.splitOnToken('.');
1743+
def dst = root;
1744+
for (int i = 0; i < elems.length-1; i++) {
1745+
dst = dst.computeIfAbsent(elems[i], _ -> new HashMap());
1746+
}
1747+
dst[elems[elems.length-1]] = v;
1748+
}
1749+
Map flattened = [:];
1750+
int prefix = "aws.cloudtrail.flattened.".length();
1751+
for (String f: params.required_flattened_fields) {
1752+
def v = field(f).get(null);
1753+
if (v == null) {
1754+
continue;
1755+
}
1756+
set(flattened, f.substring(prefix), v);
1757+
}
1758+
ctx.aws.cloudtrail.flattened = flattened;
17221759
- remove:
17231760
field:
17241761
- aws.cloudtrail.flattened
17251762
ignore_missing: true
1726-
if: ctx._conf?.retain != null && ctx._conf.retain != '' && ctx._conf.retain != 'all' && ctx._conf.retain != 'flattened'
1763+
if: ctx._conf?.retain != null && ctx._conf.retain != '' && ctx._conf.retain != 'all' && ctx._conf.retain != 'flattened' && ctx._conf.retain != 'minimal'
17271764
- remove:
17281765
field:
17291766
- aws.cloudtrail.response_elements
17301767
- aws.cloudtrail.request_parameters
17311768
- aws.cloudtrail.additional_eventdata
17321769
ignore_missing: true
1733-
if: ctx._conf?.retain != null && ctx._conf.retain != '' && ctx._conf.retain != 'all' && ctx._conf.retain != 'keyword'
1770+
if: ctx._conf?.retain != null && ctx._conf.retain != '' && ctx._conf.retain != 'all' && ctx._conf.retain != 'keyword' && ctx._conf.retain != 'minimal'
17341771
- remove:
17351772
field:
17361773
- json

packages/aws/data_stream/cloudtrail/manifest.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,14 +198,17 @@ streams:
198198
description: >-
199199
Cloudtrail `response_elements`, `request_parameters` and `additional_eventdata` data can
200200
be placed in keyword and text fields as JSON, and in flattened fields. Depending on requirements
201-
This configuration determines which fields will be retained in the final document.
201+
This configuration determines which fields will be retained in the final document. The Minimal
202+
option retains the minmal set of fields required for the Security Detection Engine rules.
202203
options:
203204
- text: Keyword and Flattened
204205
value: all
205206
- text: Keyword
206207
value: keyword
207208
- text: Flattened
208209
value: flattened
210+
- text: Minimal
211+
value: minimal
209212
- text: Neither
210213
value: none
211214
default: all

0 commit comments

Comments
 (0)