How Do I Write YARA-L Detection Rules in Google SecOps?

Security teams collect enormous amounts of telemetry, but raw logs rarely tell an analyst whether an activity represents a genuine threat. This is where detection rules become important. In Google SecOps, YARA-L provides a way to turn security events into detection logic by describing the behavior, relationships, and conditions that should be considered suspicious.

Writing an effective YARA-L rule is not simply a matter of learning syntax. The real challenge is translating a security hypothesis into precise logic that can identify meaningful activity without overwhelming analysts with irrelevant alerts.

What Is YARA-L in Google SecOps?

YARA-L is the detection-rule language used by Google SecOps to identify patterns in security telemetry. It operates against events represented through the Unified Data Model (UDM), allowing a rule to examine individual events as well as relationships between multiple events.

A simple rule can look for a particular event and field value:

rule Suspicious_Login {
  meta:
    author = "Security Team"
    description = "Detects a failed user login"

  events:
    $e.metadata.event_type = "USER_LOGIN"
    $e.security_result.action = "FAIL"

  condition:
    $e
}

This example is intentionally simple. It demonstrates the fundamental structure of a YARA-L rule: metadata describes the detection, the events section defines the evidence, and the condition determines when that evidence is sufficient to produce a detection.

More sophisticated rules can correlate different events, group activity around entities such as users or hosts, apply time windows, perform aggregation, and generate additional outcome information.

Start With a Security Hypothesis

The best way to write a YARA-L rule is to begin without writing YARA-L.

First describe the behavior you want to detect in plain language.

For example:

Detect repeated failed authentication attempts against the same account within a short period.

This statement contains nearly everything needed to design the detection:

  • The relevant behavior is authentication failure.
  • Multiple events are required.
  • The account is the entity connecting those events.
  • A time window is necessary.
  • A threshold determines when the behavior becomes interesting.

Only after these decisions have been made should they be translated into YARA-L.

This approach prevents a common detection-engineering problem: writing syntactically correct rules that do not actually represent a useful security hypothesis.

Understand the Main Parts of a Rule

A YARA-L rule can contain several sections, with meta, events, and condition forming the basic foundation.

rule Failed_Login_Burst {
  meta:
    author = "Security Team"
    description = "Detects repeated failed logins for one user"

  events:
    $e.metadata.event_type = "USER_LOGIN"
    $e.security_result.action = "FAIL"
    $user = $e.target.user.userid

  match:
    $user over 10m

  outcome:
    $failed_count = count($e.metadata.id)

  condition:
    #e >= 5
}

Each section has a different responsibility.

The meta section provides information about the rule itself. Good metadata should explain what the detection is intended to find and provide enough context for another engineer to understand its purpose.

The events section defines the evidence. This is where you identify the UDM fields and values that represent the behavior.

The match section establishes how events are grouped and over what period.

The outcome section can produce useful information from the matching activity.

The condition section determines when the evidence satisfies the detection criteria.

Keeping these responsibilities separate makes rules easier to understand and maintain.

Choose the Right UDM Fields

One of the most important parts of YARA-L detection engineering happens before the rule is written: identifying the correct UDM fields.

A detection can fail even when its logic looks perfect if it references a field that the relevant log source does not populate consistently.

For example, if a rule relies on:

$user = $e.target.user.userid

you need confidence that the relevant authentication events actually contain the account identifier in that field.

Do not assume that similarly named fields from different products have identical meaning. A username, account identifier, email address, and display name may represent different entities even though all appear to identify a person.

The safest approach is to inspect representative normalized events and determine which field consistently represents the entity you want to correlate.

Use Event Variables to Represent Evidence

Event variables represent the events that satisfy your filters.

For example:

$e.metadata.event_type = "USER_LOGIN"
$e.security_result.action = "FAIL"

Here, $e represents matching login events.

You can then extract an entity from the event:

$user = $e.target.user.userid

The $user placeholder is important because it gives the detection something around which activity can be correlated.

This becomes particularly powerful when multiple event variables are involved.

