Home / Security

Security Command Center: Findings, Triage & Alerts to Slack/Pub/Sub | 2026

Security Command Center: Findings, Triage & Alerts to Slack/Pub/Sub | 2026

Security Command Center (SCC) continuously scans your GCP organization for misconfigurations, container vulnerabilities, IAM risks, and threat indicators (Event Threat Detection). However, findings sitting silently in the GCP console won't prevent a breach. This guide demonstrates how to configure SCC Notification Configs using Terraform, filter for HIGH and CRITICAL findings, route events via Pub/Sub, and trigger a Python Cloud Run Function that formats rich Slack alert cards with direct remediation links.

By Mateusz Chmielewski · Aug 22, 2026 · 15 min read

What is Security Command Center (SCC)?

Security Command Center (SCC) is GCP's centralized security management and risk reporting platform. It ingests signals from security scanners (Security Health Analytics, Event Threat Detection, Container Threat Detection) and organizes them into actionable Findings.

Think of SCC like a building's central security control room equipped with smoke detectors, motion sensors, and door alarms. When a window is left unlocked (misconfiguration) or an unauthorized intruder enters (threat), the control room immediately flags the room number. Pub/Sub and Slack integrations act as the security officer's walkie-talkie, instantly alerting the responder on duty.

ConceptExplanationWhen to use
FindingA security record representing a vulnerability (e.g. PUBLIC_BUCKET_ACL) or threat (e.g. ANOMALOUS_IAM_GRANT) detected in your GCP environment.Findings are generated automatically by built-in SCC detectors.
Notification ConfigA rule in SCC that automatically streams newly created or updated findings matching a specific SQL-like filter to a Cloud Pub/Sub topic.Deploy at Organization or Folder level for centralized SecOps monitoring.
Finding SeverityClassified into CRITICAL, HIGH, MEDIUM, LOW. Focus automated alerts on CRITICAL and HIGH to eliminate alert noise.Use in Notification Config filters to limit Slack notifications.
Mute RuleRules that automatically mark matching findings as MUTED to prevent benign or accepted risks from triggering alerts.Apply to expected dev/sandbox configurations to suppress noise.

Why Automated SCC Alerting to Slack is Critical

Security findings left unmonitored in the GCP Console often go unnoticed for days or weeks. Without real-time notifications, critical misconfigurations (such as SSH open to `0.0.0.0/0` or exported service account keys) remain exposed to automated internet scanners.

Streaming SCC findings directly to Slack via Pub/Sub and Cloud Run Functions ensures your engineering and security teams receive instant actionable alerts with direct GCP Console deep links, reducing incident response time to seconds.

FeaturethisServicealtAaltB
Detection MechanismSCC: Continuous, agentless security scanningManual Console InspectionThird-Party Cloud Security Posture Management (CSPM)
Notification LatencyReal-time (<15 seconds via Pub/Sub)Days (manual check)15–60 minutes (polling interval)
GCP Native IntegrationDeep native integration across all GCP servicesNative Console UIRequires API keys & service accounts
Remediation GuidanceIncludes explicit GCP compliance & fix stepsBasic finding summaryGeneric remediation advice
Alert FilteringFine-grained CEL/SQL filter expressionsConsole drop-down filtersVendor-specific rules engine

Prerequisites

  • GCP Organization or Project with Security Command Center enabled
  • Terraform CLI v1.6+
  • Cloud Pub/Sub API (`pubsub.googleapis.com`) and Cloud Functions API (`cloudfunctions.googleapis.com`) enabled
  • Slack Workspace with a Webhook URL configured

Step-by-Step Guide

Step 1: Provision Pub/Sub Topic and IAM Permissions for SCC

Create a Cloud Pub/Sub topic to receive SCC findings and grant the SCC service account permission to publish messages. SCC requires `roles/pubsub.publisher` on the target Pub/Sub topic. Without this IAM binding, the notification config will fail silently.

# pubsub_scc.tf — Pub/Sub Topic & SCC Service Identity IAM
resource "google_pubsub_topic" "scc_findings" {
  name    = "scc-high-severity-findings"
  project = var.project_id
}

# Retrieve SCC Organization Service Account
data "google_scc_source" "scc_source" {
  organization = var.org_id
  display_name = "Security Health Analytics"
}

