Skip to main content
This guide provides a comprehensive reference for developers creating correlation rules to detect security threats in UTMStack v11. Rules are YAML files used by the analysis plugin to generate alerts when specific conditions are met.
Developer Reference: This page is designed as a practical guide for implementing security detection logic through correlation rules.

What are Correlation Rules?

Correlation rules define how to analyze events to detect security threats. When an event matches a rule’s conditions, an alert is generated.

Key Capabilities

  • Real-time threat detection based on event patterns
  • Multi-event correlation across time windows
  • Complex conditional logic using CEL expressions
  • Alert deduplication to prevent fatigue
  • Threat intelligence integration

Rule Structure

A complete rule consists of several components:

Rule Fields Reference

Basic Metadata

Type: Integer
Required: Yes
Unique identifier for the rule across the entire system.
IDs must be unique. Duplicate IDs will cause conflicts.
Type: Array of strings
Required: Yes
Specifies which event types this rule applies to. Rule only evaluates events with matching data types.
Common data types:
  • windows, linux, macos - OS logs
  • apache, nginx, iis - Web server logs
  • cisco, fortigate, paloalto - Network device logs
  • aws, azure, gcp - Cloud provider logs
Type: String
Required: Yes
Human-readable name for the rule. Displayed in alerts and UI.
Type: String
Required: Yes
Detailed description explaining what the rule detects and why it’s important.

Threat Classification

Type: Object
Required: Yes
Defines the potential impact of the detected threat on CIA triad (0-5 scale).
Scoring Guide:
  • 0: No impact
  • 1-2: Low impact
  • 3: Medium impact
  • 4: High impact
  • 5: Critical impact
Type: String
Required: Yes
Classification category for the threat.
Common categories:
  • Authentication, Authorization
  • Network Attack, Web Attack
  • Malware, Ransomware
  • Data Exfiltration
  • Insider Threat
  • Policy Violation
Type: String
Required: Yes
Specific technique used by the threat (often mapped to MITRE ATT&CK).
Type: String
Required: Yes
Values: origin or target
Identifies which side is considered the adversary.
Type: Array of strings
Required: No
External references for more information (MITRE ATT&CK, CVEs, articles).

Conditional Logic: The where Field

The where field defines the main condition using Common Expression Language (CEL).

Basic Syntax

Supported Operators

Complex Expression Examples


Event Correlation: The afterEvents Field

The afterEvents field enables multi-event correlation by searching for additional events within specified time windows.

Basic Structure

Search Operators

filter_term

Exact match using term search (keyword fields)Best for: IPs, usernames, exact strings

filter_match

Full-text match using text searchBest for: Messages, descriptions, analyzed text

must_not_term

Not equal using term searchBest for: Excluding specific values

must_not_match

Not matching using text searchBest for: Excluding text patterns

Dynamic Values

Use {{field.path}} syntax to reference values from the triggering event:

Time Windows

Time windows use Elasticsearch date math syntax:

Multiple Searches

Correlate across different indices:

Nested OR Logic

Use or field for alternative correlation paths:
Count Limit: Maximum count value is 50 to prevent performance issues.

Alert Deduplication

Use deduplicateBy to prevent duplicate alerts for the same threat:

How It Works

  1. Alert is generated based on rule conditions
  2. System creates a hash from specified fields
  3. If hash matches recent alert (within deduplication window), new alert is suppressed
  4. Otherwise, alert is created

Best Practices

  • Include fields that uniquely identify the threat
  • Balance between deduplication and alert visibility
  • Common fields: IPs, usernames, hostnames, attack types
  • Avoid time-based fields that change frequently

Rule Evaluation Process

1

Event Received

EventProcessor receives and parses event
2

Data Type Match

System identifies rules matching event’s data type
3

Where Condition

Evaluates where expression using event fields
4

AfterEvents Search

If where=true, performs correlation searches
5

Count Validation

Checks if required event counts are met
6

Alert Generation

Creates alert if all conditions satisfied
7

Deduplication

Checks for recent duplicate alerts
8

Alert Delivery

Delivers alert to correlation engine and UI

Real-World Examples

Example 1: Brute Force Detection

Example 2: Data Exfiltration

Example 3: Lateral Movement

Example 4: Suspicious Time Activity


Development Workflow

1

Identify Threat

Determine what security threat you want to detect
  • Review security requirements
  • Analyze threat intelligence
  • Consider MITRE ATT&CK framework
2

Analyze Event Data

Examine sample events that indicate this threat
3

Create Rule File

Create YAML file with basic structure
4

Define Metadata

Set impact scores, category, technique, references
5

Write Where Condition

Create CEL expression to identify suspicious events
  • Start simple, refine iteratively
  • Test expressions with sample data
  • Handle missing fields with safe() and has()
6

Add Correlation Logic

Define afterEvents if multi-event correlation needed
  • Choose appropriate index patterns
  • Set reasonable time windows
  • Use dynamic values for correlation
7

Configure Deduplication

Specify fields to prevent alert fatigue
8

Test Rule

Deploy to development environment and test
  • Use test events that should trigger
  • Use test events that should NOT trigger
  • Verify alert content and format
9

Refine and Optimize

Adjust based on testing results
  • Tune thresholds
  • Optimize performance
  • Reduce false positives
10

Document and Deploy

Add comprehensive description and deploy to production

Best Practices

Rule Design

Start Simple
  • Begin with basic conditions
  • Add complexity incrementally
  • Test each addition
Be Specific
  • Target specific data types
  • Use precise field matches
  • Avoid overly broad conditions
Handle Missing Data
  • Always use has() or safe() for optional fields
  • Provide sensible defaults
  • Test with incomplete events
Consider Performance
  • Limit data type scope
  • Use efficient operators
  • Minimize afterEvents searches
  • Set reasonable time windows
Prevent False Positives
  • Test with diverse datasets
  • Include normal activity patterns
  • Use whitelisting where appropriate
  • Refine based on feedback

Documentation

  • Write clear, detailed descriptions
  • Include relevant references (MITRE ATT&CK, CVEs)
  • Document expected event formats
  • Explain complex logic
  • Note any limitations or caveats

Testing

  • Test with real production data samples
  • Test edge cases and missing fields
  • Verify deduplication works correctly
  • Monitor performance impact
  • Conduct regular reviews and updates

Troubleshooting

Common Issues

Possible Causes:
  • Event doesn’t match dataTypes
  • where condition evaluates to false
  • afterEvents count not met
  • Field names don’t match event structure
Solutions:
  • Verify event has correct dataType field
  • Test where expression with sample data
  • Check field names match exactly (case-sensitive)
  • Review afterEvents search results
  • Check for typos in field names
Possible Causes:
  • Condition too broad
  • Normal activity matches pattern
  • Missing exclusions
Solutions:
  • Add more specific conditions
  • Include whitelist of known-good patterns
  • Increase thresholds (counts, time windows)
  • Add additional correlation requirements
Possible Causes:
  • Complex expressions
  • Large time windows in afterEvents
  • Too many correlation searches
Solutions:
  • Simplify expressions
  • Reduce time window durations
  • Limit number of afterEvents searches
  • Narrow indexPattern scope
  • Add more specific dataTypes
Possible Causes:
  • Field doesn’t exist in all events
  • Field name typo
  • Data type mismatch
Solutions:
  • Use has() to check field existence
  • Use safe() with defaults
  • Verify field names against events
  • Check field types match expected

Debugging Tips