$login.target.user.userid = $user
$process.principal.user.userid = $user

The shared $user indicates that the authentication and process events concern the same account.

The key idea is to think in terms of relationships, not just individual log entries.

An individual event might be completely legitimate. The relationship between several events may be what makes the activity suspicious.

Define Correlation Around Meaningful Entities

A detection should be grouped around the entity that actually represents the behavior.

Depending on the use case, that might be:

  • A user
  • A host
  • An IP address
  • A process
  • A file
  • A cloud resource
  • An application account

For example, repeated failed logins should generally be associated with the account being targeted. A process-based behavior might instead need to be associated with the originating host or user.

Choosing the wrong correlation key can dramatically change what the rule detects.

Consider a rule that groups failed authentication attempts only by source IP. Multiple users behind a shared proxy could become one apparent attack. Conversely, grouping only by user could combine activity from unrelated locations.

The correlation key should therefore reflect the question the detection is trying to answer.

Use Time Windows to Represent Behavior

The match section allows related activity to be evaluated within a defined period.

For example:

match:
  $user over 10m

This means the rule evaluates matching activity associated with the same user within the specified window.

The window should represent the behavior you are trying to detect.

A short burst of authentication failures is different from a pattern that develops gradually over several hours. Using an unnecessarily broad window can cause unrelated activity to appear connected, while an excessively narrow window can cause genuine behavior to be missed.

A useful design question is:

Would an analyst consider these events part of the same incident if they occurred at opposite ends of this window?

If the answer is no, the window may be too large.

Make the Condition Express the Detection Threshold

The condition section should represent the point at which evidence becomes significant.

For example:

condition:
  #e >= 5

The #e expression represents the number of matching events associated with the event variable.

This gives the rule a clean separation between evidence and decision logic.

The events section answers:

What constitutes a relevant failed login?

The match section answers:

Which failed logins belong to the same behavioral window?

The condition answers:

How much activity is required before the behavior becomes a detection?

That separation makes tuning substantially easier.

Correlate Multiple Events for Higher-Context Detections

Many useful detections cannot be expressed by looking at a single event.

Suppose the security hypothesis is that a user authentication is followed by suspicious process activity on the same endpoint.

The rule can represent the two observations separately:

events:
  $login.metadata.event_type = "USER_LOGIN"
  $login.target.user.userid = $user

  $process.metadata.event_type = "PROCESS_LAUNCH"
  $process.principal.user.userid = $user

The shared placeholder establishes a relationship between the events.

This style of detection can provide more context than a simple event filter because the signal comes from the combination of behaviors.

However, correlation should be purposeful. Adding more events does not automatically make a detection better. Every additional event should contribute meaningful evidence to the security hypothesis.

Protect Against Empty or Missing Values

Correlation logic requires particular care when fields can be absent.

For example:

$user = $e.target.user.userid

looks straightforward, but what happens when the field is missing?

A detection that unintentionally correlates events with empty values can produce misleading results.

Explicitly checking important correlation fields is therefore a useful defensive practice:

$e.target.user.userid != ""
$user = $e.target.user.userid

This is especially important when the rule depends on equality between events.

Detection engineers should always ask:

What happens when this field is missing, empty, malformed, or populated differently by another log source?

Those cases often reveal weaknesses that are invisible when testing only clean examples.

Use Reference Data for Environmental Context

Not everything belongs inside the rule itself.

Organizations often have lists of approved scanners, administrative systems, trusted infrastructure, service accounts, or other known environmental entities.

Instead of embedding those values directly into detection logic, use reference data where appropriate.

Conceptually:

$e.principal.hostname in %approved_hosts

This creates a useful separation.

The detection rule describes the behavior that is potentially suspicious, while the reference data describes the organization’s current environment.

That makes the detection easier to maintain. When infrastructure changes, the contextual data can be updated without rewriting the core behavioral logic.

Treat Exceptions as Carefully as Detection Conditions

False positives often lead engineers to add exclusions.

