Skip to content

Commit 2e9373d

Browse files
authored
Merge branch 'main' into kerb-unusual-client
2 parents 4c711f9 + f52aedf commit 2e9373d

File tree

7 files changed

+135
-4
lines changed

7 files changed

+135
-4
lines changed

.github/workflows/kibana-mitre-update.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818

1919
- name: Get MITRE Attack changed files
2020
id: changed-attack-files
21-
uses: tj-actions/changed-files@2f7c5bfce28377bc069a65ba478de0a74aa0ca32 # v46.0.1
21+
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5
2222
with:
2323
files: detection_rules/etc/attack-v*.json.gz
2424

.github/workflows/lock-versions.yml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,57 @@ jobs:
3737
pip cache purge
3838
pip install .[dev]
3939
40+
- name: Check out container repository
41+
env:
42+
DR_CLOUD_ID: ${{ secrets.dr_cloud_id }}
43+
DR_API_KEY: ${{ secrets.dr_api_key }}
44+
if: ${{ !env.DR_CLOUD_ID && !env.DR_API_KEY }}
45+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
46+
with:
47+
path: elastic-container
48+
repository: peasead/elastic-container
49+
50+
- name: Build and run containers
51+
env:
52+
DR_CLOUD_ID: ${{ secrets.dr_cloud_id }}
53+
DR_API_KEY: ${{ secrets.dr_api_key }}
54+
if: ${{ !env.DR_CLOUD_ID && !env.DR_API_KEY }}
55+
run: |
56+
cd elastic-container
57+
GENERATED_PASSWORD=$(openssl rand -base64 16)
58+
sed -i "s|changeme|$GENERATED_PASSWORD|" .env
59+
echo "::add-mask::$GENERATED_PASSWORD"
60+
echo "GENERATED_PASSWORD=$GENERATED_PASSWORD" >> $GITHUB_ENV
61+
set -x
62+
bash elastic-container.sh start
63+
64+
- name: Get API Key and setup auth
65+
env:
66+
DR_CLOUD_ID: ${{ secrets.dr_cloud_id }}
67+
DR_API_KEY: ${{ secrets.dr_api_key }}
68+
DR_ELASTICSEARCH_URL: "https://localhost:9200"
69+
ES_USER: "elastic"
70+
ES_PASSWORD: ${{ env.GENERATED_PASSWORD }}
71+
if: ${{ !env.DR_CLOUD_ID && !env.DR_API_KEY }}
72+
run: |
73+
cd detection-rules
74+
response=$(curl -k -X POST -u "$ES_USER:$ES_PASSWORD" -H "Content-Type: application/json" -d '{
75+
"name": "tmp-api-key",
76+
"expiration": "1d"
77+
}' "$DR_ELASTICSEARCH_URL/_security/api_key")
78+
79+
DR_API_KEY=$(echo "$response" | jq -r '.encoded')
80+
echo "::add-mask::$DR_API_KEY"
81+
echo "DR_API_KEY=$DR_API_KEY" >> $GITHUB_ENV
82+
4083
- name: Build release package with navigator files
84+
env:
85+
DR_REMOTE_ESQL_VALIDATION: "true"
86+
DR_CLOUD_ID: ${{ secrets.dr_cloud_id || '' }}
87+
DR_KIBANA_URL: ${{ secrets.dr_cloud_id == '' && 'https://localhost:5601' || '' }}
88+
DR_ELASTICSEARCH_URL: ${{ secrets.dr_cloud_id == '' && 'https://localhost:9200' || '' }}
89+
DR_API_KEY: ${{ secrets.dr_api_key || env.DR_API_KEY }}
90+
DR_IGNORE_SSL_ERRORS: ${{ secrets.dr_cloud_id == '' && 'true' || '' }}
4191
run: |
4292
python -m detection_rules dev build-release --generate-navigator
4393
@@ -56,6 +106,12 @@ jobs:
56106
- name: Lock the versions
57107
env:
58108
BRANCHES: "${{github.event.inputs.branches}}"
109+
DR_REMOTE_ESQL_VALIDATION: "true"
110+
DR_CLOUD_ID: ${{ secrets.dr_cloud_id || '' }}
111+
DR_KIBANA_URL: ${{ secrets.dr_cloud_id == '' && 'https://localhost:5601' || '' }}
112+
DR_ELASTICSEARCH_URL: ${{ secrets.dr_cloud_id == '' && 'https://localhost:9200' || '' }}
113+
DR_API_KEY: ${{ secrets.dr_api_key || env.DR_API_KEY }}
114+
DR_IGNORE_SSL_ERRORS: ${{ secrets.dr_cloud_id == '' && 'true' || '' }}
59115
run: |
60116
./detection_rules/etc/lock-multiple.sh $BRANCHES
61117
git add detection_rules/etc/version.lock.json

