Skip to content

Commit b6886f3

Browse files
authored
[FR] Add enforcement for deprecated_reason (#5953)
1 parent 2dac152 commit b6886f3

6 files changed

Lines changed: 61 additions & 6 deletions

File tree

.github/PULL_REQUEST_GUIDELINES/rule_deprecation_guidelines.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ These guidelines serve as a reminder set of considerations when recommending the
99

1010
### Rule Metadata Checks
1111

12-
- [ ] `deprecated = true` added to the rule metadata.
13-
- [ ] `updated_date` should be the date of the PR.
12+
- [ ] `maturity = "deprecated"` added to the rule metadata.
13+
- [ ] `deprecation_date` set to the date of the PR and `updated_date` matches.
14+
- [ ] `deprecated_reason` added to `[metadata]` with a short explanation (e.g. `"Replaced by <rule name>"`). Required in the same PR that flips `maturity = "deprecated"`; surfaced in Kibana on stacks >= 9.4.
1415

1516
### Testing and Validation
1617

detection_rules/etc/deprecated_rules.json

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"015cca13-8832-49ac-a01b-a396114809f6": {
33
"deprecation_date": "2026/01/16",
4+
"deprecated_reason": "CreateCluster is routine Redshift lifecycle noise; real abuse paths (snapshot sharing, role abuse, security group exposure) are covered by other rules. See PR elastic/detection-rules#5367.",
45
"rule_name": "Deprecated - AWS Redshift Cluster Creation",
56
"stack_version": "8.19"
67
},
@@ -21,6 +22,7 @@
2122
},
2223
"09443c92-46b3-45a4-8f25-383b028b258d": {
2324
"deprecation_date": "2026/02/04",
25+
"deprecated_reason": "Expensive Defend correlation from a generic process event; flagged for deprecation as a noisy edge case during top-noisy rule tuning. See PR elastic/detection-rules#5449.",
2426
"rule_name": "Deprecated - Process Termination followed by Deletion",
2527
"stack_version": "8.19"
2628
},
@@ -71,6 +73,7 @@
7173
},
7274
"1ba5160d-f5a2-4624-b0ff-6a1dc55d2516": {
7375
"deprecation_date": "2026/01/16",
76+
"deprecated_reason": "ElastiCache CacheSecurityGroup APIs apply only to retired EC2-Classic; modern VPC deployments are covered by AWS EC2 Security Group Configuration Change. See PR elastic/detection-rules#5334.",
7477
"rule_name": "Deprecated - AWS ElastiCache Security Group Modified or Deleted",
7578
"stack_version": "8.19"
7679
},
@@ -81,6 +84,7 @@
8184
},
8285
"1defdd62-cd8d-426e-a246-81a37751bb2b": {
8386
"deprecation_date": "2026/02/04",
87+
"deprecated_reason": "Marked deprecated during the Windows High Severity tuning batch for persistent false positives. See PR elastic/detection-rules#5094.",
8488
"rule_name": "Deprecated - Execution of File Written or Modified by PDF Reader",
8589
"stack_version": "8.19"
8690
},
@@ -121,11 +125,13 @@
121125
},
122126
"30e1e9f2-eb9c-439f-aff6-1e3068e99384": {
123127
"deprecation_date": "2026/02/04",
128+
"deprecated_reason": "Marked deprecated during the Linux privilege-escalation DR tuning batch. See PR elastic/detection-rules#5511.",
124129
"rule_name": "Deprecated - Network Connection via Sudo Binary",
125130
"stack_version": "8.19"
126131
},
127132
"3115bd2c-0baa-4df0-80ea-45e474b5ef93": {
128133
"deprecation_date": "2026/02/04",
134+
"deprecated_reason": "Query keyed on an undocumented, likely-invalid field value; the false positives could not be solved at the rule level. See PR elastic/detection-rules#5552.",
129135
"rule_name": "Deprecated - Agent Spoofing - Mismatched Agent ID",
130136
"stack_version": "8.19"
131137
},
@@ -136,6 +142,7 @@
136142
},
137143
"378f9024-8a0c-46a5-aa08-ce147ac73a4e": {
138144
"deprecation_date": "2026/01/16",
145+
"deprecated_reason": "CreateDBSecurityGroup targets retired EC2-Classic; VPC security group changes are covered by AWS EC2 Security Group Configuration Change. See PR elastic/detection-rules#5350.",
139146
"rule_name": "Deprecated - AWS RDS Security Group Creation",
140147
"stack_version": "8.19"
141148
},
@@ -176,6 +183,7 @@
176183
},
177184
"521fbe5c-a78d-4b6b-a323-f978b0e4c4c0": {
178185
"deprecation_date": "2026/02/04",
186+
"deprecated_reason": "Superseded by new ESQL Linux brute-force rules during the credential-access DR tuning rework. See PR elastic/detection-rules#5483.",
179187
"rule_name": "Deprecated - Potential Successful Linux RDP Brute Force Attack Detected",
180188
"stack_version": "8.19"
181189
},
@@ -186,6 +194,7 @@
186194
},
187195
"5c50ffa6-07f4-4cce-a1b7-c16928a2ed52": {
188196
"deprecation_date": "2026/02/04",
197+
"deprecated_reason": "Marked deprecated during the Linux lateral-movement DR tuning batch, with updated triage guidance attached. See PR elastic/detection-rules#5505.",
189198
"rule_name": "Deprecated - SSH Process Launched From Inside A Container via Elastic Defend",
190199
"stack_version": "8.19"
191200
},
@@ -201,6 +210,7 @@
201210
},
202211
"62b68eb2-1e47-4da7-85b6-8f478db5b272": {
203212
"deprecation_date": "2026/02/04",
213+
"deprecated_reason": "Linux BBR tuning: marked deprecated as a noisy rule with zero useful hits. See PR elastic/detection-rules#5514.",
204214
"rule_name": "Deprecated - Potential Non-Standard Port HTTP/HTTPS connection",
205215
"stack_version": "8.19"
206216
},
@@ -211,6 +221,7 @@
211221
},
212222
"66712812-e7f2-4a1d-bbda-dd0b5cf20c5d": {
213223
"deprecation_date": "2026/02/04",
224+
"deprecated_reason": "Superseded by new ESQL Linux brute-force rules during the credential-access DR tuning rework. See PR elastic/detection-rules#5483.",
214225
"rule_name": "Deprecated - Potential Successful Linux FTP Brute Force Attack Detected",
215226
"stack_version": "8.19"
216227
},
@@ -261,6 +272,7 @@
261272
},
262273
"7b3da11a-60a2-412e-8aa7-011e1eb9ed47": {
263274
"deprecation_date": "2026/01/16",
275+
"deprecated_reason": "ElastiCache CacheSecurityGroup APIs apply only to retired EC2-Classic; modern VPC deployments are covered by AWS EC2 Security Group Configuration Change. See PR elastic/detection-rules#5334.",
264276
"rule_name": "Deprecated - AWS ElastiCache Security Group Created",
265277
"stack_version": "8.19"
266278
},
@@ -281,6 +293,7 @@
281293
},
282294
"863cdf31-7fd3-41cf-a185-681237ea277b": {
283295
"deprecation_date": "2026/01/16",
296+
"deprecated_reason": "DeleteDBSecurityGroup targets retired EC2-Classic; modern VPC RDS deployments are covered by AWS EC2 Security Group Configuration Change. See PR elastic/detection-rules#5350.",
284297
"rule_name": "Deprecated - AWS RDS Security Group Deletion",
285298
"stack_version": "8.19"
286299
},
@@ -316,11 +329,13 @@
316329
},
317330
"93f47b6f-5728-4004-ba00-625083b3dcb0": {
318331
"deprecation_date": "2026/02/04",
332+
"deprecated_reason": "Superseded by Pluggable Authentication Module or Configuration Creation, a Linux-only higher-fidelity, lower-compute rule. See PR elastic/detection-rules#5421.",
319333
"rule_name": "Deprecated - Modification of Standard Authentication Module or Configuration",
320334
"stack_version": "8.19"
321335
},
322336
"947827c6-9ed6-4dec-903e-c856c86e72f3": {
323337
"deprecation_date": "2026/02/04",
338+
"deprecated_reason": "Linux BBR tuning: marked deprecated as a noisy rule with zero useful hits. See PR elastic/detection-rules#5514.",
324339
"rule_name": "Deprecated - Creation of Kernel Module",
325340
"stack_version": "8.19"
326341
},
@@ -351,6 +366,7 @@
351366
},
352367
"9d19ece6-c20e-481a-90c5-ccca596537de": {
353368
"deprecation_date": "2026/02/04",
369+
"deprecated_reason": "Superseded by Launch Service Creation and Immediate Loading, which covers LaunchDaemons and LaunchAgents via the newer Persistence event. See PR elastic/detection-rules#4547.",
354370
"rule_name": "Deprecated - LaunchDaemon Creation or Modification and Immediate Loading",
355371
"stack_version": "8.19"
356372
},
@@ -361,6 +377,7 @@
361377
},
362378
"a577e524-c2ee-47bd-9c5b-e917d01d3276": {
363379
"deprecation_date": "2026/02/04",
380+
"deprecated_reason": "Linux BBR tuning: marked deprecated as a noisy rule with zero useful hits. See PR elastic/detection-rules#5514.",
364381
"rule_name": "Deprecated - CAP_SYS_ADMIN Assigned to Binary",
365382
"stack_version": "8.19"
366383
},
@@ -376,6 +393,7 @@
376393
},
377394
"ac8805f6-1e08-406c-962e-3937057fa86f": {
378395
"deprecation_date": "2026/02/04",
396+
"deprecated_reason": "Marked deprecated during the Linux DR Tuning - 2 batch without a rule-specific justification recorded in the PR. See PR elastic/detection-rules#5481.",
379397
"rule_name": "Deprecated - Potential Protocol Tunneling via Chisel Server",
380398
"stack_version": "8.19"
381399
},
@@ -391,21 +409,25 @@
391409
},
392410
"bc0c6f0d-dab0-47a3-b135-0925f0a333bc": {
393411
"deprecation_date": "2025/11/21",
412+
"deprecated_reason": "Overlaps with the broader AWS Successful Root Console Login rule; the broader rule covers all root logins and is retained. See PR elastic/detection-rules#5201.",
394413
"rule_name": "Deprecated - AWS Root Login Without MFA",
395414
"stack_version": "8.19"
396415
},
397416
"bc8ca7e0-92fd-4b7c-b11e-ee0266b8d9c9": {
398417
"deprecation_date": "2026/02/04",
418+
"deprecated_reason": "Marked deprecated during the Linux cross-platform DR tuning batch. See PR elastic/detection-rules#5512.",
399419
"rule_name": "Deprecated - Potential Non-Standard Port SSH connection",
400420
"stack_version": "8.19"
401421
},
402422
"bdb04043-f0e3-4efa-bdee-7d9d13fa9edc": {
403423
"deprecation_date": "2026/02/04",
424+
"deprecated_reason": "Marked deprecated during the Linux discovery DR tuning batch. See PR elastic/detection-rules#5497.",
404425
"rule_name": "Deprecated - Potential Pspy Process Monitoring Detected",
405426
"stack_version": "8.19"
406427
},
407428
"c125e48f-6783-41f0-b100-c3bf1b114d16": {
408429
"deprecation_date": "2026/02/04",
430+
"deprecated_reason": "Superseded by Suspicious Renaming of ESXI VMware Files, which now also detects index.html renames in /usr/lib/vmware/. See PR elastic/detection-rules#5494.",
409431
"rule_name": "Deprecated - Suspicious Renaming of ESXI index.html File",
410432
"stack_version": "8.19"
411433
},
@@ -451,6 +473,7 @@
451473
},
452474
"d55436a8-719c-445f-92c4-c113ff2f9ba5": {
453475
"deprecation_date": "2026/02/04",
476+
"deprecated_reason": "Marked deprecated during the Linux privilege-escalation DR tuning batch. See PR elastic/detection-rules#5511.",
454477
"rule_name": "Deprecated - Potential Privilege Escalation via UID INT_MAX Bug Detected",
455478
"stack_version": "8.19"
456479
},
@@ -486,6 +509,7 @@
486509
},
487510
"e14c5fd7-fdd7-49c2-9e5b-ec49d817bc8d": {
488511
"deprecation_date": "2026/01/16",
512+
"deprecated_reason": "CreateDBCluster is routine RDS lifecycle with no meaningful attack signal; high-value RDS threats (snapshot, export, exposure) are covered elsewhere. See PR elastic/detection-rules#5350.",
489513
"rule_name": "Deprecated - AWS RDS Cluster Creation",
490514
"stack_version": "8.19"
491515
},
@@ -496,6 +520,7 @@
496520
},
497521
"e919611d-6b6f-493b-8314-7ed6ac2e413b": {
498522
"deprecation_date": "2026/01/16",
523+
"deprecated_reason": "Replaced by AWS EC2 Export Task, which detects successful exports (higher signal than failed attempts). See PR elastic/detection-rules#5248.",
499524
"rule_name": "Deprecated - AWS EC2 VM Export Failure",
500525
"stack_version": "8.19"
501526
},
@@ -516,6 +541,7 @@
516541
},
517542
"ecf2b32c-e221-4bd4-aa3b-c7d59b3bc01d": {
518543
"deprecation_date": "2026/01/16",
544+
"deprecated_reason": "StopDBInstance and StopDBCluster are routine admin operations with no meaningful attack signal. See PR elastic/detection-rules#5350.",
519545
"rule_name": "Deprecated - AWS RDS Instance/Cluster Stoppage",
520546
"stack_version": "8.19"
521547
},
@@ -526,11 +552,13 @@
526552
},
527553
"f30f3443-4fbb-4c27-ab89-c3ad49d62315": {
528554
"deprecation_date": "2026/01/16",
555+
"deprecated_reason": "CreateDBInstance is routine RDS lifecycle with no meaningful attack signal; high-value RDS threats are covered elsewhere. See PR elastic/detection-rules#5350.",
529556
"rule_name": "Deprecated - AWS RDS Instance Creation",
530557
"stack_version": "8.19"
531558
},
532559
"f41296b4-9975-44d6-9486-514c6f635b2d": {
533560
"deprecation_date": "2026/02/04",
561+
"deprecated_reason": "Marked deprecated during the Linux execution DR tuning batch without a rule-specific justification recorded in the PR. See PR elastic/detection-rules#5504.",
534562
"rule_name": "Deprecated - Potential curl CVE-2023-38545 Exploitation",
535563
"stack_version": "8.19"
536564
},
@@ -554,4 +582,4 @@
554582
"rule_name": "Linux Restricted Shell Breakout via the expect command",
555583
"stack_version": "7.16"
556584
}
557-
}
585+
}