For example, if legitimate administrative activity repeatedly triggers a rule, it may be tempting to exclude an entire host or account.

Broad exclusions can create blind spots.

Before adding an exception, determine why the activity is legitimate and whether the exception can be narrowed.

Instead of thinking:

This host is trusted.

think:

This specific behavior from this specific administrative context is expected.

That distinction is important because attackers can operate through legitimate infrastructure, compromised administrative accounts, and otherwise trusted systems.

An exception should therefore have an owner, a reason, and a scope that is no broader than necessary.

Use Outcomes to Improve Investigation

A detection should not only tell an analyst that something happened. It should provide useful context about why it happened.

An outcome expression can calculate information from matching events.

For example:

outcome:
  $failed_count = count($e.metadata.id)

The resulting information can help an analyst understand the scale of the activity without immediately returning to the raw telemetry.

This creates a useful distinction between triggering evidence and investigative context.

The condition decides whether the detection fires. Outcomes can help explain the activity after it fires.

Test the Logic, Not Just the Syntax

A rule that saves successfully is not necessarily a good detection.

Testing should include both positive and negative scenarios.

For a repeated-login detection, test cases might include:

  • A single failed login.
  • Several failures within the intended window.
  • Failures separated by more than the intended window.
  • Events where the username is missing.
  • Legitimate authentication systems that generate repeated failures.
  • Different capitalization of relevant string values.
  • Multiple users generating failures from the same infrastructure.

The purpose is to establish whether the rule behaves according to the original security hypothesis.

One particularly useful technique is to write the expected result for each test case before examining the rule’s result. This prevents the observed behavior from becoming the definition of what the rule was supposed to detect.

Tune False Positives by Finding Their Cause

When a detection generates too many alerts, simply increasing the threshold is often the easiest response—but not necessarily the most appropriate one.

Instead, classify why the alerts are occurring.

The cause might be:

  • Legitimate automation.
  • Vulnerability scanning.
  • A noisy identity provider.
  • Shared infrastructure.
  • Incomplete normalization.
  • An overly broad correlation key.
  • An inappropriate time window.
  • A detection condition that is too permissive.

Once the cause is understood, the rule can be adjusted at the correct layer.

This is a valuable detection-engineering principle:

Tune the assumption that is wrong, rather than weakening the entire detection.

Write Rules That Another Analyst Can Understand

A detection eventually becomes part of a larger security operation. The original author may not be available when someone needs to investigate or modify it.

Good metadata and clear variable names therefore matter.

Prefer:

$source_ip
$target_user
$process_event
$authentication_event

over names that require the reader to reverse-engineer their meaning.

The rule should also explain unusual exclusions or non-obvious logic in its metadata or comments.

A good detection is not merely executable logic. It is operational documentation.

A Practical YARA-L Design Pattern

A reusable way to approach many detections is:

Security hypothesis
        ↓
Relevant UDM events
        ↓
Required event fields
        ↓
Correlation entity
        ↓
Time window
        ↓
Detection threshold
        ↓
Investigation outcomes
        ↓
Positive/negative testing
        ↓
Production tuning

This workflow is more durable than memorizing individual YARA-L examples because it can be applied to authentication, endpoint, network, cloud, identity, and other detection scenarios.

Writing YARA-L detection rules in Google SecOps is fundamentally an exercise in detection engineering.

The syntax tells Google SecOps how to express the logic, but the quality of the detection comes from the reasoning behind that logic.

Start with a specific behavioral hypothesis. Identify the UDM events that provide evidence for it. Choose correlation entities carefully, use a time window that reflects the behavior, and make the condition represent a defensible detection threshold. Then test the rule against both expected attacks and legitimate activity.

The most valuable YARA-L rules are not necessarily the most complicated. They are the rules where every condition has a purpose, every correlation has a reason, and every alert gives an analyst enough context to understand what deserves investigation.

That is the difference between a rule that merely matches logs and a detection that contributes meaningful security signal.

Tags: No tags

Add a Comment

Your email address will not be published. Required fields are marked *