[FR] Allow filter-only KQL and Indicator Match rules#6334
Open
eric-forte-elastic wants to merge 5 commits into
Open
[FR] Allow filter-only KQL and Indicator Match rules#6334eric-forte-elastic wants to merge 5 commits into
eric-forte-elastic wants to merge 5 commits into
Conversation
Contributor
Enhancement - GuidelinesThese guidelines serve as a reminder set of considerations when addressing adding a feature to the code. Documentation and Context
Code Standards and Practices
Testing
Additional Checks
|
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates the DaC (Detection-as-Code) custom-rule load/export flow to support “filter-only” rules where Kibana allows an intentionally empty query / threat_query as long as filters are present (including indicator match rules).
Changes:
- Relax query validation for custom KQL rules to allow empty query text when filters are provided (while keeping existing validation behavior for other cases).
- Update TOML export formatting to preserve present-but-empty
queryandthreat_queryfields during custom-rule exports to prevent lossy round-trips. - Improve Kibana import error reporting when error payloads are missing expected fields (e.g., missing
rule_id).
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
detection_rules/rule.py |
Allows filter-only custom KQL rules by adjusting query validation/validator behavior. |
detection_rules/rule_formatter.py |
Preserves empty query / threat_query in TOML output when exporting custom rules. |
detection_rules/rule_validators.py |
Handles the now-optional query type in ES |
detection_rules/kbwrap.py |
Makes import error output resilient to missing rule_id/error details. |
tests/test_schemas.py |
Adds schema tests for empty-query-with-filters custom rule loading vs prebuilt behavior. |
tests/test_toml_formatter.py |
Adds formatter tests ensuring empty query / threat_query are preserved for custom exports. |
pyproject.toml |
Bumps package version to 1.7.4. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request
Issue link(s):
Resolves #6283, #6167
Summary - What I changed
Fixes DaC custom rule handling for filter-only KQL rules and filter-only indicator match exports.
Custom KQL query rules can now load when
CUSTOM_RULES_DIRis active and the rule intentionally relies on filters with an emptyquery. The schema keeps empty queries invalid for prebuilt rules and for custom rules that do not include filters, preserving the existing validation behavior outside the filter-only custom-rule case.Custom rule TOML export now preserves present-but-empty
queryandthreat_queryfields instead of dropping them during formatting. This prevents export/import round-trip loss for filter-only custom rules, including indicator match rules that usethreat_filterswithout an indicator index query.The impacted DaC paths are the custom rule load/export flows, including:
view-ruleand other schema-loading paths for custom filter-only KQL ruleskibana export-rules --custom-rules-onlyHow To Test
Run the focused schema and formatter tests:
source env/detection-rules-build/bin/activate python -m pytest \ tests/test_schemas.py::TestSchemas::test_empty_kuery_with_filters_is_valid_for_custom_rules \ tests/test_schemas.py::TestSchemas::test_empty_kuery_with_filters_is_invalid_for_prebuilt_rules \ tests/test_schemas.py::TestSchemas::test_empty_kuery_without_filters_is_invalid_for_custom_rules \ tests/test_toml_formatter.py \ -qExpected result:
Test with filter only rules
20260626T135835L.ndjson.txt
test_filter_only_rule.toml.txt
test_threat_query_filter_only_rule.toml.txt
With CUSTOM_DIR:


Without CUSTOM_DIR:
With CUSTOM_DIR

Without CUSTOM_DIR

Export:

Threat Indicator Rule Testing

Kibana import/export path for both rules:

Checklist
bug,enhancement,schema,maintenance,Rule: New,Rule: Deprecation,Rule: Tuning,Hunt: New, orHunt: Tuningso guidelines can be generatedmeta:rapid-mergelabel if planning to merge within 24 hoursContributor checklist