Skip to main content
Sticky

Chronicle Rule → Outcome → SOAR Playbook Workflow

  • May 20, 2026
  • 14 replies
  • 291 views

mccrilb
Forum|alt.badge.img+12

I wanted to share the workflow we’ve been using to connect Chronicle detection rules with SOAR (Gemini) playbooks, specifically focusing on how rule design directly drives playbook effectiveness.

The key idea is:

The rule is not just a trigger — it is responsible for providing all the context the playbook needs to make a decision.

1. Rule as the Context Engine

Instead of relying on the playbook to “figure things out,” we push as much structure and meaning as possible into the rule itself.

Each rule is responsible for:

  • Identifying the behavior
  • Normalizing key fields
  • Providing investigation-ready context via the outcome section

By the time the alert reaches the playbook, it should already answer:

  • What happened?
  • Who did it?
  • On what system?
  • Why is it suspicious?

2. Outcome Section as the Contract

The outcome section acts as a contract between the detection rule and the playbook.

We standardize outcomes across rules so every playbook receives consistent inputs.

Core pattern we use:

  • $outcomeUserIsTechnical (true/false)
  • $outcomeUserRoleHint (technical vs non-technical + elevated context)

These are derived from datatables (title + department), not hardcoded logic.

Why this matters

The playbook doesn’t need to:

  • Parse job titles
  • Infer privilege
  • Guess intent

It can immediately reason with:

  • “This is a non-technical user running a recon tool”
  • “This is an elevated admin performing a sensitive action”

3. Passing High-Value Fields Only

We intentionally keep outcome fields:

  • Concise
  • High signal
  • Consistent across rules

Typical fields include:

  • Command line
  • File path
  • Process name
  • Target resource
  • User role indicators

We avoid:

  • Excessive raw telemetry
  • Fields that don’t influence decisions

This keeps playbook prompts clean and performant.

4. Playbook Design (Driven by Rule Output)

Playbooks are designed with the assumption that:

  • The rule already identified suspicious behavior
  • The outcome already provides structured context

So the playbook focuses on decisioning, not discovery.

Playbook Responsibilities

Given the alert + outcome data, the playbook:

  1. Evaluates context

    • User type (technical vs non-technical)
    • Execution context (host, process, command line)
    • Action being performed
  2. Determines verdict

    • Malicious
    • Suspicious
    • Benign
  3. Provides reasoning

    • Based strictly on the current alert context
  4. Recommends next steps

    • Investigate
    • Escalate
    • Close

5. Key Design Constraint

Each playbook execution is context-isolated.

This means:

  • No linking to other alerts
  • No historical correlation assumptions

Because of this, the rule + outcome must be self-sufficient.

If the rule doesn’t provide enough context, the playbook cannot compensate.

6. Workflow in Practice

The flow looks like this:

  1. Rule triggers on high-fidelity behavior
  2. Rule populates standardized outcome fields
  3. Alert is sent to SOAR
  4. Playbook consumes:
    • Detection metadata
    • Outcome variables
  5. Playbook produces:
    • Verdict
    • Reasoning
    • Recommended actions

7. Handling Noise (Critical Insight)

If alerts are noisy, we do not fix that in the playbook.

We go back to the rule and:

  • Refine conditions
  • Add exclusions
  • Tighten logic

Reason:

A playbook should not be responsible for compensating for weak detections.

Cleaner rules = better automation decisions.

8. Where This Model Works Best

This workflow is especially effective for:

  • Behavioral detections (execution, configuration changes, discovery activity)
  • Privilege-sensitive actions
  • High-confidence signals with clear intent

9. Outcome

This approach gives us:

  • Consistent playbook inputs across all rules
  • Simpler and more reliable automation logic
  • Better triage quality (especially with Gemini)
  • Reduced need for complex playbook branching

Closing

The biggest shift for us was treating the rule as the primary source of truth, and the playbook as a decision layer, not a discovery layer.

Curious how others are structuring:

  • Outcome sections
  • Rule-to-playbook contracts
  • Context standardization across detections

Happy to compare approaches.

14 replies