.github/workflows/release-fleet.yml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,57 @@ jobs:
112112
git tag $RELEASE_TAG
113113
git push origin $RELEASE_TAG
114114
115+
- name: Check out container repository
116+
env:
117+
DR_CLOUD_ID: ${{ secrets.dr_cloud_id }}
118+
DR_API_KEY: ${{ secrets.dr_api_key }}
119+
if: ${{ !env.DR_CLOUD_ID && !env.DR_API_KEY }}
120+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
121+
with:
122+
path: elastic-container
123+
repository: peasead/elastic-container
124+
125+
- name: Build and run containers
126+
env:
127+
DR_CLOUD_ID: ${{ secrets.dr_cloud_id }}
128+
DR_API_KEY: ${{ secrets.dr_api_key }}
129+
if: ${{ !env.DR_CLOUD_ID && !env.DR_API_KEY }}
130+
run: |
131+
cd elastic-container
132+
GENERATED_PASSWORD=$(openssl rand -base64 16)
133+
sed -i "s|changeme|$GENERATED_PASSWORD|" .env
134+
echo "::add-mask::$GENERATED_PASSWORD"
135+
echo "GENERATED_PASSWORD=$GENERATED_PASSWORD" >> $GITHUB_ENV
136+
set -x
137+
bash elastic-container.sh start
138+
139+
- name: Get API Key and setup auth
140+
env:
141+
DR_CLOUD_ID: ${{ secrets.dr_cloud_id }}
142+
DR_API_KEY: ${{ secrets.dr_api_key }}
143+
DR_ELASTICSEARCH_URL: "https://localhost:9200"
144+
ES_USER: "elastic"
145+
ES_PASSWORD: ${{ env.GENERATED_PASSWORD }}
146+
if: ${{ !env.DR_CLOUD_ID && !env.DR_API_KEY }}
147+
run: |
148+
cd detection-rules
149+
response=$(curl -k -X POST -u "$ES_USER:$ES_PASSWORD" -H "Content-Type: application/json" -d '{
150+
"name": "tmp-api-key",
151+
"expiration": "1d"
152+
}' "$DR_ELASTICSEARCH_URL/_security/api_key")
153+
154+
DR_API_KEY=$(echo "$response" | jq -r '.encoded')
155+
echo "::add-mask::$DR_API_KEY"
156+
echo "DR_API_KEY=$DR_API_KEY" >> $GITHUB_ENV
157+
115158
- name: Build release package
159+
env:
160+
DR_REMOTE_ESQL_VALIDATION: "true"
161+
DR_CLOUD_ID: ${{ secrets.dr_cloud_id || '' }}
162+
DR_KIBANA_URL: ${{ secrets.dr_cloud_id == '' && 'https://localhost:5601' || '' }}
163+
DR_ELASTICSEARCH_URL: ${{ secrets.dr_cloud_id == '' && 'https://localhost:9200' || '' }}
164+
DR_API_KEY: ${{ secrets.dr_api_key || env.DR_API_KEY }}
165+
DR_IGNORE_SSL_ERRORS: ${{ secrets.dr_cloud_id == '' && 'true' || '' }}
116166
run: |
117167
cd detection-rules
118168
python -m detection_rules dev build-release

detection_rules/index_mappings.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,6 @@ def get_filtered_index_schema(
261261
filtered_keys.update(non_ecs_indices.keys())
262262
filtered_keys.update(custom_indices.keys())
263263
filtered_keys.add("logs-endpoint.alerts-*")
264-
filtered_keys.update(indices)
265264

266265
matches: list[str] = []
267266
for index in indices:

detection_rules/rule.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1528,7 +1528,11 @@ def get_packaged_integrations(
15281528
*definitions.NON_DATASET_PACKAGES,
15291529
*map(str.lower, definitions.MACHINE_LEARNING_PACKAGES),
15301530
]
1531-
if integration in ineligible_integrations or isinstance(data, MachineLearningRuleData):
1531+
if (
1532+
integration in ineligible_integrations
1533+
or isinstance(data, MachineLearningRuleData)
1534+
or (isinstance(data, ESQLRuleData) and integration not in datasets)
1535+
):
15321536
packaged_integrations.append({"package": integration, "integration": None})
15331537

15341538
packaged_integrations.extend(parse_datasets(list(datasets), package_manifest))

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "detection_rules"
3-
version = "1.5.4"
3+
version = "1.5.5"
44
description = "Detection Rules is the home for rules used by Elastic Security. This repository is used for the development, maintenance, testing, validation, and release of rules for Elastic Security’s Detection Engine."
55
readme = "README.md"
66
requires-python = ">=3.12"

tests/test_rules_remote.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,28 @@ def test_esql_related_integrations(self):
4646
for integration in related_integrations:
4747
assert integration["package"] == "aws", f"Expected 'aws', but got {integration['package']}"
4848

49+
def test_esql_non_dataset_package_related_integrations(self):
50+
"""Test an ESQL rule has its related integrations built correctly with a non dataset package."""
51+
file_path = get_path(["tests", "data", "command_control_dummy_production_rule.toml"])
52+
original_production_rule = load_rule_contents(file_path)
53+
production_rule = deepcopy(original_production_rule)[0]
54+
production_rule["metadata"]["integration"] = ["aws_bedrock"]
55+
production_rule["rule"]["query"] = """
56+
from logs-aws_bedrock.invocation-* metadata _id, _version, _index
57+
// Filter for access denied errors from GenAI responses
58+
| where gen_ai.response.error_code == "AccessDeniedException"
59+
// keep ECS and response fields
60+
| keep
61+
user.id,
62+
gen_ai.request.model.id,
63+
cloud.account.id,
64+
gen_ai.response.error_code
65+
"""
66+
rule = RuleCollection().load_dict(production_rule)
67+
related_integrations = rule.contents.to_api_format()["related_integrations"]
68+
for integration in related_integrations:
69+
assert integration["package"] == "aws_bedrock", f"Expected 'aws_bedrock', but got {integration['package']}"
70+
4971
def test_esql_event_dataset_schema_error(self):
5072
"""Test an ESQL rule that uses event.dataset field in the query that restricts the schema failing validation."""
5173
file_path = get_path(["tests", "data", "command_control_dummy_production_rule.toml"])

0 commit comments

Comments
 (0)