Get Started: YARA-L 2.0 in SecOps
YARA-L 2.0 is the unique, highly structured query language powering Google Security Operations for all search, dashboards, and rule-based threat detection. This document helps you understand the core YARA-L structure and provides practical steps for using it, whether you're a Security Analyst hunting for threats or a Detection Engineer building robust new logic.
Before you begin
- Verify that you have access to the Google SecOps platform.
- Verify data ingestion using test rules.
- You must have a basic understanding of security concepts and log data.
- This document assumes that data is being ingested into your Google SecOps instance, and normalized to the Unified Data Model (UDM).
Understand the YARA-L structure
Every YARA-L query is segmented into distinct, named sections, which dictate the query's behavior.
This structure is what enables multistage analysis and correlation.
| Command | Action | Optional | Required |
|---|---|---|
meta |
Sets descriptive metadata for the rule, such as author, description, and severity. | Optional for search and dashboards. Required only for rules. |
events |
Defines and filters events. Declares all data sources (primarily events) to consider and filters them using UDM fields. | Required (core logic of the query) for search, dashboards, and rules. |
match |
Groups by events and lets you specify the supported time window (for example, by 5m). |
Required in some cases for statistical searches where aggregation occurs. Required for multi-event correlation queries. Time specification is required in the match for rules and optional for search and dashboards. |
outcome |
Calculates essential metrics and gets insights (for example, count(), avg()). |
Optional. |
condition |
Defines the logic that must be met to either return results (in search) or trigger an alert (in a rule). Evaluates the query variable criteria to determine if a result applies (for example, $event >5). |
Optional in search and dashboards. Required only for rules. |
dedup |
Removes duplicate events by grouping them based on key variables or event paths (for example, target.user.userid, target.ip, principal.hostname or variables, such as $host, $user). Learn more about event variables. |
Optional. Not available in rules. |
order |
Sorts results defined by specific fields (for example, asc). |
Optional (only applicable when match is used). Not available in rules. |
limit |
Restricts the maximum number of returned events from the query. | Optional. Not available in rules. |
select |
Specifies the list of UDM fields to include in the query results. | Optional. Not available in rules. |
unselect |
Specifies the list of UDM fields to exclude from the query results. | Optional. Not available in rules. |
YARA-L data source availability
YARA-L has access to different data sources, depending on where you are in the platform. Events, entities (ECG), and data tables are fully available across search, dashboards, and rules.
The following table lists the available features in YARA-L:
| Feature | Available In |
|---|---|
| Cases and case history | Dashboards |
| Data tables | Search, dashboards, rules |
| Entities (ECG) | Search, dashboards, rules |
| Ingestion metrics | Dashboards |
| IoC matches | Dashboards |
| Rule detections | Dashboards, rules |
| Rule sets | Dashboards |
| Events | Search, dashboards, rules |
| UEBA metrics | Search, dashboards |
Build your first YARA-L search
All data in Google SecOps is searched using two primary methods based on your goals: filter search and statistical search (aggregations).
Filter search (event filtering)
The filter search method lets you isolate specific events from the broader telemetry stream without the overhead of statistical aggregation. This method uses criteria to narrow down massive volumes of security data—such as logs or network traffic—into a targeted result set. The logic only requires you to specify events in the events section.
To build your first YARA-L filter search, follow these steps to search for users with failed logins:
- In Google SecOps, go to the search page.
-
Filter for login events:
metadata.event_type = "USER_LOGIN"
Tip: You can omit the
events:section header in your searches. By default, the search syntax implies this section. - Add
eventactions for failed logins from users who don't have an emptyuserid.metadata.event_type = "USER_LOGIN" security_result.action = "FAIL" principal.user.userid != "" - Run this search to see the results.
Use placeholder variables
Use placeholder variables to extract specific values from your events, such as a username or an IP address. These variables act as temporary anchors that let you compare data across different events or display those values in your final output.
You apply placeholder variables to do the following:
- Bridge data: Use placeholders, such as
$useridor$ipto find matches between different event variables (for example, you can use$useridto link the user identifier across the login and logout events). - Group results: In the
matchsection, use placeholder variables to define the window of your query output, such asmatch: $userid over 1h. - Create outcomes: Use placeholders to capture and display specific data points in your query output.
For example, if you assign $user = principal.user.userid, the $user variable now holds the specific value extracted from the event. You then use $user in the match section to group all activity related to that specific user.
Statistical search (aggregation)
The statistical search method helps you get insights, trends, or anomalies by performing calculations across sets of events. Instead of returning a list of individual logs, it provides aggregated summaries of your data. The logic uses the match section (for grouping) and the outcome section (for calculations). The outcome section supports aggregation functions, such as count(), sum(), avg(), max(), min(), and stddev().
The following example uses the following query logic:
events: Filters the raw data for failed login attempts.match: Defines the grouping events (byuserid).outcome: Performs the statistical aggregation (event count per user).
Example: Aggregate failed login activity using outcome functions
The following example uses the outcome section's aggregation functions (like count() or sum()) to summarize failed login activity.
Use the
matchsection to group the failed login events byuserid:metadata.event_type = "USER_LOGIN" security_result.action = "FAIL" principal.user.userid != "" match: principal.user.useridUse the
countof failed logins for each user ($failed_login_count), defined by theoutcomevariable:metadata.event_type = "USER_LOGIN" security_result.action = "FAIL" principal.user.userid != "" match: principal.$user.userid outcome: $failed_login_count = count(metadata.id)Run this search to see the results.
Optional: Add an element of time to the
matchsection (in this case,day). Then, update theoutcomevariable to be more explicit ($daily_failed_login_count):metadata.event_type = "USER_LOGIN" security_result.action = "FAIL" principal.user.userid != "" $user =principal.user.userid match: principal.$user.userid by day outcome: $daily_failed_login_count = count(metadata.id)
Create a dashboard widget from your search
You can create a dashboard widget from aggregated searches, such as shown in the build your first search example.
Once the search is validated, you can save it as a widget and add it to your dashboard, as follows:
- When you see the results, click the Visualize tab > Add to Dashboard.
- Configure the widget:
- Name the widget (for example,
"Daily Failed Login"). - Select a time range.
- Choose whether to add it to an existing or new dashboard.
- Click Add.
- Name the widget (for example,
- Optional: Build queries directly into your dashboards. Alternatively, you can copy curated dashboards and modify edits to queries within them as a starting point.
- Optional: You can make a custom dashboard and add widgets to that using YARA-L. For details, see Create a custom dashboard.
Configure a dashboard
When you build a new dashboard, the events section is a required starting point. From there, you have the flexibility to use match (for grouping results) or outcome (for calculating outputs and aggregations).
For example, you can have a dashboard with events and match sections, where your dashboard shows the severity ($severity) of detections grouped by hour buckets.
Example: Aggregate time-series by severity
You can create a dashboard using the events and match sections to display the severity ($severity) of detections grouped into hour buckets:
detection.detection.severity != "UNKNOWN_SEVERITY"
$severity = detection.detection.severity
match:
$severity by hour
Example: Aggregate total critical impact
Similarly, you can create a dashboard using the events and outcome sections to track high-severity detections:
detection.detection.severity = "CRITICAL"
$severity = detection.detection.severity
outcome:
$detection_count = count_distinct($severity)
Example: Visualize detection volume by severity over time
In the following example, you can count critical detections and specify the time range through the console. In many cases, you will use both the match and outcome sections when building a visualization in a dashboard:
detection.detection.severity != "UNKNOWN_SEVERITY"
$severity = detection.detection.severity
match:
$severity by hour
outcome:
$detection_count = count_distinct(detection.id)
Example: Calculate user login frequency
The following example focuses on calculating the login_count for specific users using the match and outcome sections:
events:
metadata.event_type = "USER_LOGIN"
match:
target.user.userid
outcome:
$login_count = count(metadata.id)
Build a rule
A rule requires the following sections:
meta: Contains the rule name and descriptive details.events: Defines your data sources and filters using event variables.condition: Specifies which event variables must exist for the rule to trigger.
Define and use event variables
Event variables act as a logical container, grouping your filters together so you can reference that specific activity throughout your search, rule or dashboard.
When you define logic in the events section, you can use event variables (such as $e) to represent a specific event (or a group of events) that match your criteria.
Example: Define and filter event variables
To define an event variable (for example, $e), use a prefix in the events section of your query. This declares those events to be represented by the variable. For instance, the expression $e.principal.hostname = "dev" evaluates each event to determine if the hostname is an exact match.
$e.principal.hostname = "dev"
$e.metadata.event_type = "USER_LOGIN"
You can then use that variable in other sections of the query to reference that specific group of events (in match, outcome, condition sections) and their data fields.
Organize rule structure and syntax
Use the following rule structure and syntax to help you define your variables, grouping logic, and trigger thresholds:
| Element | Description | Example |
|---|---|---|
| Rule structure | Wraps your query in a rule block and assigns a unique name to identify the detection. |
rule DailyFailedLoginAttempts { } |
meta section |
Required. Includes descriptive metadata (such as `author`, `description`, `severity`) to improve rule management and provide context for your team. Recommended as a best practice for rule management. | author = "Alex"severity = "Medium" |
| Event variable | In a rules query, each field in the events section is prefixed with an event variable (like $e) to represent a specific event (or a group of events) that match your criteria. They act as logical groupings of filters. In the Convert your search to a YARA-L rule example, $e represents all user failed logins. |
$e.metadata.event_type = "USER_LOGIN" |
| Placeholder variable | Assigns an event to a common name that you can reference later in the query. For details, see Use placeholder variables. | $userid = $e.principal.user.userid |
match section |
Defines your groupings and specifies a supported time window. In the Convert your search to a YARA-L rule example, the match: $userid over day grouping correctly groups events by the user ID within each 24-hour period (1d). When you write a rule, you must specify a supported time window to define your lookback period. You can implement a hop, sliding, or tumbling window depending on your logic requirements. Using the over operator explicitly creates a hop window. |
$userid over 1d |
outcome section |
Performs statistical aggregations or captures specific variables to make your resulting alerts more informative. Use the count() function on $e.metadata.id to aggregate events within each match group. You can also assign variables, such as $userid, to capture specific UDM fields and provide more context in the resulting detection output. |
$failed_count = count($e.metadata.id) |
condition section |
Required for a rule to generate a detection. Defines your detection threshold in the condition section. For example, using #e > 5 requires that the event count must exceed five (5) to trigger an alert. If you're not performing calculations, you still need a condition section and state the existence of the event variable (for example, #e). Analyze your environment's baseline to set thresholds that catch suspicious activity while minimizing false positives. If you’re not performing calculations, you still need a condition section and simply state the existence of the event variable, such as #e. |
#e > 5 or $e |
To understand how this structure works, see the following example.
Example: Detect brute force (multiple failed logins)
The following example detects multiple failed login attempts for a single user within a 24-hour window:
rule DailyFailedLoginAttempts {
meta:
author = "Alex"
description = "Detects multiple failed login attempts for a single user within a day."
severity = "Medium"
events:
$e.metadata.event_type = "USER_LOGIN"
$e.security_result.action = "FAIL"
$e.principal.user.userid != ""
$userid = $e.principal.user.userid
match:
$userid over 1d
outcome:
$daily_failed_login_count = count($e.metadata.id)
condition:
$daily_failed_login_count > 5
}
Convert your search to a YARA-L rule
To convert a finalized search query into a reliable rule for generating detections, you typically follow these steps:
- In Google SecOps, go to the Rules Editor.
- Start a new rule.
- Paste the search query and modify it to fit the rule structure, including:
metasection: Defines the metadata rule, including the rule name, author, and severity leveleventsection: Required. Unlike in search, you must have a namedevent` section header.- Event variables: Declares and references specific events (or groups of events) within your logic.
matchsection with supported time windows: Specifies your grouping keys and defines the time parameters (for example,5mor1d). Note: If you use amatchsection in rules, you must add a time window.conditionsection: Defines the final logic or threshold that must be met to trigger a rule.
Advanced: Build a multi-event rule
You use a multi-event rule to correlate different types of activity that occur within a specific timeframe. Instead of looking at a single event, you connect multiple events, such as a user logging in and then immediately performing an unusual file download, to identify complex threats.
A multi-event rule requires the following sections:
meta: Contains the rule name and descriptive details.events: Defines your data sources and filters using event variables.match: Sets the timeframe and the placeholder variable used to bridge your events.outcomeCaptures additional context for the alert. Multi-event rules require an aggregation function.condition: Specifies which event variables must exist for the rule to trigger.
To build a multi-event rule, do the following:
- Define your event variables: In the events section, define
$e1to capture"PROCESS_LAUNCH"events and$e2to capture specific malicious file hashes. - Correlate with placeholders: Use the
$userplaceholder variable to connect these two distinct event streams by a shared principal user ID (for example,$user = $e1.principal.user.userid and $user = $e2.principal.user.userid). - Group the match: In the
matchsection, you specify that these events must happen for the same$userwithin a set window of time, such as 5 minutes (5m).
Example: Build a multi-event rule
In the following example, $e1 represents a PROCESS_LAUNCH event and $e2 represents an event with a specific malicious hash. The $user placeholder variable correlates these events by the same principal user ID.
rule MultiEventExample {
meta:
author = "Alex"
description = "Detects a bad hash execution or a process launch from a specific IP for the same user."
events:
$e1.principal.ip = "1.1.1.1"
$e1.metadata.event_type = "PROCESS_LAUNCH"
$e2.target.file.sha256 = "badhash..."
$user = $e1.principal.user.userid
$user = $e2.principal.user.userid
match:
$user over 5m
condition:
$e1 or $e2
}
The following rule components describe the logic used in the example:
- Event variables: Defined two event variables,
$e1and$e2. Used the placeholder variable$userto join these events on the commonuseridfield. matchsection: Included amatchsection for this multi-event rule to group by user and specify a hop time window of five minutes (5m) to correlate the events.conditionsection: Defined the logic to trigger the alert. This example triggers an alert if either the first or the second event exists.
Use other tools to build your query
These tools are essential companions for writing, validating, and accelerating YARA-L adoption:
- UDM Lookup tool: Quickly search and reference UDM field names, definitions, and data types directly within the UI. If the field ID is unknown, prioritize checking this reference.
- Natural language to YARA-L search: In the search bar, enter descriptions to draft your initial query or get or translate corresponding YARA-L suggestions.
- SPL → YARA-L Translator (Labs tool): If you're transitioning from competitor platforms, use this tool (available in the Labs section) to convert legacy Splunk SPL queries into YARA-L. This generates a structured starting point, which accelerates your migration and refines your detection logic. To use the Labs tool, in Google SecOps, go to yourinstancename.chronicle.security/labs.
What's next
- Explore the full YARA-L 2.0 language syntax
- Browse the functions in YARA-L 2.0
- Browse the Google SecOps community) for more examples
Need more help? Get answers from Community members and Google SecOps professionals.