mccrilb
Forum|alt.badge.img+12
  • Author
  • Silver 2
  • May 20, 2026

this is a template of a rule and how it creates the output fields for the playbook. FYI, we are using Legacy Chronicle still.

 

!--scriptorstartfragment-->

rule sh_template_rule_workflow_context_to_playbook {

 

  meta:

    author = "template"

    description = "TEMPLATE: Demonstrates the Chronicle rule → standardized outcome context → Gemini playbook workflow. This rule detects a high-signal suspicious command execution pattern (example technique) and emits consistent outcome fields (host, user, process chain, target process, event metadata, and user role hints). The intent is to show how the detection rule provides the context contract that the SOAR/Gemini playbook consumes to produce a verdict and recommended actions. MITRE: (template) Defense Evasion (TXXXX), Discovery (TXXXX)."

    gemini_prompt = "This alert was generated by a TEMPLATE Chronicle rule designed to demonstrate the workflow where the rule provides structured context to a SOAR/Gemini playbook via standardized outcome fields. The detection data includes the hostname (alertHostname), user (alertPrincipalUser), user role hints (outcomeUserRoleHint, outcomeUserIsTechnical), target process (alertTargetProcessPath, alertTargetProcessCommandLine), principal/parent process context (alertPrincipalProcessPath, alertPrincipalProcessCommandLine, alertParentProcessPath, alertParentProcessCommandLine), and event metadata (alertEventType, alertProductEventType) plus an event count (alertDistinctEventCount). Use ONLY the data in this alert; do not assume related alerts, prior cases, or historical context. Evaluate: 1) Who ran it (alertPrincipalUser) and whether their role hint suggests this is expected; non-technical users performing high-risk actions are more suspicious. 2) The process chain and execution method; interactive shells and unusual parents increase suspicion. 3) Whether the command line indicates high-risk intent versus routine administration. 4) Identify what additional validation steps an analyst should take to confirm maliciousness or benign intent (e.g., corroborating process tree, verifying change tickets, checking follow-on behaviors). Provide a verdict of Suspicious or Malicious by default unless there is clear evidence of an approved/admin scenario. Output valid JSON with exactly three fields: explanation, verdict, verdict_explanation. Do not include any additional text."

    reference = "https://example.com/template-reference"

    tags = "attack.example, workflow.template, rule-to-playbook, gemini"

    rule_inspiration = "Community workflow example: rule provides context contract for playbook"

    rule_validation = "Template / Not validated"

    severity = "Medium"

    dataTables = "UserRole_Technical_Titles, UserRole_Technical_Depts, UserRole_Elevated_Titles, UserRole_Elevated_Depts"

   

 

  events:

    // TEMPLATE: Replace vendor/product filters with what your environment uses.

    ($e1.metadata.vendor_name = "Crowdstrike" or $e1.metadata.product_name = "Microsoft-Windows-Sysmon")

    and ($e1.metadata.event_type = "PROCESS_LAUNCH"

            or $e1.metadata.event_type = "STATUS_UPDATE"

            or $e1.metadata.event_type = "PROCESS_UNCATEGORIZED"

    )

    and $e1.principal.hostname = $hostname

 

    // TEMPLATE DETECTION: Example suspicious command execution patterns (safe to share).

    // Swap this section to match your actual use case (bcdedit, vssadmin, netsh, schtasks, etc.)

    and (

      // --- PATH 1: High-signal discovery/admin commands launched interactively ---

      ($e1.target.process.command_line = /\b(cmd\.exe|powershell\.exe)\b/ nocase

            and $e1.target.process.command_line = /\b(whoami|nltest|net\s+user|net\s+group|dsquery|wmic|systeminfo)\b/ nocase

      )

 

      // --- PATH 2: High-risk configuration change keywords (template) ---

      or ($e1.target.process.command_line = /\b(set|config|disable|delete)\b/ nocase

            and $e1.target.process.command_line = /\b(policy|logging|security|firewall|defender)\b/ nocase

      )

    )

 

    // TEMPLATE: Exclude common enterprise tooling (keep generic)

    and not $e1.principal.process.file.full_path = /\\Tanium\\|\\BigFix\\|\\ConfigMgr\\|\\SCCM\\|\\Lansweeper\\|\\Defender\\/ nocase

 

  match:

    $hostname over 5m

 

  outcome:

    // --- Host & User Context (4) ---

    $alertHostname = array_distinct($e1.principal.hostname)

    $alertPrincipalUser = array_distinct($e1.principal.user.userid)

 

    // Use your established "service/machine account aware" role-hinting pattern

    $outcomeUserIsTechnical = array_distinct(

      if(

        ($e1.principal.user.userid = /\$$/)

        or ($e1.principal.user.windows_sid = "S-1-5-18")

        or ($e1.principal.user.windows_sid = "S-1-5-19")

        or ($e1.principal.user.windows_sid = "S-1-5-20")

        or ($e1.principal.user.windows_sid = /S-1-5-93-/),

        "true",

        if(

          ($e1.principal.user.title in regex %UserRole_Technical_Titles.Title nocase)

          or

          ($e1.principal.user.department in %UserRole_Technical_Depts.dept nocase),

          "true",

          "false"

        )

      )

    )

 

    $outcomeUserRoleHint = array_distinct(

      if(

        ($e1.principal.user.userid = /\$$/)

        or ($e1.principal.user.windows_sid = "S-1-5-18")

        or ($e1.principal.user.windows_sid = "S-1-5-19")

        or ($e1.principal.user.windows_sid = "S-1-5-20")

        or ($e1.principal.user.windows_sid = /S-1-5-93-/),

        "service",

        if(

          (

            ($e1.principal.user.title in regex %UserRole_Technical_Titles.Title nocase)

            or

            ($e1.principal.user.department in %UserRole_Technical_Depts.dept nocase)

            or

            ($e1.principal.user.title in regex %UserRole_Elevated_Titles.Title nocase)

            or

            ($e1.principal.user.department in %UserRole_Elevated_Depts.dept nocase)

          ),

          "technical",

          "non-technical"

        )

      )

    )

 

    // --- Process Chain (4) ---

    $alertPrincipalProcessPath = array_distinct($e1.principal.process.file.full_path)

    $alertPrincipalProcessCommandLine = array_distinct($e1.principal.process.command_line)

    $alertParentProcessPath = array_distinct($e1.principal.process.parent_process.file.full_path)

    $alertParentProcessCommandLine = array_distinct($e1.principal.process.parent_process.command_line)

 

    // --- Target Process (2) ---

    $alertTargetProcessPath = array_distinct($e1.target.process.file.full_path)

    $alertTargetProcessCommandLine = array_distinct($e1.target.process.command_line)

 

    // --- Event Metadata (2) ---

    $alertEventType = array_distinct($e1.metadata.event_type)

    $alertProductEventType = array_distinct($e1.metadata.product_event_type)

 

    // --- Count (1) ---

    $alertDistinctEventCount = count_distinct($e1.metadata.id)

 

  condition:

    $e1

}!--scriptorendfragment-->


