SecOps Dashboard Challenge: Visualize Your Security

We are on a mission to drive the adoption for our Google SecOps Native Dashboard feature, and we want YOU, our amazing community, to lead the charge! Let’s unlock the full potential of this together! We also want you to empower your security operations with the new Native Dashboard, create insightful visualizations and gain better visibility using our out-of-the-box dashboards created by Google SecOps internal team!

This isn't just any contest; it's your chance to shine and help shape the future of SecOps visibility! Your vote matters so be sure to check out the details below on how you can help us determine a winner!

Duration: March 31st - April 30th

Announcement date: Winners will be announced Mid-May 2025

How to Participate

  1. Create a dashboard using the Google SecOps Native Dashboard feature.
  2. Leverage the provided out-of-the-box dashboard samples as a foundation or inspiration. 
  3. Share a screenshot or short video (you may blur out sensitive confidential information) of their dashboard by responding to this post in the Google SecOps community. Please include a brief description of the dashboard's purpose and key visualizations.
  4. Use a specific hashtag (e.g., #SecOpsDashboardChallenge) to facilitate tracking.

To begin exploring dashboards in Google SecOps

  1. Log in to your Google SecOps portal.
  2. Navigate to "Dashboard & Report" in the left-hand menu.
  3. Select "Native Dashboard".
  4. Review the pre-built sample dashboards on the main dashboard pages for inspiration.
  5. Start building your own custom native dashboards.

Resources

  1. Native Dashboard Documentations
  2. Native Dashboards preview in Chronicle SIEM
  3. Native Dashboard Blog Posts

Judging Criteria

We will select three winners based on the following criteria:

  1. Most Creative Dashboard: This will reward innovative and visually appealing dashboards that showcase unique data visualizations or use cases.
  2. Most Liked Dashboard: This is where we need your help Community! The winner will be determined by the number of likes or reactions received, reflecting the community's favorite. Please vote for your favorite dashboards by clicking the like button for each dashboard you like the most.
  3. Most Innovative Dashboard: This will recognize dashboards that demonstrate novel problem-solving, automation, or integration capabilities within the SecOps environment.

Prize

All participants will receive a reward! The 1st place winner will receive 3 swag items, 2nd place will receive 2 swag items, and 3rd place will receive 1 swag item! Once the winner has been determined, we will contact you to ship your prize out!

Example Dashboards

Curated Public Dashboards examples:

suzhuang_0-1743429268027.png

General Security Overview Dashboards

  • Main
  • Web Center Overview

System Health and Data Ingestion Dashboards

  • Data Ingestion and Health
  • Process Event Summary
  • Sysmon Monitoring
Data Security Dashboards
  • Data Loss Prevention (DLP)
  • PCI - Data Encryption

suzhuang_1-1743429289144.png

Identity and Access Management Dashboards

  • User Sign In Overview
  • Multi-Factor Authentication
  • Group Activity Summary
  • PCI - Identity and Access

Cloud Security Dashboards

  • Cloud Posture Overview
  • Google Workspace Alerts
  • Microsoft 365 Alerts

Endpoint Monitoring Dashboards

  • EDR Alerts Overview
  • PCI - EDR Alerts Overview


10 26 76.4K
26 REPLIES 26

@suzhuang This is really great stuff. Thanks for putting this together. Community we are excited to see what you come up with. And we have some fun swag gifts for all that participate and for the winners! Come show off your skills and let's see what you can build! 

SWAGS 👀👀

Great work for end user work inside safety , 

SWAGS 👀👀

 

Yes @Ammar-Abdullah ! Let's see what you got and the swag will start to flow. 

This is exciting! 😎 Just waiting for Native Dashboards to be enabled for my tenant. 🛡

Screenshot 2025-04-15 at 10.12.00.png

Hi @chad-imp! Looking forward to seeing what you create!  

This so cool. Thanks for putting this together. Just a quick clarification for myself and potentially others. Should we just post our screenshot as a reply to this post or make a brand new one?

-Drew

 

Here are some widgets using the Native Dashboards related to different potential threats

Google Workspace Phishing  Pie Chart - 
phishing_widget.png

Less Common Country Heartbeat from CrowdStrike Logs - 
countries.pngMISP Low Confidence Threats by IP

misp_low_conf_threat.png

Great work @Grumbler  I really like the thinking behind tracking endpoint heartbeat locations. 
Imagine tracking endpoint VS user login location and flagging gaps. 

I would also love to hear more about your employee spoofing tracking. I have similar setup using Workspace Alerts on Gmail events but have not dashboarded it yet. 

 

@Grumbler Thanks for your question Drew. Just reply to this post and add your screenshot. Looking forward to seeing what you put together!  

Hello potential participants, we have less than 10 days before the contest is over, I would love to see all the creative dashboards you are putting together! You don't need to use real data, if you have a sample of your own dashboard that would work too! Can't wait to see everyone's dashboard here!

Is there any requirements of how many widgets we need to do?

I do not think so! 

🔐 #SecOpsDashboardChallenge: Google Workspace Native Dashboard

I'm excited to share my submission for the Google Cloud SecOps Native Dashboard Challenge!
My entry focuses on Google Workspace, visualized natively using custom queries to support SecOps workflows.

🧠 Dashboard Overview:

The dashboard is structured into modular sections— Google Workspace and Google Mail with clearly labeled headers and interactive buttons that act as hyperlinks to other native dashboards and admin tools (e.g., Google Admin Log Search, Email Investigation Tool, Google Vault). This enhances usability and integrates triage tools directly into the dashboard experience.

SecOps Native Workspace Dashboard ExampleSecOps Native Workspace Dashboard Example


📊Widget Highlights:

Google Workspace Section

🔍Login Status Over Time

  • Visualizes successful and failed login trends.
  • Helps surface authentication anomalies and brute-force patterns.

 

// User Login Events over time
metadata.event_type = "USER_LOGIN"
$action = security_result.action
$action != 0
$date = timestamp.get_date(metadata.event_timestamp.seconds)
match:
    $action, $date
outcome:
    $event_count = count(metadata.id)
order:
    $date asc

 

👤Google Workspace Admin Events

  • Tracks sensitive admin operations like group modifications or 2FA changes.
  • Bar chart sorted by event count for instant visibility into high-risk activities.

 

// Filter for Google Workspace Admin events
metadata.vendor_name = "Google Workspace"
metadata.product_name = "admin"

// Filter out events o low interest
metadata.event_type != "USER_UNCATEGORIZED" 
metadata.event_type != "STATUS_UNCATEGORIZED" 
metadata.event_type != "GENERIC_EVENT" 
metadata.event_type != "USER_UNCATEGORIZED" 
metadata.event_type != "EMAIL_UNCATEGORIZED"

// Extract event_type field
$event_type = metadata.event_type
//$event_type != "" // Ensure event_type is populated

match:
    $event_type
outcome:
    $event_count = count(metadata.id)
order:
    $event_count desc

 

👥Unique Users in Login Events

  • Real-time metric to gauge daily Unique Login population.

 

// Count of Unique User Login
$event.metadata.event_type = "USER_LOGIN"

outcome:
    $Count = count_distinct($event.principal.user.userid)

 

🧾 Admins by Activity

  • Tracks who is making changes which is useful for detecting ClickOps vs IaC and User vs Service Account.

 

metadata.log_type = "WORKSPACE_ACTIVITY"
metadata.product_name = "admin"
$admin_user = principal.user.email_addresses
$admin_user != ""

match:
  $admin_user

outcome:
  $action_count = count(metadata.id)

order:
  $action_count desc
limit: 10

 

😎Users Created by Whom

  • Help quickly track user creation events over time and identify anomalies.

 

// Who is creating users over time
metadata.log_type = "WORKSPACE_ACTIVITY"
metadata.product_name = "admin"
metadata.event_type = "USER_CREATION"

$actor = principal.user.email_addresses
$actor != ""

$date = timestamp.get_date(metadata.event_timestamp.seconds)

match:
  $date, $actor

outcome:
  $user_creation_count = count(metadata.id)

order:
  $date asc

 

🗺Admin Activity (Non Corp IP) 

  • Tracks Admin activity from non Corp addresses to identify potential anomalies in near real-time.

 

// Admin Activity (Non Corp IP) 
metadata.log_type = "WORKSPACE_ACTIVITY"
metadata.product_name = "admin"
principal.user.email_addresses != /trusteduser/ // Filter out trusted email addresses or service accounts if any

$admin_ip = principal.asset.ip
$admin_ip != ""
$admin_ip != /123.123.123.123/. // Filter out your trusted subnets if any

match:
  $admin_ip

outcome:
  $action_count = count(metadata.id)

order:
  $action_count desc
limit: 10

 


Google Mail Section

⚠️User Phishing Reports & Suspicious Labels

  • Visualizes user-reported phishing attempts and supports investigation into potential emerging threats.

 

// Count phishing report events (User Phishing classification) by hour
metadata.log_type = "WORKSPACE_ACTIVITY"
metadata.product_name = "admin"
metadata.vendor_name = "Google Workspace"
metadata.product_event_type = "SECURITY_CENTER_RULE_THRESHOLD_TRIGGER"
metadata.event_type = "GENERIC_EVENT"

$rule_name = security_result.rule_name
$rule_name = "User Phishing classification"
$event_date = timestamp.get_date(metadata.event_timestamp.seconds) 

match:
    $rule_name, $event_date

outcome:
    $event_count = count(metadata.id)

order:
    $event_date asc

 

✉️Email Trends: Delivery Errors, Labels, and Spam

  • Several widgets show delivery issues, label breakdowns, and spam volumes across dates.
  • One of my favorite widgets charts post-delivery actions (e.g., user-marked spam, Gmail classification changes), giving insight into detection accuracy and user interaction.

 

// Title: Suspicous Gmail Message Labels Over Time
// Description: Visualize email classifications (Spam, Phish, Error, etc.) over time.

metadata.log_type = "WORKSPACE_ACTIVITY"
metadata.product_name = "gmail"
metadata.event_type = "EMAIL_TRANSACTION"

// Extract the label and date
$label = security_result.detection_fields.value
$date = timestamp.get_date(metadata.event_timestamp.seconds)

// Filter: Make sure both are populated
$label = / - /
$label != /Clean/
$label != /clean/
$label != /policy_holder/
$label != ""
$date != ""

match:
    $label, $date

outcome:
    $event_count = count(metadata.id)

order:
    $date asc

 

🔎Filtered Suspicious Emails and Link Domains

  • A table aggregates subject/sender/link domain combinations with counts to quickly pivot into threat hunting or playbook workflows.

 

// Suspicious Email by subject and sender (Filtered View)

metadata.log_type = "WORKSPACE_ACTIVITY"
metadata.product_name = "gmail"
metadata.event_type = "EMAIL_TRANSACTION"

$from = network.email.from
$subject = network.email.subject
$mail_id = network.email.mail_id

$mail_id != ""
$subject != ""

// Build your filters!

$from != ""
(   
    $from != /COMPANY_DOMAIN/ AND
    $from != /TRUSTED SENDERS/ AND
 )

// Suspicious words in subject - examples below, my list was longer.
($subject = /password/ nocase or
 $subject = /update/ nocase or
 $subject = /verify/ nocase or
 $subject = /security/ nocase or
 $subject = /urgent/ nocase or 
 $subject = /Account/ nocase or

match:
    $subject, $from

outcome:
    $phish_subject_email_count = count_distinct($mail_id)

order:
    $phish_subject_email_count desc
limit:
    20

 

🚩Top Reported Email Domains

  • Give us a quick view of which email senders our Users are reporting the most so that we can take action. 

 

// Gmail messages with specific user actions or reclassifications
metadata.vendor_name = "Google Workspace"
metadata.product_name = "gmail"
metadata.log_type = "WORKSPACE_ACTIVITY"
metadata.event_type = "EMAIL_TRANSACTION"

// Extract needed fields
$label = about.labels.value
$message_id = network.email.mail_id
$sender = network.email.from

// Ensure fields are populated
$label != ""
$message_id != ""
$sender != "" and $sender != /allowlist-senders/ //update this to your needs

// Match labels 69 o 70 and 71 based on description
(
    $label = /69 - / or
    $label = /70 - / //and
    //$label = /71 - /
)

match:
    $sender

outcome:
    $unique_message_count = count_distinct($message_id)

order:
    $unique_message_count desc

 

 


⚙️Behind the Scenes

  • All visualizations are built using native Dashboards YARA-L queries.
  • I plan to share a GitHub repo soon with my complete query set.

Please feel free to comment and suggest ideas! 
Thanks

This is great Chad 😅

Thank you @Grumbler

I built a custom 🤖 GPT and trained it on YARA-L for SecOps Native which I plan to publish soon on Github. You basically feed it sanitized UDM events and then let it construct searches. 

Would something like interest the community? 📰

Show More
I must admit that without training, most GPT's I tested struggled with YARA-L queries for Native Dashboards. 

 

You should totally add these dbs to the community github. I would be interested on how you trained this personally

This is awesome! I would love to see your Github link once you have that available! 

Awesome work, amazing to see how you leveraged Native Dashboard to track data from Google Workspace!!👏

#SecOps Dashboard Challenge

Dashboard Name: MITRE Threat Matrix View

The MITRE Threat Matrix View dashboard is organized to provide comprehensive visibility into adversary behavior using the MITRE ATT&CK framework. Each tactic from the matrix is represented with two dedicated panels, offering both quantitative and contextual analysis of triggered detection rules.

CyberChamp_0-1746024651228.png

 

CyberChamp_1-1746024651337.png

 

CyberChamp_2-1746024651225.png

 

 

Panel Breakdown:

Tactic:

Purpose: Displays the count and details of security rules that were triggered under the specific MITRE tactic.

Insight Provided: Helps analysts understand which detection rules are being actively engaged for a given tactic, highlighting areas of active threat activity or potential false positives.

Query:

 

detection.detection.rule_name = $rule_name
detection.detection.outcomes["mitre_attack_tactic"] = /Execution/ nocase
detection.detection.outcomes["mitre_attack_technique"]  != ""

outcome:
    $Rule_Count = count_distinct($rule_name)

 

Technique:

Purpose: Visualizes the distribution of triggered rules across the techniques under the given tactic.

Insight Provided: Offers a granular view into which specific techniques (e.g., Credential Dumping, Lateral Movement) are being observed most often, helping pinpoint attack patterns.

Query:

 

detection.detection.rule_name = $rule_name
detection.detection.outcomes["mitre_attack_tactic"] = /Execution/ nocase
detection.detection.outcomes["mitre_attack_technique"]  != ""
detection.detection.outcomes["mitre_attack_technique"] = $technique

match:
    $technique, $rule_name

outcome:
    $Rule_Count = count_distinct($rule_name)

 

Dashboard Name: Overview Dashboard

CyberChamp_3-1746024651223.png

 

Query:

 

Panel Name: Avg GB Ingested per Day
// Filter events to those from the "Ingestion API" component
ingestion.component="Ingestion API" 

// Extract the date from the ingestion start time
$date = timestamp.get_date(ingestion.start_time)

// Calculate the total log volume in gigabytes (GB) for each date, rounded to 3 decimal places
outcome:
    $number_days = count_distinct(timestamp.get_date(ingestion.start_time))
    $log_volume = math.round(sum(ingestion.log_volume) / 1073741824,3)  
    $per_day = math.round($log_volume / $number_days,3)
    // 1073741824 bytes = 1 GB

Panel Name: Total GB Ingested
// Filter events to those from the "Ingestion API" component
ingestion.component="Ingestion API" 

// Calculate the total log volume in gigabytes (GB) for each date, rounded to 3 decimal places
outcome:
    $log_volume = math.round(sum(ingestion.log_volume) / 1073741824,3)  
    // 1073741824 bytes = 1 GB

Panel Name: Ingestion Metrics by Date & Logs

$log_type = ingestion.log_type AND $log_type != ""
ingestion.component = "Ingestion API"
ingestion.log_type != "" AND ingestion.log_type != "FORWARDER_HEARTBEAT"
$date = timestamp.get_date(ingestion.start_time) AND ingestion.start_time != 0
match:
    $date, $log_type
outcome:
    $thoughput = math.round(sum(ingestion.log_volume) / (1000 * 1000 * 1000), 1)

 

CyberChamp_4-1746024651253.png

 

Query:

 

Panel Name: Detections

detection.detection.rule_name = /.*/
outcome:
$detections = count(detection.id)

Panel Name: Rule Detection by Severity

$severity = detection.detection.rule_labels["severity"]
$severity != ""
match:
   $severity

Panel Name: Rules Detection by Severity Over Time

$severity = detection.detection.rule_labels["severity"]
$severity != ""
$detection_time = timestamp.get_date(detection.detection_time.seconds)
match:
   $severity, $detection_time
outcome:
   $count = count_distinct(detection.id)

order:
    $detection_time

outcome:
   $count = count_distinct(detection.id)

 

 
CyberChamp_5-1746024651221.png

 

Query:

 

Panel Name: Rule detection over time

$date = timestamp.get_date(detection.detection_time.seconds)
match:
    $date
outcome:
    $total=count_distinct(detection.id)
order:
    $date

Panel Name: Top 10 Rule Names by Detections

$rulename = detection.detection.rule_name
match:
    $rulename
outcome:
    $detection_count = count_distinct(detection.id)
order:
    $detection_count desc
limit:
    10

 

CyberChamp_6-1746024651451.png

 

Query:
 

 

Panel Name: Top 10 IOC Matches

ioc.category != ""
ioc.category = $category
match:
$category
outcome:
$ioc_matches = count(ioc.category)
order:
  $ioc_matches desc

Panel Name: IOC type

ioc.ioc_type = $ioc_type
match:
    $ioc_type

outcome:
    $ioc_matches = count(ioc.ioc_type)
order:
    $ioc_matches desc

Panel Name: IOC IPs

ioc.ioc_value != ""
ioc.ioc_value = $ioc_value_ip
ioc.ioc_type = "IOC_TYPE_IP"
match:
    $ioc_value_ip

outcome:
    $ioc_matches = count(ioc.ioc_value)
order:
    $ioc_matches desc

Panel Name: IOC DOMAIN

ioc.ioc_value != ""
ioc.ioc_value = $ioc_value_domain
ioc.ioc_type = "IOC_TYPE_DOMAIN"
match:
    $ioc_value_domain

outcome:
    $ioc_matches = count(ioc.ioc_value)
order:
    $ioc_matches desc

Panel Name: IOC Matches By Category

ioc.ioc_type = $ioc_type
ioc.category = $ioc_category
match:
    $ioc_category, $ioc_type
outcome:
    $ioc_matches = count(ioc.category)
order:
    $ioc_matches desc

Panel Name: IOC Matches By Domain

ioc.ioc_value = $ioc_value_domain
ioc.ioc_type = "IOC_TYPE_DOMAIN"
ioc.category = $ioc_category
ioc.severity = $ioc_severity
match:
    $ioc_value_domain, $ioc_category, $ioc_severity

 

Thanks.

I love the detection panel you built!! This is awesome!

@Grumbler @chad-imp @CyberChamp This is great stuff! Thank you all for submitting your example dashboards and extra scripts. Adding this to Github is an EXCELLENT idea! More swag for that too! 

A HUGE thank you to all that participated in our SecOps Dashboard Challenge! 

We're going to close this post and ask that the Community selects which dashboards they like the best by adding a thumbs up. At the end of two weeks, the post with the most likes will claim top rank for this contest. Excited to see who you choose! 

But if you have time this weekend...👀 

#SecOps Dashboard Challenge

I have created a GCP Dashboard that shows:

  1. Access denied events by account for finding config errors and other anomalies. 
  2. Failed Logins by Application to detect auth anomaly trends by Application. 
  3. GCP resources that we ingest logs for so that we know what we have in the system. 
  4. GCP Projects over time that are encountering failures to find anomalies. 

unnamed.png

 

 

// Title: Top Resources Triggering Access Denied Events
// Description: Counts access denied events grouped by resource name and type to highlight frequent targets.

// Filter for GCP Audit logs
metadata.log_type = "GCP_CLOUDAUDIT"

// Focus only on BLOCK actions
$action = security_result.action
$action = "BLOCK"

// Extract fields
$resource_name = target.resource.name
$resource_name != ""

$resource_type = target.resource.resource_type
$resource_type != 0

// Extract event date (optional for time series)
$date = timestamp.get_date(metadata.event_timestamp.seconds)
$date != ""

// Group by resource name and resource type
match:
    $resource_name, $resource_type, $date

outcome:
    $denied_count = count(metadata.id)

order:
    $denied_count desc
limit: 50

 

 

A big thank you to everyone who participated in our first ever contest! We're thrilled by the response. Get ready for (more) exciting new features coming soon to Native Dashboard - stay tuned for announcements! The community and product teams will announce the winner next week. Thanks again for being a part of it! ❤️