Security Blog

Google PSOE Exam Insights: Detection Engineering with Context Data

Written by Cody Rochester | September 29, 2025

Continuing on from my initial PSOE Study Guide where I shared my experience passing Google Cloud Security’s new Professional Security Operations Engineer (PSOE) certification and provided an overview of the six key domains covered by the exam. As promised, we're now kicking off a deeper dive to help you in your preparation.

Preparing for this exam can feel overwhelming because it spans a wide array of domains across the Google Cloud security suite. My preferred approach:

  • Use the exam objectives as a study guide.
  • Perform hands-on work in areas I’m less familiar with—real experience is the best teacher.

This article maps directly to Section 4: Detection Engineering
→ 4.1 Developing and implementing mechanisms to detect risks and identify threats
→ Assessing how to use entity/context data within detection rules to improve their accuracy (e.g., Google SecOps Entity Context Graph).


Detection Engineering is domain #4  of the Google Cloud Professional Security Operations Engineer cert

 

Laying the Groundwork

Before diving in, we need to ensure that we have a solid grasp on each piece of the puzzle here. The objective is requiring an understanding of Yara-L detection rules, and entity/context data (ECG - Entity Context Graph). 

Let's define these so we have firm footing to work on.

YARA-L Rules

In an effort to be concise, I won't go in depth on the basic structure of yara-l rules, but the documentation here is a great resource to get up to speed before moving on.

Entity/Context Data

The next and largest puzzle piece here is entity/context data. To put it simply, context data logs are there strictly for the purpose of providing context to entities. These logs can be from three sources.

  • ENTITY_CONTEXT: These are logs that were manually added to the environment. (ex. Azure AD, 3rd party IOC feed)
  • DERIVED_CONTEXT: These are logs that are added via SecOps automation passively (ex. first_seen/last_seen timestamps for entities)
  • GLOBAL_CONTEXT: These are logs that are provided by Google (ex. WHOIS, OPEN_SOURCE_INTEL_IOC, MANDIANT_FUSION_IOC) **Enterprise+ license required for Mandiant Fusion IOC

Entities are mapped to a fixed type such as:

DOMAIN_NAME, FILE, IP_ADDRESS, RESOURCE, URL, USER

Adding this to UDM Search will pull the list of entity types and show you how many records of each exist in your environment:

graph.metadata.entity_type = $entityType
match:
 $entityType
outcome:
  $total = count(graph.metadata.product_entity_id)

 

Google SecOps Search results showing entity type counts across the environment (formerly UDM Search).


To search or reference Entity/Context logs, you will need to always use graph. followed by either metadata. or entity. depending on the circumstance. For example:

graph.metadata.vendor_name = "Okta"
graph.entity.user.title = "Intern"

 

Example 1: Enhancing a Login Detection Rule

Now that we've laid the groundwork, we'll cover a couple of examples that should turn the theory into something real that you can work with.

The first example will be a simple rule to detect a USER_LOGIN event.

rule PSOE_Training {

 meta:
   author = "cody.rochester@foresite.com"

 events:
   $e1.metadata.event_type = "USER_LOGIN"
   $e1.security_result.action = "ALLOW"
   $ip = $e1.principal.ip

 match:
   $ip over 1h

 condition:
   $e1
}

This rule has little value on its own. We can improve it by joining entity/context data:

rule PSOE_Training {

 meta:
   author = "cody.rochester@foresite.com"

 events:
   $e1.metadata.event_type = "USER_LOGIN"
   $e1.security_result.action = "ALLOW"

   //joining triggering event to entity data
   $ip = $e1.principal.ip
   $ip = $e2.graph.entity.ip

   $confidence_details = cast.as_float($e2.graph.metadata.threat.confidence_details)
    $confidence_details > 80

 match:
   $ip over 1h

 condition:
   $e1 and $e2
}


By establishing a variable that must be an equivalent value between $e1 and $e2, I've now created what is called a "join" by stating that this rule will only be allowed to fire if the principal.ip from the login event is the same as the graph.entity.ip from an entity/context log.

 