mccrilb
Forum|alt.badge.img+12
  • Author
  • Silver 2
  • May 20, 2026

then a simple playbook outline to show how we inject the information to gemini and parse the response:

Playbook name: Rule and Gemini Integration
Purpose: When a Chronicle detection generates a case, this playbook:

  1. Pulls the rule metadata (especially metadata.gemini_prompt, plus description/tags)
  2. Builds a Gemini prompt that includes:
    • the rule’s gemini_prompt
    • the rule’s description/tags
    • up to 20 outcome fields from the detection event
  3. Calls “Ask Gemini”
  4. Cleans Gemini’s response (because the result comes back HTML-wrapped / code-block-wrapped)
  5. Parses the JSON (unflattens it so key/value fields are easy to reference)
  6. Branches based on verdict (Benign vs not Benign)
  7. Writes Gemini’s verdict/explanation into the case as a “General Insight”

matthewnichols
Community Manager
Forum|alt.badge.img+20

Now that’s what I’m talking about! Thanks ​@mccrilb for sharing this with the Community! Would love to hear feedback from Community members on this. Keep ‘em coming ​@mccrilb


GromeroSec
Forum|alt.badge.img+5
  • Bronze 2
  • May 24, 2026

Really like this model, especially the idea of treating the rule output as a contract for the playbook.