detection_rules/packaging.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ def _generate_registry_package(self, save_dir: Path) -> None:
554554
deprecated_reason=dep_entry.deprecated_reason,
555555
stack_version=stack_version,
556556
)
557-
asset_path = rules_dir / f"deprecated_{asset['id']}.json"
557+
asset_path = rules_dir / f"{asset['id']}.json"
558558
asset_path.write_text(json.dumps(asset, indent=4, sort_keys=True), encoding="utf-8")
559559

560560
notice_contents = NOTICE_FILE.read_text()

docs-dev/deprecating.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@ release package to Kibana.
1313
1. Update the `maturity` to `deprecated`
1414
2. Move the rule file to [rules/_deprecated](../rules/_deprecated)
1515
3. Add `deprecation_date` and update `updated_date` to match
16+
4. Add `deprecated_reason` in `[metadata]` with a short explanation (e.g. "Replaced by <rule name>"). Required in the
17+
same PR that flips `maturity = "deprecated"`; surfaced in Kibana on stacks >= 9.4 and ignored on older stacks.
1618

1719
Next time the versions are locked, the rule will be added to the [deprecated_rules.json](../detection_rules/etc/deprecated_rules.json)
18-
file.
20+
file, and `deprecated_reason` is copied into the package asset (gated at build time by `MIN_STACK_VERSION_DEPRECATED_STUBS`).
1921

