はじめに
Security Command Center (SCC) は、Google Cloud 環境全体のセキュリティ状態を一元的に可視化し、管理するためのサービスになります。
設定ミス、脆弱性、脅威、コンプライアンス違反などを自動的に検出してくれます。
SCC は脅威を検知してくれますが、実際に運用するとなるとリアルタイムの通知が必要になるかと思います。
現時点では標準の通知機能はありませんが、Pub/SubやCloud RunといったGoogle Cloud のサービスとSendGridを利用することでメール通知が可能となります。
今回はこちらの実装方法についてご紹介させて頂きます。
概要
今回のシステムは、SCC が検知した脅威を Pub/Sub に送信し、そのイベントを Eventarc が検知して Cloud Run を起動、最終的に SendGrid を利用してメールを送信するという流れです。
- SCC (Security Command Center)
Google Cloud 環境の脅威や脆弱性を検知します。 - Pub/Sub (Publish/Subscribe)
SCC が検知したイベントをリアルタイムで受け取るメッセージングサービスです。 - Eventarc
Pub/Sub にメッセージが発行されたイベントをトリガーとして検知し、Cloud Run を自動的に起動します。 - Cloud Run
Eventarc によって起動されるサーバーレスなコンテナ実行環境です。ここで動作するPythonアプリケーションが、SCC の通知内容を処理し、メールを送信します。 - SendGrid Mail API
信頼性の高いメール送信サービスで、API を通じて簡単にメールを送ることができます。
この連携により、SCC で脅威が検知されると、自動的に詳細情報を含むメールが指定された宛先に届くようになります。
詳細
この自動メール通知システムを構築するための具体的な手順を下記に記載します。
Google Cloud の公式ドキュメントSecurity Command Center のリアルタイム通知を有効にするも参考しています。
1. 通知をパブリッシュする Pub/Sub トピックを作成します。
SCCが検知したセキュリティイベントを送信するための、Pub/Subトピックを作成します。
コマンドに記載の「YOUR_XXX」については適宜読み替えてください。
$ gcloud pubsub topics create YOUR_SCC_TOPIC_NAME $ gcloud pubsub subscriptions create YOUR_SCC_SUBSCRIPTION_NAME --topic YOUR_SCC_TOPIC_NAME
2. Cloud Run サービスの作成
2-1 事前準備
a. SendGrid API キーの Secret Manager への登録
セキュリティのため、SendGrid API キーは Secret Manager に保存し、Cloud Run から安全に参照するようにします。
$ echo "YOUR_SENDGRID_API_KEY" | gcloud secrets create SENDGRID_API_KEY_SECRET --data-file=-
b. Cloud Run 用サービスアカウントの作成と権限付与
サービスアカウントの作成とroles/secretmanager.secretAccessor を付与します。
これにより、Cloud Run サービスが Secret Manager に保存された SendGrid API キーを読み取れるようになります。
$ gcloud iam service-accounts create YOUR_CLOUD_RUN_SERVICE_ACCOUNT_ID \ --description="Service account for Cloud Run SCC Email Notifier" \ --display-name="Cloud Run SCC Email SA"
$ gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \ --member='serviceAccount:SERVICE_ACCOUNT_A_EMAIL' \ --role="roles/secretmanager.secretAccessor"
2-2 Cloud Run サービスのデプロイ
Cloud Runサービス画面の「インライン エディタで関数を作成する」から必要な項目を入力し作成を押下します。
- サービス名
- リージョン
- ランタイム(今回はPython3.13を選択)
- 認証を有効化
- 環境変数(今回は送信先、送信元メールアドレスを環境変数として設定)
- シークレットの参照(SendGrid API キー)
- サービスアカウント(先ほど作成したアカウントを指定)
2-3 ソースコードの設定
デプロイしたCloud Runサービスのソースタブからソースコードをデプロイします。
a. requirements.txt に「sendgrid」「flask」を追記します。
b. 関数のエントリポイントを「handle_pubsub_notification」に変更します。
C. ソースコードを下記内容で保存し、再デプロイを実施します。
※こちら動作確認で利用したものとなります。ご利用頂く際は自己責任でお願い致します。
import base64 import json import os from flask import Flask, request from sendgrid import SendGridAPIClient from sendgrid.helpers.mail import Mail app = Flask(__name__) # --- 環境変数から設定を取得 --- FROM_EMAIL_ADDRESS = os.environ['FROM_EMAIL_ADDRESS'] TO_EMAIL_ADDRESS = os.environ['TO_EMAIL_ADDRESS'] SENDGRID_API_KEY = os.environ['SENDGRID_API_KEY'] @app.route('/', methods=['POST']) def handle_pubsub_notification(request): """ Pub/Sub からのプッシュ通知を受け取り、その内容を解析してSendGridでメールを送信します。 """ envelope = request.get_json() pubsub_message = envelope['message'] message_data = base64.b64decode(pubsub_message['data']).decode('utf-8') scc_notification = json.loads(message_data) subject, body = generate_email_content(scc_notification) message = Mail( from_email=FROM_EMAIL_ADDRESS, to_emails=TO_EMAIL_ADDRESS, subject=subject, plain_text_content=body ) sg = SendGridAPIClient(SENDGRID_API_KEY) sg.send(message) return'', 204 def generate_email_content(scc_notification): """ SCC通知のJSONデータからメールの件名と本文(プレーンテキスト)を生成します。 """ finding = scc_notification.get('finding', {}) category = finding.get('category', 'N/A') state = finding.get('state', 'N/A') severity = finding.get('severity', 'N/A') resource_name = finding.get('resourceName', 'N/A') event_time = finding.get('eventTime', 'N/A') # --- メール件名の生成 --- subject = f"【SCCアラート】 {category} - 重要度: {severity} ({state}) on {resource_name.split('/')[-1]} " # --- メール本文の生成 (プレーンテキスト形式) --- body = f""" * 概要 カテゴリ: {category} 重要度: {severity} ステータス: {state} リソース: {resource_name} 発生日時: {event_time} * 元のSCC通知データ (JSON) {{code}} {json.dumps(scc_notification, indent=2, ensure_ascii=False)} {{/code}} """ return subject, body
補足
SCC の通知は、Pub/Sub を経由して JSON 形式で送られてきます。
その JSON データの中に、finding や asset といった情報が含まれています。
finding オブジェクトの中にカテゴリ、重要度、リソース名などの詳細が含まれています。
必要な情報を抽出し、タイトル・本文に含めるよう適宜修正頂ければと思います。
{ "finding": { "name": "organizations/123/sources/456/findings/abc", "category": "INSECURE_FIREWALL", "state": "ACTIVE", "severity": "HIGH", "resourceName": "//cloudresourcemanager.googleapis.com/projects/your-project-id", "eventTime": "2025-07-09T08:00:00Z", "sourceProperties": { "description": "Firewall rule allows ingress from 0.0.0.0/0 to all ports.", "ipProtocol": "tcp", "port": "all", "ruleName": "allow-all-ingress" }, "securityMarks": { "value": "marks" } // ... その他多くのフィールド ... }, "notificationConfigName": "organizations/123/notificationConfigs/my-notification" }
2-4 Pub/Subトリガーの設定
デプロイしたCloud Runサービスのトリガータブから「Pub/Subトリガー」を選択し、トリガーを作成します。
必要な項目を入力しトリガーを保存を押下します。
- トリガー名
- Pub/Subトピック(1. にて作成したPub/Subトピックを指定する)
- リージョン
- サービスアカウント(roles/eventarc.eventReceiver , roles/pubsub.subscriber, roles/pubsub.subscriber ,roles/run.invoker が付与されたサービスアカウントを別途作成し指定する)
3. Security Command Center Pub/Subエクスポートの作成
Security Command Center の設定画面より継続的エクスポートを選択します。
Pub/Subエクスポートの作成を選択し、必要な項目を入力し保存を押下します。
- エクスポート名
- エクスポートの説明
- エクスポート先
- Pub/Subトピック(1. にて作成したPub/Subトピックを指定する)
- 検出クエリ(フィルタは必要に応じて変更してください)
下記の例では、重大度がCriticalまたはHighのものを検出するクエリになります。
severity="CRITICAL" OR severity="HIGH"
4. メール投稿イメージ
実際に SCC が Google Cloud 環境の脅威や脆弱性を検知するとメールが送信されます。
今回は、弊社で利用しているプロジェクト管理ツールのBacklogにメールを送信し課題を起票する形にしていますがイメージとしてはこのようになります。
まとめ
これで、Security Command Center で脅威が検知されると、自動的に Pub/Sub、Eventarc、Cloud Run を経由し、設定したメールアドレスに SendGrid で詳細な通知メールが送信されるシステムが完成しました。
このシステムを導入することで、Google Cloud 環境のセキュリティ状況をリアルタイムに把握し、迅速な対応を取ることが可能になります。ぜひご自身の環境で試して頂ければ幸いです。