My approach is very similar in spirit, but with one additional layer: I use the rule + alert context as the input for a structured N1 decision workflow, not just as enrichment for a downstream action.

In practice, the playbook I’m using in Google SecOps / SOAR behaves like an N1 triage agent with three explicit outcomes:

  • YES = the rule itself likely needs tuning
  • VALIDACION = the event may be benign / expected, but requires customer validation before any exception is approved
  • NO = the rule appears aligned and the alert still has security value

That distinction has been useful because it separates three very different operational paths:

  1. actual rule-quality problems
  2. customer-owned exception candidates
  3. valid detections that should stay as detections

A few design choices that have worked well for me:

1. The playbook is context-isolated too
Very similar to your model, I do not assume historical correlation inside this decision step. The playbook evaluates the current alert and its rule context as a self-contained unit.

2. The prompt is strict about judging the rule, not just the event
One thing I explicitly push in the Gemini step is:
“decide whether the problem is the rule, not only whether the event looks benign.”

That helps avoid the common failure mode where automation starts compensating for weak detections instead of identifying them.

3. VALIDACION is a first-class outcome
This has been important operationally.
A lot of alerts are not “bad rule” vs “good rule” in a pure technical sense.
Sometimes the rule matches exactly what it was meant to detect, but the activity may still be business-authorized.
In those cases, I do not want the playbook to jump directly to exclusion logic.
I want it to produce a structured “customer validation required” path.

4. The output is operational, not only analytical
The Gemini step returns a tightly constrained result:

  • classification
  • assessment
  • cause
  • and, when applicable, up to two concrete YARA-L-level tuning options

If the result is VALIDACION, the next path is not “auto-tune.”
It becomes a controlled communication / validation flow with the customer.

5. The playbook also creates reusable operational objects around the alert
For example, I create entities from detection metadata such as:

  • rule name / threat signature
  • source / technology context

That makes later handling in the case easier and keeps the triage layer more structured.

So in short, the model I’m converging on is:

rule = source of detection intent and structured context
playbook = decision layer for N1 triage and next-step routing

Not discovery. Not broad correlation. More like a controlled judgment layer on top of the alert.

I also agree strongly with your point on noise:
if the output keeps landing in “YES,” I treat that as evidence that the rule logic needs work, not that the playbook should become more clever.

Curious if you’ve also found value in separating:

  • true rule tuning issues
  • valid detections that require customer confirmation
  • valid detections that should remain actionable without exception handling

That separation has helped a lot in my environment.


mccrilb
Forum|alt.badge.img+12
  • Author
  • Silver 2
  • May 26, 2026

I like that!.

There is a lot here to digest!

 We have a different workflows, but the central idea looks to be much the same. I am curious how Gemini determines if the issue is a rule tuning problem? do you also pass the full rule on with the prompt? 

I am curious if you have also seen some of the issues that I have seen. If the input is too long, it crashes. I have seen that on threat hunting rules for encrypted powershell. Also we sometimes hit a guardrail for some hashes. Lastly, I had to build a python function to cleanup the output from gemini as it will occasionally output html code or other ASCII characters that bust the unflatten JSON function.

Anyone else taken this path? I would be open to having a conversation on this instead of trying to talk in text. I would like to hear Google’s thoughts on what we are doing, maybe work with us or anyone else doing this? Host a call? 

 


GromeroSec
Forum|alt.badge.img+5
  • Bronze 2
  • May 27, 2026

I like that!.

There is a lot here to digest!

 We have a different workflows, but the central idea looks to be much the same. I am curious how Gemini determines if the issue is a rule tuning problem? do you also pass the full rule on with the prompt? 

I am curious if you have also seen some of the issues that I have seen. If the input is too long, it crashes. I have seen that on threat hunting rules for encrypted powershell. Also we sometimes hit a guardrail for some hashes. Lastly, I had to build a python function to cleanup the output from gemini as it will occasionally output html code or other ASCII characters that bust the unflatten JSON function.

