Skip to main content
Solved

Data table event enrichment (inner vs left vs outer)

  • February 3, 2026
  • 7 replies
  • 382 views

komajaro
Forum|alt.badge.img+1

Hello,

Is there a way to influcence the type of join operation when using data tables ?

Previously, when working with splunk there was an option to pick one of 3 choices: inner, outer or left.

When working with data tables in secops I see that it behaves like an inner join, which effectively filters results, which is something I want to avoid.

Example:

  • when a data table contains account A and events contain account A enrichment works as expected.
  • when a data table contains account B and events contain account A enrichment does not work and events are filtered out (but I want to see them despite ‘unsuccessful’ enrichment).

Best answer by jstoner

The release notes (https://docs.cloud.google.com/chronicle/docs/secops/release-notes) are the best place for this as they should be rolled out there. I see the initial join release in September but not the subsequent one. I am doing a little research to see if there is an update on this. Your account or partner team may also be able to assist with this for some additional details. 

7 replies

jstoner
Community Manager
Forum|alt.badge.img+24
  • Community Manager
  • February 3, 2026

There is on-going work on joins with data tables occurring and this question is timely but potentially a little early. I tested this on my internal tenant and was able to get a result but I don’t believe it has been pushed out fully. That said, we can (shortly) do a left join between the events and a data table and the search syntax would look something like this:

 

$e.metadata.event_type = "USER_LOGIN"
$e.target.user.userid = $user
left join $e.target.user.userid = %adhoc_users.userid
match:
$user
outcome:
$company = array_distinct(%adhoc_users.organization)
$state = array_distinct(%adhoc_users.state)
$probationary = array_distinct(%adhoc_users.probationary)

This would give you all the user login events and then show the org, state and probationary status of the users that exist in both the event and data table but still provide the users in the events even if they are not in the data table.

Again, this may not be in your tenant yet but should be getting there soon.


komajaro
Forum|alt.badge.img+1
  • Author
  • New Member
  • February 4, 2026

Hey John,

Thanks a lot for the explanation and a follow-up question:
- How can I track this functionality ?
- Should I just read the release notes or is there a way to verify this from within our Google SecOps instance ?


jstoner
Community Manager
Forum|alt.badge.img+24
  • Community Manager
  • Answer
  • February 4, 2026

The release notes (https://docs.cloud.google.com/chronicle/docs/secops/release-notes) are the best place for this as they should be rolled out there. I see the initial join release in September but not the subsequent one. I am doing a little research to see if there is an update on this. Your account or partner team may also be able to assist with this for some additional details. 


komajaro
Forum|alt.badge.img+1
  • Author
  • New Member
  • February 11, 2026

As I haven’t received a response from our partner team, I wanted to check whether you were able to obtain any information about that functionality ?


jstoner
Community Manager
Forum|alt.badge.img+24
  • Community Manager
  • February 20, 2026

Just closing the loop on this but the release notes appeared a few days ago https://docs.cloud.google.com/chronicle/docs/secops/release-notes#February_12_2026


NASEEF
Forum|alt.badge.img+9
  • Silver 2
  • June 2, 2026

Hello @JStoner,

Is left join / optional enrichment against a reference list or datatable supported in YARA-L rules today?

I have a detection where I want to enrich alerts with a bunit value from a datatable based on the source IP.

Desired behavior:

  • If the source IP exists in the datatable, populate bunit in the outcome.
  • If the source IP does not exist in the datatable, still generate the detection and set bunit to null/empty.

Example:

Source IP = 10.1.1.1

Datatable:
10.1.1.1 -> Servers
10.1.1.2 -> Workstations

Expected outcome:

 
IP = 10.1.1.1, bunit = Servers

and

 
IP = 10.1.1.3, bunit = null

From my testing, once I add a datatable join such as:

 
$e.principal.ip = %asset_table.ip
%asset_table.bunit = $bunit

the datatable match becomes mandatory and events without a matching IP are excluded from the rule.

Is there currently a supported way to perform this type of optional enrichment (left join semantics) in YARA-L, or is pre-enrichment outside the rule the recommended approach?

Thanks.


hliu
Forum|alt.badge.img+5
  • Bronze 4
  • July 3, 2026

Average Splunk |lookup enjoyer here.

As noted by ​@komajaro and ​@NASEEF
the default behavior of Secops data table is an inner join, instead of outer.
While this is great for filtering, it’s a headache for enrichment.
If a value isn't in the table, the event is dropped, leading to potential false negatives.

The recent left (outer) join feature mentioned by ​@jstoner works in UDM Search, however it isn't available in the Detection Engine yet.

Possible workarounds in the rules to emulate an outer left join today:

1. catch-all row in the datatable + reference list guardrail

This trick ensures that the key passed to the Data Table always exists in that table, preventing the rule from dropping the event.

a. Add a row to your Data Table where the key is catchall_unknown and the enrichment columns are empty or say NA.
b. Create a Reference List containing all the keys actually present in the Data Table.

c. In the detection rule, e.g.:

// reference list guardrail to protect against losing events from unmatched data
$safe_key_from_event=if($key_from_event in $reference_list, $key_from_event, "catchall_unknown")

//event and datatable join, now effectively an outer join
$safe_key_from_event=%data_table.key_column

//enrichment mapping
$other_columns_from_table=%data_table.other_columns_from_table

The reason on using an additional 1-dimensional reference list for guardrail, instead of re-using the original datatable, is because the rule engine doesn’t allow a data table within the if() function, most likely the engine treats the %table.column syntax as joins instead of logical evaluations. However if the column is dropped from the syntax (like in the case of reference lists), it works.
Remember to use a match section and there is a max number of tables per rule if the in  operator is used.


2. ingest the table into the entity graph

For either automatic enrichment or, if the entries (key_column values) are not an usual entity type like USER or HOSTNAME, join with entity graph in the rule.
 

Let's imagine a relatively complicated example where the data table consists of
country_code,country,zone,description,risk_score,risk_type,etc

being country_code an ISO alpha-2 code, which would be the match key to custom extractions from other assets like user's email: name. lastname. @ XX . company. net


Use the RESOURCE entity type (entity.metadata.entity_type = "RESOURCE"), designed to represent abstract objects, locations or organizational units that aren't specifically a user or host.

Example mapping of the data table to UDM entity:
country_code > entity.metadata.product_entity_id (The match key)
country > entity.resource.name
zone > entity.resource.resource_subtype
description > entity.metadata.description
risk_score > entity.metadata.severity (or a custom label)
risk_type > entity.resource.attribute.labels
etc.


Once country_codes from the table are ingested as entities, in the detection rule we could proceed with the key extraction from the event and join
$e.event_key = $d.graph.entity.metadata.product_entity_id

by default this is still an inner join however we could make it outer join with this trick:

condition: $e and #d >= 0

where $e presence is mandatory and #d is optional, effectively left outer join.

I haven't personally tested this second option as-is.
It worked for me when I needed to left outer join 2 event datasets $e1 and (#e2 >= 0)
but ​@jstoner  doesn't think it applies to entities.

 

however in Google documentation they are using this syntax $e and #d > 10  so there's hope.

let us know whether anyone tries trick 2, knows any other method, or if left outer join feature is soon to be released for detection rules