# Grant SCC service agent publisher access to the Pub/Sub topic
resource "google_pubsub_topic_iam_binding" "scc_publisher" {
  topic   = google_pubsub_topic.scc_findings.name
  project = var.project_id
  role    = "roles/pubsub.publisher"

  members = [
    "serviceAccount:service-org-${var.org_id}@gcp-sa-scc.iam.gserviceaccount.com"
  ]
}

Step 2: Configure SCC Notification Config in Terraform

Deploy a `google_scc_notification_config` in Terraform filtering for ACTIVE, CRITICAL or HIGH findings. Filtering at the SCC notification level prevents unnecessary Pub/Sub message execution costs and keeps Slack channels focused solely on high-impact security events.

# scc_notification.tf — Organization-level SCC Notification Config
resource "google_scc_notification_config" "slack_alerts" {
  config_id    = "high-critical-slack-notify"
  organization = var.org_id
  pubsub_topic = google_pubsub_topic.scc_findings.id

  # Filter: Only ACTIVE findings with CRITICAL or HIGH severity
  streaming_config {
    filter = <<EOF
state = "ACTIVE"
AND (severity = "CRITICAL" OR severity = "HIGH")
AND NOT mute = "MUTED"
EOF
  }

  depends_on = [google_pubsub_topic_iam_binding.scc_publisher]
}

Step 3: Write Python Cloud Run Function to Parse SCC Findings

Create a Python 3.11 Cloud Function (2nd Gen) that triggers on Pub/Sub messages, extracts finding details, and formats a Slack incoming webhook payload. Raw SCC JSON payloads are dense. Structuring the Slack message into a clear alert card highlighting Resource Name, Category, Severity, and Direct Remediation Link accelerates engineer triage.

# main.py — Cloud Function Pub/Sub to Slack Handler
import base64
import json
import os
import urllib.request

SLACK_WEBHOOK_URL = os.environ.get("SLACK_WEBHOOK_URL")

def scc_slack_notifier(event, context):
    """Triggered from a message on a Cloud Pub/Sub topic."""
    if 'data' not in event:
        print("No data in Pub/Sub event.")
        return

    pubsub_message = base64.b64decode(event['data']).decode('utf-8')
    payload = json.loads(pubsub_message)
    finding = payload.get("finding", {})

    severity = finding.get("severity", "UNKNOWN")
    category = finding.get("category", "Unspecified Category")
    resource_name = finding.get("resourceName", "Unknown Resource")
    explanation = finding.get("description", "No description provided.")
    external_uri = finding.get("externalUri", "")

    # Color branding based on severity
    color = "#DC2626" if severity == "CRITICAL" else "#F59E0B"

    slack_card = {
        "attachments": [
            {
                "color": color,
                "title": f"🚨 SCC {severity} Finding: {category}",
                "title_link": external_uri,
                "fields": [
                    {"title": "Resource", "value": f"`{resource_name}`", "short": False},
                    {"title": "Explanation", "value": explanation, "short": False},
                    {"title": "State", "value": finding.get("state"), "short": True},
                    {"title": "Event Time", "value": finding.get("eventTime"), "short": True}
                ],
                "footer": "GCP Security Command Center Alert",
                "ts": int(os.path.getmtime(__file__))
            }
        ]
    }

    req = urllib.request.Request(
        SLACK_WEBHOOK_URL,
        data=json.dumps(slack_card).encode('utf-8'),
        headers={'Content-Type': 'application/json'}
    )
    try:
        with urllib.request.urlopen(req) as response:
            print(f"Slack alert sent successfully. Response code: {response.status}")
    except Exception as e:
        print(f"Failed to post to Slack: {e}")

Step 4: Deploy Cloud Run Function with Terraform

Package and deploy the Cloud Run Function (Cloud Functions v2) with Pub/Sub trigger in Terraform. Deploying via Terraform ensures your SecOps alert pipeline infrastructure is version-controlled and reproducible across environments.