Anyone else taken this path? I would be open to having a conversation on this instead of trying to talk in text. I would like to hear Google’s thoughts on what we are doing, maybe work with us or anyone else doing this? Host a call? 

 

This is what im using and it works well on my playbook: 

PROMPT
You are a SOC analyst reviewing a detection rule, the event/UDM it matched, and the alert generated from it. Your task is to determine which of these 3 outcomes applies: 1. YES - The detection was triggered because of a problem in the rule itself. - The rule is detecting something it should not be detecting due to broad, weak, ambiguous, poorly scoped, or technically misaligned logic. - Use YES only when the rule is technically wrong or misaligned with its own stated intent, independent of customer approval.

What to evaluate: - Does the matched event actually fit the intent of the rule? - Did the rule trigger because of logic that is too broad, ambiguous, poorly scoped, weak, or technically misaligned? - Is the rule matching on fields or text in a way that causes unrelated or benign events to be detected? - Does the event show that the rule is effectively detecting the wrong thing? - Or does the event match the rule correctly, but require customer confirmation before treating it as expected activity?

 

Decision rules: - If the rule is functioning as intended and the event truly matches the intended logic, do not use YES unless the rule logic itself is technically defective. - If the event matches the intended logic of the rule, and the only unresolved question is whether the activity is authorized, expected, allowlisted, approved, or business-justified, classify as VALIDACION. -

Do not classify as YES when the proposed change depends on customer approval, business context, known user behavior, approved travel, approved admin activity, expected process execution, expected country of origin, or any other operational exception that must be confirmed externally. - Country, user, host, IP, process, command line, or business-context exceptions that require client confirmation must be classified as VALIDACION unless the rule logic itself is technically broken. - Use NO when the event matches the rule as designed and still preserves real security value requiring investigation.

Examples of YES: - regex or string match is too broad - rule relies on raw Message text and matches unrelated content - logic is too generic and captures unrelated activity outside the intended detection purpose - conditions are incomplete and miss required technical context - the event technically matches, but not in the way the detection intended

Important: - Focus on whether the rule is wrong or misaligned. - Do not redesign the entire detection strategy. - Be practical and strict. - If Regla requiere afinacion = YES, propose exactly 2 YARA-L level solutions. - The 2 proposed solutions must be concrete and actionable. - Prefer YARA-L native syntax when possible. - The solutions can include things such as: - narrowing a regex - changing the field used for matching - adding a missing condition - excluding a specific benign pattern - tightening scope with product, event type, user, host, process, or other available fields - Do not give more than 2 solutions.

Put each YARA-L solution in its own visual block using this exact structure: <br><hr><br> <code>[YARA-L solution]</code> <br><hr><br> - Each solution must contain only the specific YARA-L fragment to add, replace, or exclude. - Prefer the smallest durable fragment that fixes the benign pattern, not just the single observed instance. - Prefer a generalized pattern when the observed value is clearly one member of a recurring benign family. - Do not overfit the solution to a single hostname, username, suffix, process instance, or country if the same benign behavior is likely to recur with similar values. - Prefer a single line fragment per solution. - If a replacement is needed, provide only the replacement fragment, not the full rewritten rule. - Keep each YARA-L solution short, surgical, and reusable. - The goal is to show exactly what should be adjusted, without regenerating the full detection and without overfitting to one event.

--------------------------------

Whit this prompt, i receive as respones; specific yara pieces that i add to my rule to tune it. And it makes wonders.

The two inputs i use are: 
[Siemplify_Create Gemini Case Summary_1.JsonResult]
[Tools_Get Original Alert Json_1.JsonResult]

And the get original alert json includes the rule itself. So yes, the rule is part of the input


GromeroSec
Forum|alt.badge.img+5
  • Bronze 2
  • May 27, 2026

I like that!.

There is a lot here to digest!

 We have a different workflows, but the central idea looks to be much the same. I am curious how Gemini determines if the issue is a rule tuning problem? do you also pass the full rule on with the prompt? 