Example 2: Reducing False Positives in Permissions Changes

Now that this join is established, we've essentially unlocked the other fields that exist within that entity/context log which can be used in the Outcome section, downstream in SOAR, and in the Events section to add additional logic into rules.

To ensure you are using entity fields that exist in your SIEM, a good method is to use Search to find the logs you'd like to use for enrichment to validate the fields. Start broad with a Search like graph.metadata.source_type = "GLOBAL_CONTEXT" and use the aggregation feature to find the kinds of logs you are wanting to join as context data to raise the fidelity of your detection.


Google SecOps Search displaying available entity context fields, including entity.ip, product entity IDs, and metadata attributes

IOC feeds will often provide scores that can be used like in the example above. If you have difficulty using a number from entity/context data in a detection rule, check the log to see what datatype the value is being parsed as. Some fields will be strings and be encased by quotations. Mathematical functions/operations aren't possible with strings, so be sure to use entity fields that are number values when writing number operations into your detection rules.

Moving onto the second example, let's make a simple rule to detect RESOURCE_PERMISSIONS_CHANGE events on a protected type of resource if the resource name contains "boston_devs_only".

Baseline rule:

rule PSOE_Training {

 meta:
   author = "cody.rochester@foresite.com"

 events:
   $e1.metadata.event_type = "RESOURCE_PERMISSIONS_CHANGE"
   $e1.target.resource.name = /boston_devs_only/
   $user = $e1.principal.user.email_addresses

 match:
   $user over 1h

 condition:
   $e1
}

 

Unfortunately, this rule is frequently sending false positives because certain developers are permitted to make these changes. While we could add exclusions for developers, that leaves room for error with stale accounts, new employees, and any employees who have their privileges revoked, requiring a high level of effort to maintain. Another issue with this use case is that only developers from the Boston office are permitted to perform these actions. We can't geo-block outside of Boston because many developers are working remotely and we want to allow all developers who are assigned to the Boston Office. Thankfully, in this example, we are ingesting Okta context data which provides a lot of information about User entities.

 

Improved with Context Data

rule PSOE_Training {

 meta:
   author = "cody.rochester@foresite.com"

 events:
   $e1.metadata.event_type = "RESOURCE_PERMISSIONS_CHANGE"
   $e1.target.resource.name = /boston_devs_only/

   //joining triggering UDM event to ECG (Entity Context Graph)
   $user = $e1.principal.user.email_addresses
   $user = $e2.graph.entity.user.email_addresses

   //ensuring the entity context data is coming from Okta to avoid conflicts with other context sources
   $e2.graph.metadata.vendor_name = "Okta"

   not (
       $e2.graph.entity.user.title = /developer/nocase and //regex matching on all titles containing the string "developer"
       $e2.graph.entity.location.name = "Boston Office"
   )

 match:
   $user over 1h

 condition:
   $e1 and $e2
}

 


Expanded view of Google SecOps Search showing entity context metadata such as threat confidence, feed source, and vendor details

Referencing the location name and job title updated by Okta entity data, the detection rule is running against the real-time information regarding these users, reducing maintenance significantly. This is a great example of how entity/context data can be used to improve the accuracy of a detection rule. I would encourage anyone preparing for the PSOE to query entity data in an environment that they have access to and think of ways to apply the contextual information to detection rules to improve fidelity. There's no better teacher than experience!

 

Takeaways

  • Entity/context joins raise detection fidelity by unlocking enriched fields.

  • Use Search to validate available fields and data types before writing rules.

  • Numeric fields can be used in scoring logic; string fields cannot.

  • Context data from identity providers like Okta is invaluable for tuning permissions-based rules.

If you’re preparing for the PSOE certification, practice writing detection rules that apply enrichment data. Theory is useful, but experience in SecOps environments is the best preparation.

Next Step: Want more PSOE study insights?

👉 Subscribe to our blog for practitioner-led breakdowns on Google Cloud Security exams and real-world SecOps applications.