# function_scc.tf — Cloud Function 2nd Gen with Pub/Sub Trigger
resource "google_cloudfunctions2_function" "scc_to_slack" {
  name        = "scc-slack-notifier"
  location    = "europe-west1"
  project     = var.project_id
  description = "Routes SCC High & Critical findings to SecOps Slack Channel"

  build_config {
    runtime     = "python311"
    entry_point = "scc_slack_notifier"
    source {
      storage_source {
        bucket = google_storage_bucket.function_code.name
        object = google_storage_bucket_object.code_zip.name
      }
    }
  }

  service_config {
    max_instance_count = 5
    available_memory   = "256Mi"
    timeout_seconds    = 60
    environment_variables = {
      SLACK_WEBHOOK_URL = var.slack_webhook_url
    }
  }

  event_trigger {
    trigger_region = "europe-west1"
    event_type     = "google.cloud.pubsub.topic.v1.messagePublished"
    pubsub_topic   = google_pubsub_topic.scc_findings.id
    retry_policy   = "RETRY_POLICY_DO_NOT_RETRY"
  }
}

Step 5: Test Finding Generation & Verify Slack Delivery

Create a benign security misconfiguration (e.g. a temporary firewall rule allowing all ingress) to trigger an SCC finding and verify Slack receipt. Testing end-to-end alert pipelines verifies that filters, IAM permissions, Pub/Sub delivery, and Slack webhooks are functional before an actual security incident occurs.

# Step 1: Create a test open firewall rule to trigger Security Health Analytics
gcloud compute firewall-rules create test-scc-open-fw \
  --network=default \
  --allow=tcp:22 \
  --source-ranges=0.0.0.0/0 \
  --project=PROJECT_ID

# Step 2: Trigger manual SCC scan (or wait ~10 mins for automated SHA scan)
gcloud scc assets run-discovery --organization=ORG_ID

# Step 3: Verify execution in Cloud Function logs
gcloud functions logs read scc-slack-notifier --region=europe-west1 --limit=10

# Step 4: Clean up test firewall rule immediately!
gcloud compute firewall-rules delete test-scc-open-fw --project=PROJECT_ID --quiet

Step 6: Implement SCC Mute Rules for Noise Suppression

Create an SCC Mute Rule in Terraform to automatically silence findings in staging/dev environments. Alert fatigue is the primary cause of missed critical security events. Muting accepted sandbox findings keeps SecOps channels focused on real threats.

# scc_mute_rule.tf — Mute findings in development project
resource "google_scc_mute_config" "mute_dev_sandbox" {
  mute_config_id = "mute-dev-sandbox-findings"
  organization   = var.org_id
  description    = "Mute all low/medium findings in dev projects"

  filter = <<EOF
resource.project_display_name : "dev-sandbox-*"
AND (severity = "LOW" OR severity = "MEDIUM")
EOF
}

Verification & Health Check

Best Practices

  • Store Slack Webhooks in GCP Secret Manager
  • Filter Out Low Severity and Muted Findings

Common Mistakes

  • {"errorCode":"PUBSUB_PUBLISH_PERMISSION_DENIED","symptoms":"SCC Notification Config created successfully, but no Pub/Sub messages are delivered.","rootCause":"The SCC organization service account was not granted roles/pubsub.publisher on the topic.","fixCommand":"gcloud pubsub topics add-iam-policy-binding TOPIC_NAME --member=serviceAccount:[email protected] --role=roles/pubsub.publisher","code":"resource \"google_pubsub_topic_iam_binding\" \"fix_scc_pub\" {\n topic = google_pubsub_topic.scc_findings.name\n role = \"roles/pubsub.publisher\"\n members = [\"serviceAccount:service-org-${var.org_id}@gcp-sa-scc.iam.gserviceaccount.com\"]\n}\n","language":"hcl","filename":"fix_scc_pubsub.tf","prevention":"Verify the org service account email format using `gcloud scc notification-configs describe`."}

Cost Analysis

Featuremetriccost1kcost10kcost100kcost1m
SCC Standard Tier Scanning$0.00$0.00$0.00$0.00 / month
Pub/Sub Message Ingestion (5k msgs/mo)< $0.01< $0.01< $0.01< $0.10 / yr
Cloud Run Function Executions (256MB RAM)$0.00 (Free Tier)$0.00$0.00$0.00 / month
Total Monthly SecOps Alerting Pipeline Cost~$0.00 / month~$0.00 / month~$0.00 / month~$0.10 / yr

References

Browse all tutorials