Google Cloud Security Command Center Notifications in Slack with Threat Intelligence Enrichment

Stay on top of your Google Cloud security without drowning in alert noise.
In my previous post on the Top 10 Organization Policy Constraints for Google Cloud, I shared the preventive guardrails I recommend to stop risky configurations before they get deployed. But even with solid Organization Policies in place, you still need good visibility into what is already running in your environment. Think of misconfigurations on existing resources, vulnerable packages in your containers or VMs, and active threats detected in your logs.
In Google Cloud, Security Command Center (SCC) is the native tool for this. It brings together findings from Security Health Analytics, Container Threat Detection, Event Threat Detection, and vulnerability scanning in one place.
We see a lot of organizations that have Security Command Center enabled, but nobody is actively looking at the console day to day. A while back, I created a solution on my GitHub (google-cloud-scc-findings-notifications) to push SCC findings straight to a Slack channel using Pub/Sub, a Cloud Run function, and Terraform.
I just updated the repository with a couple of improvements based on what we run into in practice: better filtering and prioritization for CVEs, and IoC and vulnerability enrichment using Google Threat Intelligence (GTI).
What the Alerts Look Like in Slack
Here are two examples from the repo showing what the notifications look like in Slack when GTI enrichment is enabled.
1. Exploitable CVE Alert (CVE-2021-44228 Log4Shell)
A new security finding has been identified: [WIDE EXPLOIT | CRITICAL IMPACT] CVE-2021-44228 (SOFTWARE_VULNERABILITY)
2. Threat Alert with GTI IoC Enrichment (GRIDTIDE / UNC2814 Espionage Campaign)
A new security finding has been identified: Malware: GRIDTIDE Backdoor & SoftEtherVPN C2 (UNC2814)
The Problem with Forwarding Every โHighโ and โCriticalโ Finding
When teams first set up SCC notifications to Slack or email, they usually filter on severity="CRITICAL" OR severity="HIGH" and call it a day. In a real Google Cloud organization, that approach becomes painful pretty quickly:
- CVE alert fatigue: If a base container image or OS package has a CVE rated
HIGHorCRITICAL, SCC will report aVULNERABILITYfinding for every single workload and project where that package is present. Even if the vulnerability has no known exploit in the wild, your Slack channel suddenly gets flooded with hundreds of messages. Before long, engineers mute the channel and miss the alerts that actually matter. - Manual triage work: When Event Threat Detection flags suspicious activity, like outbound traffic to a known command-and-control server or a suspicious binary execution, the raw finding gives you an IP address, domain, or file hash. As a security engineer, your first step is always copying those Indicators of Compromise (IoCs) into VirusTotal or Google Threat Intelligence to see what you are dealing with.
With this update, I wanted the notifier to handle both of those things automatically before the message ever lands in Slack.
What I Updated
1. Better Filtering and CVE Prioritization
First, I updated the Terraform setup to use the SCC v2 Notification API (google_scc_v2_organization_notification_config) at the organization level and tightened the default filter:
(severity="HIGH" OR severity="CRITICAL") AND state="ACTIVE" AND -mute="MUTED" AND ( finding_class!="VULNERABILITY" OR vulnerability.cve.id="" OR ( ( vulnerability.cve.exploitation_activity="WIDE" OR vulnerability.cve.exploitation_activity="AVAILABLE" OR vulnerability.cve.exploitation_activity="CONFIRMED" ) AND ( vulnerability.cve.impact="CRITICAL" OR vulnerability.cve.impact="HIGH" ) ) )
Here is what this filter does:
- All active
HIGHandCRITICALthreats and misconfigurations still come through: Findings from Event Threat Detection (THREAT), Security Health Analytics (MISCONFIGURATION), andTOXIC_COMBINATIONare sent immediately, as long as they areACTIVEand not muted. - CVEs are filtered on actual exploitability: For software vulnerabilities (
VULNERABILITY), you only get paged in Slack when the CVE hasWIDE,AVAILABLE, orCONFIRMEDexploitation activity and aCRITICALorHIGHimpact. That cuts out thousands of theoretical CVEs that are not being exploited. - Organization-wide CVE deduplication: If an exploitable CVE pops up across 40 projects at the same time during a scan, you do not want 40 identical Slack messages. The Cloud Run function now deduplicates repeated alerts for the same CVE across the organization within a configurable cooldown window (
cve_dedup_window_seconds, 1 hour by default), and includes a link to view all affected resources across your organization in SCC. - Actionable CVE details in the message: Each vulnerability alert shows the NVD link, Exploitability, Impact, CVSSv3 score, whether an upstream fix is available, and the exact package version you need to upgrade to.
2. Google Threat Intelligence (GTI) Enrichment
The part I am most excited about in this update is the integration with Google Threat Intelligence (GTI) (powered by Mandiant and VirusTotal threat data).
When you configure a GTI API key, the Cloud Run function automatically queries Google Threat Intelligence and adds a verdict block right inside the Slack notification:
- For CVE findings: It pulls the GTIG Vulnerability Assessment risk rating, priority (for example
P0), exploitation status, EPSS score and percentile, whether it is in the CISA Known Exploited Vulnerabilities (KEV) catalog, known ransomware usage, available mitigations, and the GTIG summary. - For Threat findings (IoCs): When Event Threat Detection triggers an alert containing IP addresses, domains/hostnames, or SHA-256 file hashes, the function checks those indicators against GTI / VirusTotal. Right in Slack, you can see how many security vendors flag the IP, domain, or hash as malicious (for example
MALICIOUS 35/76), the ASN and country of the IP, and whether the indicator belongs to a known threat campaign.
Good to know: the Google Threat Intelligence enrichment is completely optional. If you deploy the notifier without a GTI API key, everything works out of the box and the function simply leaves out the GTI section.
How It Is Built Under the Hood
From an architecture and security perspective, I wanted to keep the setup simple, serverless, and secure by default:
- SCC v2 Notification Config & Pub/Sub: SCC streams matching findings at the organization level to a Pub/Sub topic.
- Eventarc & Cloud Run functions (2nd gen): Eventarc triggers a Python 3.13 Cloud Run function. Ingress on the function is locked down to
ALLOW_INTERNAL_ONLY, and it runs with dedicated, least-privilege service accounts for build and runtime. - Encrypted Secrets with Cloud KMS & Secret Manager: You never put a plaintext Slack bot token or GTI API key in your Git repository or
terraform.tfvars. Stage 1 of the Terraform setup creates a Cloud KMS key so you can encrypt your tokens locally and only pass the base64 ciphertext to Terraform. At deploy time, the secret is stored in Secret Manager and mounted into the function. - Smart Error Handling: Transient issues (like a temporary network error or Slack rate limit) are retried by Eventarc, while permanent configuration issues (like an invalid token or wrong channel ID) are logged once as an
ERRORso the function does not get stuck in an endless retry loop.
Test It Out or Deploy It with Terraform
If you want to see how the messages look in your own Slack channel before rolling out the Terraform code in Google Cloud, you can replay the two sample fixtures directly from your laptop with a single command:
# Replay Demo 1: Log4Shell (CVE-2021-44228) to Slack (with optional GTI_API_KEY)
SLACK_BOT_TOKEN=xoxb-your-token \
SLACK_CHANNEL=C0123456789 \
GTI_API_KEY=your_optional_gti_key \
python3 app/scc-finding-slack-notifications/main.py tests/fixtures/vuln_v2_log4shell_cve_2021_44228.json --send
# Replay Demo 2: UNC2814 / GRIDTIDE Espionage Campaign to Slack (with optional GTI_API_KEY)
SLACK_BOT_TOKEN=xoxb-your-token \
SLACK_CHANNEL=C0123456789 \
GTI_API_KEY=your_optional_gti_key \
python3 app/scc-finding-slack-notifications/main.py tests/fixtures/etd_v2_gridtide_espionage.json --send
Deploying the full pipeline to your Google Cloud organization is done in two short Terraform stages:
# 1. Stage 1: KMS key for encrypting the Slack bot token
cd infra/kms && cp terraform.tfvars.example terraform.tfvars # edit project_id & members
terraform init && terraform apply
# 2. Encrypt the Slack bot token
read -rs SLACK_BOT_TOKEN && export SLACK_BOT_TOKEN
terraform output -raw encrypt_command | sh && unset SLACK_BOT_TOKEN
# 3. Stage 2: Deploy the SCC notification config, Pub/Sub topic, and Cloud Run function
cd .. && cp terraform.tfvars.example terraform.tfvars # edit, paste the ciphertext
terraform init && terraform apply
Get It on GitHub
You can find the full source code, Terraform modules, and documentation on my GitHub repository:
๐ github.com/jorgecalo/google-cloud-scc-findings-notifications
(Using Microsoft Teams instead of Slack? I also updated the Teams version with the same filtering and Google Threat Intelligence enrichment. Read my post on Google Cloud Security Command Center Notifications in Microsoft Teams or grab the code at github.com/jorgecalo/google-cloud-scc-findings-notifications-teams.)
Feel free to reach out via LinkedIn or my contact page if you have any questions, or if you want to test out the Google Threat Intelligence enrichment!

Jorge Liauw Calo
Security Engineer at Google Cloud (Google Cybershield) with 13+ years of experience in Cybersecurity across highly regulated industries including Semiconductor, Banking, Fintech, and Insurance. Active member of the Google Cloud Community BeNeLux and Google Cloud Security Community Amsterdam.