2022

2123
### Using the deprecate-rule command

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.6.24"
3+
version = "1.6.25"
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_all_rules.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,30 @@ def test_deprecated_rules(self):
761761
rule_str = f"{rule_id} - {entry['rule_name']} ->"
762762
self.assertIn(rule_id, deprecated_rules, f'{rule_str} is logged in "deprecated_rules.json" but is missing')
763763

764+
@unittest.skipIf(RULES_CONFIG.bypass_version_lock, "Skipping deprecated version lock check")
765+
def test_newly_deprecated_rules_have_reason(self):
766+
"""Newly deprecated rules must include `deprecated_reason` in [metadata].
767+
768+
Rules already in `deprecated_rules.json` are grandfathered.
769+
"""
770+
already_deprecated = set(self.rules_config.deprecated_rules)
771+
missing: list[str] = []
772+
773+
for rule in self.deprecated_rules:
774+
if rule.id in already_deprecated:
775+
continue
776+
if not rule.contents.metadata.get("deprecated_reason"):
777+
missing.append(self.rule_str(rule))
778+
779+
if missing:
780+
rules_str = "\n ".join(missing)
781+
self.fail(
782+
"The following newly deprecated rules are missing `deprecated_reason` in "
783+
"[metadata]. Add a short explanation (e.g. 'Replaced by <rule name>'). This "
784+
"field is only required for NEW deprecations on this branch; rules already "
785+
f"tracked in `deprecated_rules.json` are grandfathered.\n {rules_str}"
786+
)
787+
764788
def test_deprecated_rules_modified(self):
765789
"""Test to ensure deprecated rules are not modified."""
766790

0 commit comments

Comments
 (0)