I am curious if you have also seen some of the issues that I have seen. If the input is too long, it crashes. I have seen that on threat hunting rules for encrypted powershell. Also we sometimes hit a guardrail for some hashes. Lastly, I had to build a python function to cleanup the output from gemini as it will occasionally output html code or other ASCII characters that bust the unflatten JSON function.

Anyone else taken this path? I would be open to having a conversation on this instead of trying to talk in text. I would like to hear Google’s thoughts on what we are doing, maybe work with us or anyone else doing this? Host a call? 

 

For the crash thing;i configured the gemini action to retry on failure, max number of retries and delay of 5 minutes.
Thats the only way i have found to that.
 

 

Also, i’d tried the same prompt with vertex and diferent models, and i receive less errors. 


mccrilb
Forum|alt.badge.img+12
  • Author
  • Silver 2
  • May 27, 2026

I use the retry also, the crashes Aren’t at that point, the crashes were from the Un-Flatten JSON function. I built a function to clean the gemini output before it hits the unflatten function. 

 


mccrilb
Forum|alt.badge.img+12
  • Author
  • Silver 2
  • May 27, 2026

FYI, I am trying that out, to see what it looks like. One difference I see is that I am treating each alert as separate,  a case can have many types of alerts involved.  If I send the alert data json gemini looks to hit a guardrail.  

 


mccrilb
Forum|alt.badge.img+12
  • Author
  • Silver 2
  • May 27, 2026

FYI, I tried a test case with only one alert in the case and it did work. This is something that I run into with some of my threathunts, large powershell commnd scripts are to just to big to process.   I suspect cases with multiple alerts will also have this issue. 

 


GromeroSec
Forum|alt.badge.img+5
  • Bronze 2
  • May 28, 2026

Yeah

FYI, I tried a test case with only one alert in the case and it did work. This is something that I run into with some of my threathunts, large powershell commnd scripts are to just to big to process.   I suspect cases with multiple alerts will also have this issue. 

 

Yeah, forgot to mention that, the first step for my playbook is to use the action “first alert of the case” to then create a flow condition, and only if it is the first one, then i run the playbook with the gemini action; im counting on the SOAR grouping method to work fine so that i dont run the playbook unnecesary as the focus is to “tune” the yara rule | So to check only the first alert works for me | 


mccrilb
Forum|alt.badge.img+12
  • Author
  • Silver 2
  • June 2, 2026

Here is a workflow I am going to try when I get the chance. it pulls both ideas into a single workflow.

 


GromeroSec
Forum|alt.badge.img+5
  • Bronze 2
  • June 3, 2026

Here is a workflow I am going to try when I get the chance. it pulls both ideas into a single workflow.

 

Amazing ​@mccrilb !! I will check it myself; currently we make this on a separate flow as i couldnt found time to implement it on the soar. 

Also

I will propose an aditional layer that a client suggest and it really makes sense.

A “KB” pre-check;  being the KB a json with “notes” about the events; like: This user is VIP, or this rule have more  impact if happens on the night or something like that. I know that this logic can be added via the rule itself; or even using the “entities” on the SOAR. but to be fair; i dont found them very “reliable” 

So i create a custom action, to read a .json on a server (planning to put them on a private online repo) and add a additional “phase” with custom settings of the client. This works for me because i manage a variety of clients, so i cant crea a “universal” workflow. 

Just talking aloud if you find this idea usefull

Prompt:

You are a SOAR triage assistant. Decide whether the event should be "promoted" or "dismissed" based only on the provided KB notes and the alert summary.

Use the KB as the source of truth. Do not apply generic cybersecurity assumptions. Do not invent missing facts. Do not mention KB notes that are not relevant to the alert.

according only to the KB notes in: [ReadKB.JsonResult]


mccrilb
Forum|alt.badge.img+12
  • Author
  • Silver 2
  • June 4, 2026

“ This user is VIP, or this rule have more  impact if happens on the night or something like that. “ I do something like that in my rule. ($outcomeUserRoleHint) I have data tables that have users titles and departments and I set a flag in the outcome section. In the gemini prompt I have instructions around technical verses non-technical behavior. Each of your clients would have a different data table to check, but the flag and prompt would be the same. I am sure you could also set an after hours flag that way.