通知構成の作成と管理

このページでは、次のような例について、Security Command Center API の通知機能の使用方法を説明します。

  • NotificationConfig の作成
  • NotificationConfig の取得
  • NotificationConfig の更新
  • NotificationConfig の削除
  • NotificationConfig の一覧表示
  • Pub/Sub 通知の受信

また、Security Command Center プレミアムのお客様には、Security Command Center ダッシュボードで Pub/Sub の継続的エクスポートを設定する方法もあります。

始める前に

このページの例を使用するには、検出通知の設定のガイドを完了する必要があります。

以降の例を実行するには、適切な権限を持つ Identity and Access Management(IAM)ロールが必要です。

  • NotificationConfig の作成: セキュリティ センター通知構成編集者(roles/securitycenter.notificationConfigEditor
  • NotificationConfig の取得と一覧表示: セキュリティ センター通知構成閲覧者(roles/securitycenter.notificationConfigViewer)またはセキュリティ センター通知構成編集者(roles/securitycenter.notificationConfigEditor
  • NotificationConfig の更新と削除: セキュリティ センター通知編集者(roles/securitycenter.notificationConfigEditor

notificationConfig にアクセスするプリンシパルに適切なロールを付与するには、次のいずれかの IAM ロールが必要です。

  • 組織管理者(roles/resourcemanager.organizationAdmin
  • フォルダ IAM 管理者(roles/resourcemanager.folderIamAdmin
  • プロジェクト IAM 管理者(roles/resourcemanager.projectIamAdmin

Security Command Center の IAM ロールは、組織レベル、フォルダレベル、またはプロジェクト レベルで付与できます。検出結果、アセット、セキュリティ ソースを表示、編集、作成、更新する権限は、アクセス権が付与されているレベルによって異なります。Security Command Center のロールの詳細については、アクセス制御をご覧ください。

データ所在地と通知

Security Command Center でデータ所在地が有効になっている場合、Pub/Sub(notificationConfig リソース)への継続的なエクスポートを定義する構成はデータの対象であり、Security Command Center のロケーションに保存されます。

Security Command Center のロケーションの検出結果を Pub/Sub にエクスポートするには、検出結果と同じ Security Command Center のロケーションに継続的なエクスポートを構成する必要があります。

継続的なエクスポートで使用されるフィルタには、所在地管理の対象となるデータが含まれる可能性があるため、作成する前に正しいロケーションを指定していることを確認してください。Security Command Center では、エクスポートを作成するロケーションは制限されません。

継続的エクスポートは作成場所にのみ保存され、他のロケーションで表示や編集はできません。

継続的なエクスポートを作成した後に、そのロケーションを変更することはできません。ロケーションを変更するには、継続的なエクスポートを削除して、新しいロケーションに再作成する必要があります。

API 呼び出しを使用して継続的なエクスポートを取得するには、notificationConfig の完全なリソース名でロケーションを指定する必要があります。次に例を示します。

GET https://securitycenter.googleapis.com/v2/{name=organizations/123/locations/eu/notificationConfigs/my-pubsub-export-01}

同様に、gcloud CLI を使用して継続的なエクスポートを取得するには、構成の完全なリソース名または --locations フラグを使用してロケーションを指定する必要があります。次に例を示します。

gcloud scc notifications describe myContinuousExport organizations/123 \
    --location=locations/us

NotificationConfig の作成

NotificationConfig を作成するには、次のものが必要です。

  • 通知の送信先にする既存の Pub/Sub トピック。
  • notificationConfig を作成するプリンシパルに必要な IAM ロール。

詳細については、検出通知の設定ガイドの Pub/Sub トピックを設定する手順をご覧ください。

NotificationConfig を作成する前に、各組織で保持できる NotificationConfig ファイルの数に上限があることを確認してください。詳細については、割り当てと上限をご覧ください。

NotificationConfig には、通知を有用なイベントに限定する filter フィールドが含まれています。このフィールドは、Security Command Center API の findings.list メソッドで使用できるすべてのフィルタを受け入れます。

NotificationConfig を作成する場合は、Google Cloud リソース階層(組織、フォルダ、プロジェクトのいずれか)から NotificationConfig の親を指定します。後で NotificationConfig を取得、更新、削除する必要がある場合は、参照時に親の組織、フォルダ、またはプロジェクトの数値 ID を指定する必要があります。

任意の言語やプラットフォームを使用して NotificationConfig を作成するには:

gcloud

gcloud scc notifications create NOTIFICATION_NAME \
--PARENT=PARENT_ID \
--location=LOCATION
--description="NOTIFICATION_DESCRIPTION" \
--pubsub-topic=PUBSUB_TOPIC \
--filter="FILTER"

次のように置き換えます。

  • NOTIFICATION_NAME: 通知の名前。 1~128 文字で、英数字、アンダースコア、ハイフンのみを使用できます。
  • PARENT: 通知が適用されるリソース階層内の範囲(organizationfolder、または project)。
  • PARENT_ID: 親組織、フォルダ、またはプロジェクトの ID。organizations/123folders/456projects/789 の形式で指定します。
  • LOCATION: データ所在地が有効になっている場合は、通知を作成する Security Command Center のロケーションを指定します。結果の notificationConfig リソースは、この場所にのみ保存されます。このロケーションで発行された検出結果のみが Pub/Sub に送信されます。

    データ所在地が有効になっていない場合、--location フラグを指定すると、Security Command Center API v2 を使用して通知が作成されます。フラグの有効な値は global のみです。

  • NOTIFICATION_DESCRIPTION: 通知の説明(1,024 文字以内)。

  • PUBSUB_TOPIC: 通知を受け取る Pub/Sub トピック。形式は projects/PROJECT_ID/topics/TOPIC です。

  • FILTER: Pub/Sub に送信する検出結果を選択するために定義する式。例: state="ACTIVE"

Python

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。

def create_notification_config(parent_id, notification_config_id, pubsub_topic):
    """
    Args:
        parent_id: must be in one of the following formats:
            "organizations/{organization_id}"
            "projects/{project_id}"
            "folders/{folder_id}"
        notification_config_id: "your-config-id"
        pubsub_topic: "projects/{your-project-id}/topics/{your-topic-ic}"

    Ensure this ServiceAccount has the "pubsub.topics.setIamPolicy" permission on the new topic.
    """
    from google.cloud import securitycenter as securitycenter

    client = securitycenter.SecurityCenterClient()

    created_notification_config = client.create_notification_config(
        request={
            "parent": parent_id,
            "config_id": notification_config_id,
            "notification_config": {
                "description": "Notification for active findings",
                "pubsub_topic": pubsub_topic,
                "streaming_config": {"filter": 'state = "ACTIVE"'},
            },
        }
    )

    print(created_notification_config)

Java

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。


import com.google.cloud.securitycenter.v1.CreateNotificationConfigRequest;
import com.google.cloud.securitycenter.v1.NotificationConfig;
import com.google.cloud.securitycenter.v1.NotificationConfig.StreamingConfig;
import com.google.cloud.securitycenter.v1.SecurityCenterClient;
import java.io.IOException;

public class CreateNotificationConfigSnippets {

  public static void main(String[] args) throws IOException {
    // parentId: must be in one of the following formats:
    //    "organizations/{organization_id}"
    //    "projects/{project_id}"
    //    "folders/{folder_id}"
    String parentId = String.format("organizations/%s", "ORG_ID");
    String notificationConfigId = "{config-id}";
    String projectId = "{your-project}";
    String topicName = "{your-topic}";

    createNotificationConfig(parentId, notificationConfigId, projectId, topicName);
  }

  // Crete a notification config.
  // Ensure the ServiceAccount has the "pubsub.topics.setIamPolicy" permission on the new topic.
  public static NotificationConfig createNotificationConfig(
      String parentId, String notificationConfigId, String projectId, String topicName)
      throws IOException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the "close" method on the client to safely clean up any remaining background resources.
    try (SecurityCenterClient client = SecurityCenterClient.create()) {

      // Ensure this ServiceAccount has the "pubsub.topics.setIamPolicy" permission on the topic.
      String pubsubTopic = String.format("projects/%s/topics/%s", projectId, topicName);

      CreateNotificationConfigRequest request =
          CreateNotificationConfigRequest.newBuilder()
              .setParent(parentId)
              .setConfigId(notificationConfigId)
              .setNotificationConfig(
                  NotificationConfig.newBuilder()
                      .setDescription("Java notification config")
                      .setPubsubTopic(pubsubTopic)
                      .setStreamingConfig(
                          StreamingConfig.newBuilder().setFilter("state = \"ACTIVE\"").build())
                      .build())
              .build();

      NotificationConfig response = client.createNotificationConfig(request);
      System.out.printf("Notification config was created: %s%n", response);
      return response;
    }
  }
}

Go

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。

import (
	"context"
	"fmt"
	"io"

	securitycenter "cloud.google.com/go/securitycenter/apiv1"
	"cloud.google.com/go/securitycenter/apiv1/securitycenterpb"
)

func createNotificationConfig(w io.Writer, orgID string, pubsubTopic string, notificationConfigID string) error {
	// orgID := "your-org-id"
	// pubsubTopic := "projects/{your-project}/topics/{your-topic}"
	// notificationConfigID := "your-config-id"

	ctx := context.Background()
	client, err := securitycenter.NewClient(ctx)

	if err != nil {
		return fmt.Errorf("securitycenter.NewClient: %w", err)
	}
	defer client.Close()

	req := &securitycenterpb.CreateNotificationConfigRequest{
		// Parent must be in one of the following formats:
		//		"organizations/{orgId}"
		//		"projects/{projectId}"
		//		"folders/{folderId}"
		Parent:   fmt.Sprintf("organizations/%s", orgID),
		ConfigId: notificationConfigID,
		NotificationConfig: &securitycenterpb.NotificationConfig{
			Description: "Go sample config",
			PubsubTopic: pubsubTopic,
			NotifyConfig: &securitycenterpb.NotificationConfig_StreamingConfig_{
				StreamingConfig: &securitycenterpb.NotificationConfig_StreamingConfig{
					Filter: `state = "ACTIVE"`,
				},
			},
		},
	}

	notificationConfig, err := client.CreateNotificationConfig(ctx, req)
	if err != nil {
		return fmt.Errorf("Failed to create notification config: %w", err)
	}
	fmt.Fprintln(w, "New NotificationConfig created: ", notificationConfig)

	return nil
}

Node.js

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。

// npm install '@google-cloud/security-center'
const {SecurityCenterClient} = require('@google-cloud/security-center');

const client = new SecurityCenterClient();

// parent: must be in one of the following formats:
//    `organizations/${organization_id}`
//    `projects/${project_id}`
//    `folders/${folder_id}`
// configId = "your-config-name";
// pubsubTopic = "projects/{your-project}/topics/{your-topic}";
// Ensure this Service Account has the "pubsub.topics.setIamPolicy" permission on this topic.
const parent = `organizations/${organizationId}`;

async function createNotificationConfig() {
  const [response] = await client.createNotificationConfig({
    parent: parent,
    configId: configId,
    notificationConfig: {
      description: 'Sample config for node.js',
      pubsubTopic: pubsubTopic,
      streamingConfig: {filter: 'state = "ACTIVE"'},
    },
  });
  console.log('Notification config creation succeeded: ', response);
}

createNotificationConfig();

PHP

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。

use Google\Cloud\SecurityCenter\V1\Client\SecurityCenterClient;
use Google\Cloud\SecurityCenter\V1\CreateNotificationConfigRequest;
use Google\Cloud\SecurityCenter\V1\NotificationConfig;
use Google\Cloud\SecurityCenter\V1\NotificationConfig\StreamingConfig;

/**
 * @param string $organizationId        Your org ID
 * @param string $notificationConfigId  A unique identifier
 * @param string $projectId             Your Cloud Project ID
 * @param string $topicName             Your topic name
 */
function create_notification(
    string $organizationId,
    string $notificationConfigId,
    string $projectId,
    string $topicName
): void {
    $securityCenterClient = new SecurityCenterClient();
    // 'parent' must be in one of the following formats:
    //		"organizations/{orgId}"
    //		"projects/{projectId}"
    //		"folders/{folderId}"
    $parent = $securityCenterClient::organizationName($organizationId);
    $pubsubTopic = $securityCenterClient::topicName($projectId, $topicName);

    $streamingConfig = (new StreamingConfig())->setFilter('state = "ACTIVE"');
    $notificationConfig = (new NotificationConfig())
        ->setDescription('A sample notification config')
        ->setPubsubTopic($pubsubTopic)
        ->setStreamingConfig($streamingConfig);
    $createNotificationConfigRequest = (new CreateNotificationConfigRequest())
        ->setParent($parent)
        ->setConfigId($notificationConfigId)
        ->setNotificationConfig($notificationConfig);

    $response = $securityCenterClient->createNotificationConfig($createNotificationConfigRequest);
    printf('Notification config was created: %s' . PHP_EOL, $response->getName());
}

Ruby

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。

require "google/cloud/security_center"

# Your organization id. e.g. for "organizations/123", this would be "123".
# org_id = "YOUR_ORGANZATION_ID"

# Your notification config id. e.g. for
# "organizations/123/notificationConfigs/my-config" this would be "my-config".
# config_id = "YOUR_CONFIG_ID"

# The PubSub topic where notifications will be published.
# pubsub_topic = "YOUR_TOPIC"

client = Google::Cloud::SecurityCenter.security_center

# You can also use 'project_id' or 'folder_id' as a parent.
# client.project_path project: project_id
# client.folder_path folder: folder_id
parent = client.organization_path organization: org_id

notification_config = {
  description:      "Sample config for Ruby",
  pubsub_topic:     pubsub_topic,
  streaming_config: { filter: 'state = "ACTIVE"' }
}

response = client.create_notification_config(
  parent:              parent,
  config_id:           config_id,
  notification_config: notification_config
)
puts "Created notification config #{config_id}: #{response}."

C#

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。


using Google.Api.Gax.ResourceNames;
using Google.Cloud.SecurityCenter.V1;
using System;

///<summary> Create NotificationConfig Snippet. </summary>
public class CreateNotificationConfigSnippets
{
    public static NotificationConfig CreateNotificationConfig(
        string organizationId, string notificationConfigId, string projectId, string topicName)
    {
        // You can also use 'projectId' or 'folderId' instead of the 'organizationId'.
        //      ProjectName projectName = new ProjectName(projectId);
        //      FolderName folderName = new FolderName(folderId);
        OrganizationName orgName = new OrganizationName(organizationId);
        TopicName pubsubTopic = new TopicName(projectId, topicName);

        SecurityCenterClient client = SecurityCenterClient.Create();
        CreateNotificationConfigRequest request = new CreateNotificationConfigRequest
        {
            ParentAsOrganizationName = orgName,
            ConfigId = notificationConfigId,
            NotificationConfig = new NotificationConfig
            {
                Description = ".Net notification config",
                PubsubTopicAsTopicName = pubsubTopic,
                StreamingConfig = new NotificationConfig.Types.StreamingConfig { Filter = "state = \"ACTIVE\"" }
            }
        };

        NotificationConfig response = client.CreateNotificationConfig(request);
        Console.WriteLine($"Notification config was created: {response}");
        return response;
    }
}

これで、指定した Pub/Sub トピックに通知がパブリッシュされるようになりました。

通知をパブリッシュするため、サービス アカウントが service-org-ORGANIZATION_ID@gcp-sa-scc-notification.iam.gserviceaccount.com の形式で作成されます。このサービス アカウントは、最初の NotificationConfig を作成するときに作成され、通知構成の作成時に PUBSUB_TOPIC の IAM ポリシーに対する securitycenter.notificationServiceAgent ロールが自動的に付与されます。通知が機能するには、このサービス アカウントのロールが必要です。

NotificationConfig の取得

NotificationConfig を取得するには、securitycenter.notification.get 権限を含む IAM ロールが必要です。

gcloud

gcloud scc notifications describe PARENT_TYPE/PARENT_ID/locations/LOCATION/notificationConfigs/NOTIFICATION_NAME

次のように置き換えます。

  • PARENT_TYPE は、通知構成で指定されたリソース階層のレベルに応じて organizationsfoldersprojects のいずれかに置き換えます。
  • PARENT_ID は親リソースの数値 ID に置き換えます。
  • LOCATION: データ所在地が有効になっているか、notificationConfig リソースが API v2 を使用して作成されている場合は必須です。

    データ所在地が有効になっている場合は、通知が保存される Security Command Center のロケーションを指定します。

    データ所在地が有効になっていない場合、Security Command Center API v2 を使用して、notificationConfig リソースが作成された場合 /locations/LOCATION のみを含めます。この場合、唯一の有効な場所が global です。

  • NOTIFICATION_NAME: 通知の名前。

Python

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。

def get_notification_config(parent_id, notification_config_id):
    """
    Args:
        parent_id: must be in one of the following formats:
            "organizations/{organization_id}"
            "projects/{project_id}"
            "folders/{folder_id}"
        notification_config_id: "your-config-id"
    """
    from google.cloud import securitycenter as securitycenter

    client = securitycenter.SecurityCenterClient()

    notification_config_name = (
        f"{parent_id}/notificationConfigs/{notification_config_id}"
    )

    notification_config = client.get_notification_config(
        request={"name": notification_config_name}
    )
    print(f"Got notification config: {notification_config}")

Java

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。


import com.google.cloud.securitycenter.v1.NotificationConfig;
import com.google.cloud.securitycenter.v1.SecurityCenterClient;
import java.io.IOException;

public class GetNotificationConfigSnippets {

  public static void main(String[] args) throws IOException {
    // parentId: must be in one of the following formats:
    //    "organizations/{organization_id}"
    //    "projects/{project_id}"
    //    "folders/{folder_id}"
    String parentId = String.format("organizations/%s", "ORG_ID");

    String notificationConfigId = "{config-id}";

    getNotificationConfig(parentId, notificationConfigId);
  }

  // Retrieve an existing notification config.
  public static NotificationConfig getNotificationConfig(
      String parentId, String notificationConfigId) throws IOException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the "close" method on the client to safely clean up any remaining background resources.
    try (SecurityCenterClient client = SecurityCenterClient.create()) {
      NotificationConfig response =
          client.getNotificationConfig(String.format("%s/notificationConfigs/%s",
              parentId, notificationConfigId));

      System.out.printf("Notification config: %s%n", response);
      return response;
    }
  }
}

Go

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。

import (
	"context"
	"fmt"
	"io"

	securitycenter "cloud.google.com/go/securitycenter/apiv1"
	"cloud.google.com/go/securitycenter/apiv1/securitycenterpb"
)

func getNotificationConfig(w io.Writer, orgID string, notificationConfigID string) error {
	// orgID := "your-org-id"
	// notificationConfigID := "your-config-id"

	ctx := context.Background()
	client, err := securitycenter.NewClient(ctx)

	if err != nil {
		return fmt.Errorf("securitycenter.NewClient: %w", err)
	}
	defer client.Close()

	// Parent must be in one of the following formats:
	//		"organizations/{orgId}"
	//		"projects/{projectId}"
	//		"folders/{folderId}"
	parent := fmt.Sprintf("organizations/%s", orgID)
	req := &securitycenterpb.GetNotificationConfigRequest{
		Name: fmt.Sprintf("%s/notificationConfigs/%s", parent, notificationConfigID),
	}

	notificationConfig, err := client.GetNotificationConfig(ctx, req)
	if err != nil {
		return fmt.Errorf("Failed to retrieve notification config: %w", err)
	}
	fmt.Fprintln(w, "Received config: ", notificationConfig)

	return nil
}

Node.js

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。

// npm install @google-cloud/security-center/
const {SecurityCenterClient} = require('@google-cloud/security-center');

const client = new SecurityCenterClient();

// formattedConfigName: You can also use
//    `client.projectNotificationConfigPath(projectId, configId)` or
//    `client.folderNotificationConfigPath(folderId, configId)`.
// configId = "your-config-id";
const formattedConfigName = client.organizationNotificationConfigPath(
  organizationId,
  configId
);

async function getNotificationConfg() {
  const [response] = await client.getNotificationConfig({
    name: formattedConfigName,
  });
  console.log('Notification config: ', response);
}

getNotificationConfg();

PHP

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。

use Google\Cloud\SecurityCenter\V1\Client\SecurityCenterClient;
use Google\Cloud\SecurityCenter\V1\GetNotificationConfigRequest;

/**
 * @param string $organizationId        Your org ID
 * @param string $notificationConfigId  A unique identifier
 */
function get_notification(string $organizationId, string $notificationConfigId): void
{
    $securityCenterClient = new SecurityCenterClient();
    $notificationConfigName = $securityCenterClient::notificationConfigName(
        // You can also use 'projectId' or 'folderId' instead of the 'organizationId'.
        $organizationId,
        $notificationConfigId
    );
    $getNotificationConfigRequest = (new GetNotificationConfigRequest())
        ->setName($notificationConfigName);

    $response = $securityCenterClient->getNotificationConfig($getNotificationConfigRequest);
    printf('Notification config was retrieved: %s' . PHP_EOL, $response->getName());
}

Ruby

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。

require "google/cloud/security_center"

# Your organization id. e.g. for "organizations/123", this would be "123".
# org_id = "YOUR_ORGANZATION_ID"

# Your notification config id. e.g. for
# "organizations/123/notificationConfigs/my-config" this would be "my-config".
# config_id = "YOUR_CONFIG_ID"

client = Google::Cloud::SecurityCenter.security_center

# You can also use 'project_id' or 'folder_id' as a parent.
config_path = client.notification_config_path organization:        org_id,
                                              notification_config: config_id

response = client.get_notification_config name: config_path
puts "Notification config fetched: #{response}"

C#

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。


using Google.Cloud.SecurityCenter.V1;
using System;

/// <summary>Snippet for GetNotificationConfig</summary>
public class GetNotificationConfigSnippets
{
    public static NotificationConfig GetNotificationConfig(string organizationId, string configId)
    {
        SecurityCenterClient client = SecurityCenterClient.Create();
        // You can also use 'projectId' or 'folderId' instead of the 'organizationId'.
        NotificationConfigName notificationConfigName = new NotificationConfigName(organizationId, configId);

        NotificationConfig response = client.GetNotificationConfig(notificationConfigName);
        Console.WriteLine($"Notification config: {response}");
        return response;
    }
}

NotificationConfig の更新

NotificationConfig を更新するには、securitycenter.notification.update 権限を含む IAM ロールが必要です。

フィールド マスクを使用して更新する場合は、指定したフィールドのみが更新されます。フィールド マスクを使用しない場合は、NotificationConfig 内のすべての変更可能なフィールドが新しい値に置き換えられます。フィールド マスクを使用することで、Pub/Sub のトピックと説明文を更新できます。

この例を完了するには、新しいトピックに登録されていることと、通知のサービス アカウントにそのトピックに対する pubsub.topics.setIamPolicy 権限が付与されている必要があります。

必要な権限を付与したら、任意の言語を使用して NotificationConfig の説明、Pub/Sub トピック、フィルタを更新します。

gcloud

gcloud scc notifications update PARENT_TYPE/PARENT_ID/locations/LOCATION/notificationConfigs/NOTIFICATION_NAME
--description="NOTIFICATION_DESCRIPTION" \
--pubsub-topic=PUBSUB_TOPIC \
--filter="FILTER"

次のように置き換えます。

  • PARENT_TYPE は、通知構成で指定されたリソース階層のレベルに応じて organizationsfoldersprojects のいずれかに置き換えます。
  • PARENT_ID は親リソースの数値 ID に置き換えます。
  • LOCATION: データ所在地が有効になっているか、notificationConfig が API v2 を使用して作成されている場合は必須です。

    データ所在地が有効になっている場合は、通知が保存される Security Command Center のロケーションを指定します。

    データ所在地が有効になっていない場合は、フルネームに /locations/LOCATION を含めるか、notificationConfig リソースが Security Command Center API を使用して作成された場合にのみ --location フラグを指定します。v2 の場合、有効な場所は global のみです。

  • NOTIFICATION_NAME: 通知の名前。

  • NOTIFICATION_DESCRIPTION: 通知の説明(1,024 文字以内)。

  • PUBSUB_TOPIC: 通知を受け取る Pub/Sub トピック。形式は projects/PROJECT_ID/topics/TOPIC です。

  • FILTER: Pub/Sub に送信する検出結果を選択するために定義する式。例: state="ACTIVE"

Python

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。

def update_notification_config(parent_id, notification_config_id, pubsub_topic):
    """
    Args:
        parent_id: must be in one of the following formats:
            "organizations/{organization_id}"
            "projects/{project_id}"
            "folders/{folder_id}"
        notification_config_id: "config-id-to-update"
        pubsub_topic: "projects/{new-project}/topics/{new-topic}"

    If updating a pubsub_topic, ensure this ServiceAccount has the
    "pubsub.topics.setIamPolicy" permission on the new topic.
    """
    from google.cloud import securitycenter as securitycenter
    from google.protobuf import field_mask_pb2

    client = securitycenter.SecurityCenterClient()

    notification_config_name = (
        f"{parent_id}/notificationConfigs/{notification_config_id}"
    )

    updated_description = "New updated description"
    updated_filter = 'state = "INACTIVE"'

    # Only description and pubsub_topic can be updated.
    field_mask = field_mask_pb2.FieldMask(
        paths=["description", "pubsub_topic", "streaming_config.filter"]
    )

    updated_notification_config = client.update_notification_config(
        request={
            "notification_config": {
                "name": notification_config_name,
                "description": updated_description,
                "pubsub_topic": pubsub_topic,
                "streaming_config": {"filter": updated_filter},
            },
            "update_mask": field_mask,
        }
    )

    print(updated_notification_config)

Java

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。


import com.google.cloud.securitycenter.v1.NotificationConfig;
import com.google.cloud.securitycenter.v1.NotificationConfig.StreamingConfig;
import com.google.cloud.securitycenter.v1.SecurityCenterClient;
import com.google.protobuf.FieldMask;
import java.io.IOException;

public class UpdateNotificationConfigSnippets {

  public static void main(String[] args) throws IOException {
    // parentId: must be in one of the following formats:
    //    "organizations/{organization_id}"
    //    "projects/{project_id}"
    //    "folders/{folder_id}"
    String parentId = String.format("organizations/%s", "ORG_ID");
    String notificationConfigId = "{config-id}";
    String projectId = "{your-project}";
    String topicName = "{your-topic}";

    updateNotificationConfig(parentId, notificationConfigId, projectId, topicName);
  }

  // Update an existing notification config.
  // If updating a Pubsub Topic, ensure the ServiceAccount has the
  // "pubsub.topics.setIamPolicy" permission on the new topic.
  public static NotificationConfig updateNotificationConfig(
      String parentId, String notificationConfigId, String projectId, String topicName)
      throws IOException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the "close" method on the client to safely clean up any remaining background resources.
    try (SecurityCenterClient client = SecurityCenterClient.create()) {

      String notificationConfigName =
          String.format(
              "%s/notificationConfigs/%s", parentId, notificationConfigId);

      // Ensure this ServiceAccount has the "pubsub.topics.setIamPolicy" permission on the topic.
      String pubsubTopic = String.format("projects/%s/topics/%s", projectId, topicName);

      NotificationConfig configToUpdate =
          NotificationConfig.newBuilder()
              .setName(notificationConfigName)
              .setDescription("updated description")
              .setPubsubTopic(pubsubTopic)
              .setStreamingConfig(StreamingConfig.newBuilder().setFilter("state = \"ACTIVE\""))
              .build();

      FieldMask fieldMask =
          FieldMask.newBuilder()
              .addPaths("description")
              .addPaths("pubsub_topic")
              .addPaths("streaming_config.filter")
              .build();

      NotificationConfig updatedConfig = client.updateNotificationConfig(configToUpdate, fieldMask);

      System.out.printf("Notification config: %s%n", updatedConfig);
      return updatedConfig;
    }
  }
}

Go

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。

import (
	"context"
	"fmt"
	"io"

	securitycenter "cloud.google.com/go/securitycenter/apiv1"
	"cloud.google.com/go/securitycenter/apiv1/securitycenterpb"
	"google.golang.org/genproto/protobuf/field_mask"
)

func updateNotificationConfig(w io.Writer, orgID string, notificationConfigID string, updatedPubsubTopic string) error {
	// orgID := "your-org-id"
	// notificationConfigID := "your-config-id"
	// updatedPubsubTopic := "projects/{new-project}/topics/{new-topic}"

	ctx := context.Background()
	client, err := securitycenter.NewClient(ctx)

	if err != nil {
		return fmt.Errorf("securitycenter.NewClient: %w", err)
	}
	defer client.Close()

	updatedDescription := "Updated sample config"
	updatedFilter := `state = "INACTIVE"`
	// Parent must be in one of the following formats:
	//		"organizations/{orgId}"
	//		"projects/{projectId}"
	//		"folders/{folderId}"
	parent := fmt.Sprintf("organizations/%s", orgID)
	req := &securitycenterpb.UpdateNotificationConfigRequest{
		NotificationConfig: &securitycenterpb.NotificationConfig{
			Name:        fmt.Sprintf("%s/notificationConfigs/%s", parent, notificationConfigID),
			Description: updatedDescription,
			PubsubTopic: updatedPubsubTopic,
			NotifyConfig: &securitycenterpb.NotificationConfig_StreamingConfig_{
				StreamingConfig: &securitycenterpb.NotificationConfig_StreamingConfig{
					Filter: updatedFilter,
				},
			},
		},
		UpdateMask: &field_mask.FieldMask{
			Paths: []string{"description", "pubsub_topic", "streaming_config.filter"},
		},
	}

	notificationConfig, err := client.UpdateNotificationConfig(ctx, req)
	if err != nil {
		return fmt.Errorf("Failed to update notification config: %w", err)
	}

	fmt.Fprintln(w, "Updated NotificationConfig: ", notificationConfig)

	return nil
}

Node.js

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。

// npm install @google-cloud/security-center/
const {SecurityCenterClient} = require('@google-cloud/security-center');

const client = new SecurityCenterClient();

// formattedConfigName: You can also use
//    `client.projectNotificationConfigPath(projectId, configId)` or
//    `client.folderNotificationConfigPath(folderId, configId)`.
// configId = "your-config-id";
const formattedConfigName = client.organizationNotificationConfigPath(
  organizationId,
  configId
);

// pubsubTopic = "projects/{your-project}/topics/{your-topic}";
// Ensure this Service Account has the "pubsub.topics.setIamPolicy" permission on this topic.

async function updateNotificationConfig() {
  const [response] = await client.updateNotificationConfig({
    updateMask: {
      paths: ['description', 'pubsub_topic', 'streaming_config.filter'],
    },
    notificationConfig: {
      name: formattedConfigName,
      description: 'Updated config description',
      pubsubTopic: pubsubTopic,
      streamingConfig: {filter: 'state = "INACTIVE"'},
    },
  });
  console.log('notification config update succeeded: ', response);
}

updateNotificationConfig();

PHP

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。

use Google\Cloud\SecurityCenter\V1\Client\SecurityCenterClient;
use Google\Cloud\SecurityCenter\V1\NotificationConfig;
use Google\Cloud\SecurityCenter\V1\NotificationConfig\StreamingConfig;
use Google\Cloud\SecurityCenter\V1\UpdateNotificationConfigRequest;
use Google\Protobuf\FieldMask;

/**
 * @param string $organizationId        Your org ID
 * @param string $notificationConfigId  A unique identifier
 * @param string $projectId             Your Cloud Project ID
 * @param string $topicName             Your topic name
 */
function update_notification(
    string $organizationId,
    string $notificationConfigId,
    string $projectId,
    string $topicName
): void {
    $securityCenterClient = new SecurityCenterClient();

    // Ensure this ServiceAccount has the 'pubsub.topics.setIamPolicy' permission on the topic.
    // https://cloud.google.com/pubsub/docs/reference/rest/v1/projects.topics/setIamPolicy
    $pubsubTopic = $securityCenterClient::topicName($projectId, $topicName);
    // You can also use 'projectId' or 'folderId' instead of the 'organizationId'.
    $notificationConfigName = $securityCenterClient::notificationConfigName($organizationId, $notificationConfigId);

    $streamingConfig = (new StreamingConfig())->setFilter('state = "ACTIVE"');
    $fieldMask = (new FieldMask())->setPaths(['description', 'pubsub_topic', 'streaming_config.filter']);
    $notificationConfig = (new NotificationConfig())
        ->setName($notificationConfigName)
        ->setDescription('Updated description.')
        ->setPubsubTopic($pubsubTopic)
        ->setStreamingConfig($streamingConfig);
    $updateNotificationConfigRequest = (new UpdateNotificationConfigRequest())
        ->setNotificationConfig($notificationConfig);

    $response = $securityCenterClient->updateNotificationConfig($updateNotificationConfigRequest);
    printf('Notification config was updated: %s' . PHP_EOL, $response->getName());
}

Ruby

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。

require "google/cloud/security_center"

# Your organization id. e.g. for "organizations/123", this would be "123".
# org_id = "YOUR_ORGANZATION_ID"

# Your notification config id. e.g. for
# "organizations/123/notificationConfigs/my-config" this would be "my-config".
# config_id = "YOUR_CONFIG_ID"

# Updated description of the notification config.
# description = "YOUR_DESCRIPTION"

# The PubSub topic where notifications will be published.
# pubsub_topic = "YOUR_TOPIC"

# Updated filter string for Notification config.
# filter = "UPDATED_FILTER"

client = Google::Cloud::SecurityCenter.security_center

# You can also use 'project_id' or 'folder_id' as a parent.
config_path = client.notification_config_path organization:        org_id,
                                              notification_config: config_id
notification_config = { name: config_path }
notification_config[:description] = description unless description.nil?
notification_config[:pubsub_topic] = pubsub_topic unless pubsub_topic.nil?
notification_config[:streaming_config][:filter] = filter unless filter.nil?

paths = []
paths.push "description" unless description.nil?
paths.push "pubsub_topic" unless pubsub_topic.nil?
paths.push "streaming_config.filter" unless filter.nil?
update_mask = { paths: paths }

response = client.update_notification_config(
  notification_config: notification_config,
  update_mask:         update_mask
)
puts response

C#

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。


using Google.Cloud.SecurityCenter.V1;
using static Google.Cloud.SecurityCenter.V1.NotificationConfig.Types;
using Google.Protobuf.WellKnownTypes;
using System;

/// <summary>Snippet for UpdateNotificationConfig</summary>
public class UpdateNotificationConfigSnippets
{
    public static NotificationConfig UpdateNotificationConfig(
        string organizationId, string notificationConfigId, string projectId, string topicName)
    {
        // You can also use 'projectId' or 'folderId' instead of the 'organizationId'.
        NotificationConfigName notificationConfigName = new NotificationConfigName(organizationId, notificationConfigId);
        TopicName pubsubTopic = new TopicName(projectId, topicName);

        NotificationConfig configToUpdate = new NotificationConfig
        {
            NotificationConfigName = notificationConfigName,
            Description = "updated description",
            PubsubTopicAsTopicName = pubsubTopic,
            StreamingConfig = new StreamingConfig { Filter = "state = \"INACTIVE\"" }
        };

        FieldMask fieldMask = new FieldMask { Paths = { "description", "pubsub_topic", "streaming_config.filter" } };
        SecurityCenterClient client = SecurityCenterClient.Create();
        NotificationConfig updatedConfig = client.UpdateNotificationConfig(configToUpdate, fieldMask);

        Console.WriteLine($"Notification config updated: {updatedConfig}");
        return updatedConfig;
    }
}

NotificationConfig の削除

NotificationConfig を削除するには、securitycenter.notification.delete 権限を含む IAM ロールが必要です。

NotificationConfig を削除しても、securitycenter.notificationServiceAgent ロールは Pub/Sub トピックに残ります。他のどの NotificationConfig でもその Pub/Sub トピックを使用していない場合は、トピックからロールを削除します。詳細については、アクセス制御をご覧ください。

任意の言語を使用して、NotificationConfig を削除します。

gcloud

gcloud scc notifications delete PARENT_TYPE/PARENT_ID/locations/LOCATION/notificationConfigs/NOTIFICATION_NAME

次のように置き換えます。

  • PARENT_TYPE は、通知構成で指定されたリソース階層のレベルに応じて organizationsfoldersprojects のいずれかに置き換えます。
  • PARENT_ID は親リソースの数値 ID に置き換えます。
  • LOCATION: データ所在地が有効になっているか、notificationConfig が API v2 を使用して作成されている場合は必須です。

    データ所在地が有効になっている場合は、通知が保存される Security Command Center のロケーションを指定します。

    データ所在地が有効になっていない場合は、フルネームに /locations/LOCATION を含めるか、notificationConfig が Security Command Center API v2 を使用して作成された場合にのみ --location フラグを指定します。その場合、有効な場所は global のみです。

  • NOTIFICATION_NAME: 通知の名前。

Python

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。

def delete_notification_config(parent_id, notification_config_id):
    """
    Args:
        parent_id: must be in one of the following formats:
            "organizations/{organization_id}"
            "projects/{project_id}"
            "folders/{folder_id}"
        notification_config_id: "your-config-id"
    """
    from google.cloud import securitycenter as securitycenter

    client = securitycenter.SecurityCenterClient()

    notification_config_name = (
        f"{parent_id}/notificationConfigs/{notification_config_id}"
    )

    client.delete_notification_config(request={"name": notification_config_name})
    print(f"Deleted notification config: {notification_config_name}")

Java

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。


import com.google.cloud.securitycenter.v1.SecurityCenterClient;
import java.io.IOException;

public class DeleteNotificationConfigSnippets {

  public static void main(String[] args) throws IOException {
    // parentId: must be in one of the following formats:
    //    "organizations/{organization_id}"
    //    "projects/{project_id}"
    //    "folders/{folder_id}"
    String parentId = String.format("organizations/%s", "ORG_ID");

    String notificationConfigId = "{config-id}";

    deleteNotificationConfig(parentId, notificationConfigId);
  }

  // Delete a notification config.
  public static boolean deleteNotificationConfig(String parentId, String notificationConfigId)
      throws IOException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the "close" method on the client to safely clean up any remaining background resources.
    try (SecurityCenterClient client = SecurityCenterClient.create()) {

      client.deleteNotificationConfig(String.format("%s/notificationConfigs/%s",
          parentId, notificationConfigId));

      System.out.printf("Deleted Notification config: %s%n", notificationConfigId);
    }
    return true;
  }
}

Go

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。

import (
	"context"
	"fmt"
	"io"

	securitycenter "cloud.google.com/go/securitycenter/apiv1"
	"cloud.google.com/go/securitycenter/apiv1/securitycenterpb"
)

func deleteNotificationConfig(w io.Writer, orgID string, notificationConfigID string) error {
	// orgID := "your-org-id"
	// notificationConfigID := "config-to-delete"

	ctx := context.Background()
	client, err := securitycenter.NewClient(ctx)

	if err != nil {
		return fmt.Errorf("securitycenter.NewClient: %w", err)
	}
	defer client.Close()

	// Parent must be in one of the following formats:
	//		"organizations/{orgId}"
	//		"projects/{projectId}"
	//		"folders/{folderId}"
	parent := fmt.Sprintf("organizations/%s", orgID)
	name := fmt.Sprintf("%s/notificationConfigs/%s", parent, notificationConfigID)
	req := &securitycenterpb.DeleteNotificationConfigRequest{
		Name: name,
	}

	if err = client.DeleteNotificationConfig(ctx, req); err != nil {
		return fmt.Errorf("Failed to retrieve notification config: %w", err)
	}
	fmt.Fprintln(w, "Deleted config: ", name)

	return nil
}

Node.js

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。

// npm install @google-cloud/security-center/
const {SecurityCenterClient} = require('@google-cloud/security-center');

const client = new SecurityCenterClient();

// formattedConfigName: You can also use
//    `client.projectNotificationConfigPath(projectId, configId)` or
//    `client.folderNotificationConfigPath(folderId, configId)`.
// configId = "your-config-id";
const formattedConfigName = client.organizationNotificationConfigPath(
  organizationId,
  configId
);

async function deleteNotificationConfg() {
  await client.deleteNotificationConfig({name: formattedConfigName});
  console.log('Notification config deleted: ', formattedConfigName);
}

deleteNotificationConfg();

PHP

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。

use Google\Cloud\SecurityCenter\V1\Client\SecurityCenterClient;
use Google\Cloud\SecurityCenter\V1\DeleteNotificationConfigRequest;

/**
 * @param string $organizationId        Your org ID
 * @param string $notificationConfigId  A unique identifier
 */
function delete_notification(string $organizationId, string $notificationConfigId): void
{
    $securityCenterClient = new SecurityCenterClient();
    $notificationConfigName = $securityCenterClient::notificationConfigName(
        // You can also use 'projectId' or 'folderId' instead of the 'organizationId'.
        $organizationId,
        $notificationConfigId
    );
    $deleteNotificationConfigRequest = (new DeleteNotificationConfigRequest())
        ->setName($notificationConfigName);

    $securityCenterClient->deleteNotificationConfig($deleteNotificationConfigRequest);
    print('Notification config was deleted' . PHP_EOL);
}

Ruby

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。

require "google/cloud/security_center"

# Your organization id. e.g. for "organizations/123", this would be "123".
# org_id = "YOUR_ORGANZATION_ID"

# Your notification config id. e.g. for
# "organizations/123/notificationConfigs/my-config" this would be "my-config".
# config_id = "YOUR_CONFIG_ID"

client = Google::Cloud::SecurityCenter.security_center

# You can also use 'project_id' or 'folder_id' as a parent.
config_path = client.notification_config_path organization:        org_id,
                                              notification_config: config_id

response = client.delete_notification_config name: config_path
puts "Deleted notification config #{config_id} with response: #{response}"

C#

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。


using Google.Cloud.SecurityCenter.V1;
using System;

/// <summary>Snippet for DeleteNotificationConfig</summary>
public class DeleteNotificationConfigSnippets
{
    public static bool DeleteNotificationConfig(string organizationId, string notificationConfigId)
    {
        // You can also use 'projectId' or 'folderId' instead of the 'organizationId'.
        NotificationConfigName notificationConfigName = new NotificationConfigName(organizationId, notificationConfigId);
        SecurityCenterClient client = SecurityCenterClient.Create();

        client.DeleteNotificationConfig(notificationConfigName);
        Console.WriteLine($"Deleted Notification config: {notificationConfigName}");
        return true;
    }
}

NotificationConfig の一覧表示

NotificationConfigs を一覧表示するには、securitycenter.notification.list 権限を含む IAM ロールが必要です。

Security Command Center API のすべてのリストは、ページ分けされます。各レスポンスでは、結果のページと次のページを返すためのトークンが戻されます。デフォルトの pageSize は、10 です。ページサイズは、最小値の 1 から最大値の 1,000 まで構成できます。

任意の言語を使用して、NotificationConfigs を一覧表示します。

gcloud

gcloud scc notifications list PARENT_TYPE/PARENT_ID/locations/LOCATION

次のように置き換えます。

  • PARENT_TYPEorganizationsfoldersprojects のいずれかに置き換えます。通知を一覧表示する範囲によって異なります。
  • PARENT_ID は親リソースの数値 ID に置き換えます。
  • LOCATION: データ所在地が有効になっているか、notificationConfig リソースが API v2 を使用して作成されている場合は必須です。

    データ所在地が有効になっている場合は、通知が保存される Security Command Center のロケーションを指定します。

    以下を含むデータ所在地が有効になっていない場合、/locations/LOCATION名前または--locationコマンドのフラグには、 notificationConfig Security Command Center API v2 を使用して作成されたリソースで、唯一の有効な場所はglobalして、ソース別にトラフィック データを分類します。

Python

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。

def list_notification_configs(parent_id):
    """
    Args:
        parent_id: must be in one of the following formats:
            "organizations/{organization_id}"
            "projects/{project_id}"
            "folders/{folder_id}"
    """
    from google.cloud import securitycenter as securitycenter

    client = securitycenter.SecurityCenterClient()

    notification_configs_iterator = client.list_notification_configs(
        request={"parent": parent_id}
    )
    for i, config in enumerate(notification_configs_iterator):
        print(f"{i}: notification_config: {config}")

Java

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。


import com.google.cloud.securitycenter.v1.NotificationConfig;
import com.google.cloud.securitycenter.v1.SecurityCenterClient;
import com.google.cloud.securitycenter.v1.SecurityCenterClient.ListNotificationConfigsPagedResponse;
import com.google.common.collect.ImmutableList;
import java.io.IOException;

public class ListNotificationConfigSnippets {

  public static void main(String[] args) throws IOException {
    // parentId: must be in one of the following formats:
    //    "organizations/{organization_id}"
    //    "projects/{project_id}"
    //    "folders/{folder_id}"
    String parentId = String.format("organizations/%s", "ORG_ID");

    listNotificationConfigs(parentId);
  }

  // List notification configs present in the given parent.
  public static ImmutableList<NotificationConfig> listNotificationConfigs(String parentId)
      throws IOException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the "close" method on the client to safely clean up any remaining background resources.
    try (SecurityCenterClient client = SecurityCenterClient.create()) {

      ListNotificationConfigsPagedResponse response = client.listNotificationConfigs(parentId);

      ImmutableList<NotificationConfig> notificationConfigs =
          ImmutableList.copyOf(response.iterateAll());

      System.out.printf("List notifications response: %s%n", response.getPage().getValues());
      return notificationConfigs;
    }
  }
}

Go

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。

import (
	"context"
	"fmt"
	"io"

	securitycenter "cloud.google.com/go/securitycenter/apiv1"
	"cloud.google.com/go/securitycenter/apiv1/securitycenterpb"
	"google.golang.org/api/iterator"
)

func listNotificationConfigs(w io.Writer, orgID string) error {
	// orgId := "your-org-id"

	ctx := context.Background()
	client, err := securitycenter.NewClient(ctx)

	if err != nil {
		return fmt.Errorf("securitycenter.NewClient: %w", err)
	}
	defer client.Close()

	req := &securitycenterpb.ListNotificationConfigsRequest{
		// Parent must be in one of the following formats:
		//		"organizations/{orgId}"
		//		"projects/{projectId}"
		//		"folders/{folderId}"
		Parent: fmt.Sprintf("organizations/%s", orgID),
	}
	it := client.ListNotificationConfigs(ctx, req)
	for {
		result, err := it.Next()
		if err == iterator.Done {
			break
		}

		if err != nil {
			return fmt.Errorf("it.Next: %w", err)
		}

		fmt.Fprintln(w, "NotificationConfig: ", result)
	}

	return nil
}

Node.js

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。

// npm install @google-cloud/security-center/
const {SecurityCenterClient} = require('@google-cloud/security-center');

const client = new SecurityCenterClient();

// parent: must be in one of the following formats:
//    `organizations/${organization_id}`
//    `projects/${project_id}`
//    `folders/${folder_id}`
const parent = `organizations/${organizationId}`;

async function listNotificationConfigs() {
  const [resources] = await client.listNotificationConfigs({parent: parent});
  console.log('Received Notification configs: ');
  for (const resource of resources) {
    console.log(resource);
  }
}

listNotificationConfigs();

PHP

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。

use Google\Cloud\SecurityCenter\V1\Client\SecurityCenterClient;
use Google\Cloud\SecurityCenter\V1\ListNotificationConfigsRequest;

/**
 * @param string $organizationId        Your org ID
 */
function list_notification(string $organizationId): void
{
    $securityCenterClient = new SecurityCenterClient();
    // 'parent' must be in one of the following formats:
    //		"organizations/{orgId}"
    //		"projects/{projectId}"
    //		"folders/{folderId}"
    $parent = $securityCenterClient::organizationName($organizationId);
    $listNotificationConfigsRequest = (new ListNotificationConfigsRequest())
        ->setParent($parent);

    foreach ($securityCenterClient->listNotificationConfigs($listNotificationConfigsRequest) as $element) {
        printf('Found notification config %s' . PHP_EOL, $element->getName());
    }

    print('Notification configs were listed' . PHP_EOL);
}

Ruby

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。

require "google/cloud/security_center"

# Your organization id. e.g. for "organizations/123", this would be "123".
# org_id = "YOUR_ORGANZATION_ID"

client = Google::Cloud::SecurityCenter.security_center

# You can also use 'project_id' or 'folder_id' as a parent.
# client.project_path project: project_id
# client.folder_path folder: folder_id
parent = client.organization_path organization: org_id

client.list_notification_configs(parent: parent).each_page do |page|
  page.each do |element|
    puts element
  end
end

C#

次のサンプルでは、v1 API を使用します。v2 のサンプルを変更するには、v1v2 に置き換え、/locations/LOCATION をリソース名に追加します。

ほとんどのリソースでは、/PARENT/PARENT_ID の後に /locations/LOCATION をリソース名に追加します。ここで、PARENTorganizationsfolders、または projects です。

検出結果の場合は、/sources/SOURCE_ID の後に /locations/LOCATION をリソース名に追加します。ここで、SOURCE_ID は、検出結果を発行した Security Command Center サービスの ID です。


using Google.Api.Gax.ResourceNames;
using Google.Api.Gax;
using Google.Cloud.SecurityCenter.V1;
using System;

/// <summary>Snippet for ListNotificationConfig</summary>
public class ListNotificationConfigSnippets
{
    public static PagedEnumerable<ListNotificationConfigsResponse, NotificationConfig> ListNotificationConfigs(string organizationId)
    {
        // You can also use 'projectId' or 'folderId' instead of the 'organizationId'.
        //      ProjectName projectName = new ProjectName(projectId);
        //      FolderName folderName = new FolderName(folderId);
        OrganizationName orgName = new OrganizationName(organizationId);
        SecurityCenterClient client = SecurityCenterClient.Create();
        PagedEnumerable<ListNotificationConfigsResponse, NotificationConfig> notificationConfigs = client.ListNotificationConfigs(orgName);

        // Print Notification Configuration names.
        foreach (var config in notificationConfigs)
        {
            Console.WriteLine(config.NotificationConfigName);
        }
        return notificationConfigs;
    }
}

Pub/Sub 通知の受信

このセクションでは、通知メッセージの例と、検出結果を含む NotificationMessage に Pub/Sub メッセージを変換する方法を示す例について説明します。

通知は、JSON 形式で Pub/Sub にパブリッシュされます。通知メッセージの例を、次に示します。

{
   "notificationConfigName": "organizations/ORGANIZATION_ID/notificationConfigs/CONFIG_ID",
   "finding": {
     "name": "organizations/ORGANIZATION_ID/sources/SOURCE_ID/findings/FINDING_ID",
     "parent": "organizations/ORGANIZATION_ID/sources/SOURCE_ID",
     "state": "ACTIVE",
     "category": "TEST-CATEGORY",
     "securityMarks": {
       "name": "organizations/ORGANIZATION_ID/sources/SOURCE_ID/findings/FINDING_ID/securityMarks"
     },
     "eventTime": "2019-07-26T07:32:37Z",
     "createTime": "2019-07-29T18:45:27.243Z"
   }
 }

任意の言語を使用して、Pub/Sub メッセージを NotificationMessage に変換します。

gcloud

gcloud CLI を使用して、Pub/Sub メッセージを NotificationMessage に変換することはできません。gcloud CLI を使用して NotificationMessage を取得し、ターミナルで直接 JSON を出力できます。

  # The subscription used to receive published messages from a topic
  PUBSUB_SUBSCRIPTION="projects/PROJECT_ID/subscriptions/SUBSCRIPTION_ID"

  gcloud pubsub subscriptions pull $PUBSUB_SUBSCRIPTION

次のように置き換えます。

  • PROJECT_ID: プロジェクト ID。
  • SUBSCRIPTION_ID: サブスクリプション ID。

Python

# Requires https://cloud.google.com/pubsub/docs/quickstart-client-libraries#pubsub-client-libraries-python
import concurrent

from google.cloud import pubsub_v1
from google.cloud.securitycenter_v1 import NotificationMessage

# TODO: project_id = "your-project-id"
# TODO: subscription_name = "your-subscription-name"

def callback(message):
    # Print the data received for debugging purpose if needed
    print(f"Received message: {message.data}")

    notification_msg = NotificationMessage.from_json(message.data)

    print(
        "Notification config name: {}".format(
            notification_msg.notification_config_name
        )
    )
    print(f"Finding: {notification_msg.finding}")

    # Ack the message to prevent it from being pulled again
    message.ack()

subscriber = pubsub_v1.SubscriberClient()
subscription_path = subscriber.subscription_path(project_id, subscription_name)

streaming_pull_future = subscriber.subscribe(subscription_path, callback=callback)

print(f"Listening for messages on {subscription_path}...\n")
try:
    streaming_pull_future.result(timeout=1)  # Block for 1 second
except concurrent.futures.TimeoutError:
    streaming_pull_future.cancel()

Java


import com.google.cloud.pubsub.v1.AckReplyConsumer;
import com.google.cloud.pubsub.v1.MessageReceiver;
import com.google.cloud.pubsub.v1.Subscriber;
import com.google.cloud.securitycenter.v1.NotificationMessage;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.util.JsonFormat;
import com.google.pubsub.v1.ProjectSubscriptionName;
import com.google.pubsub.v1.PubsubMessage;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class NotificationReceiver {

  private NotificationReceiver() {
  }

  public static void receiveNotificationMessages(String projectId, String subscriptionId) {
    // String projectId = "{your-project}";
    // String subscriptionId = "{your-subscription}";
    ProjectSubscriptionName subscriptionName =
        ProjectSubscriptionName.of(projectId, subscriptionId);

    try {
      Subscriber subscriber =
          Subscriber.newBuilder(subscriptionName, new NotificationMessageReceiver()).build();
      subscriber.startAsync().awaitRunning();

      // This sets the timeout value of the subscriber to 10s.
      subscriber.awaitTerminated(10_000, TimeUnit.MILLISECONDS);
    } catch (IllegalStateException | TimeoutException e) {
      System.out.println("Subscriber stopped: " + e);
    }
  }

  static class NotificationMessageReceiver implements MessageReceiver {

    @Override
    public void receiveMessage(PubsubMessage message, AckReplyConsumer consumer) {
      NotificationMessage.Builder notificationMessageBuilder = NotificationMessage.newBuilder();

      try {
        String jsonString = message.getData().toStringUtf8();
        JsonFormat.parser().merge(jsonString, notificationMessageBuilder);

        NotificationMessage notificationMessage = notificationMessageBuilder.build();
        System.out.println(
            String.format("Config id: %s", notificationMessage.getNotificationConfigName()));
        System.out.println(String.format("Finding: %s", notificationMessage.getFinding()));
      } catch (InvalidProtocolBufferException e) {
        System.out.println("Could not parse message: " + e);
      } finally {
        consumer.ack();
      }
    }
  }
}

Go

import (
	"bytes"
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/pubsub"
	"cloud.google.com/go/securitycenter/apiv1/securitycenterpb"
	"github.com/golang/protobuf/jsonpb"
)

func receiveMessages(w io.Writer, projectID string, subscriptionName string) error {
	// projectID := "your-project-id"
	// subsriptionName := "your-subscription-name"

	ctx := context.Background()

	client, err := pubsub.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("pubsub.NewClient: %w", err)
	}
	defer client.Close()

	sub := client.Subscription(subscriptionName)
	cctx, cancel := context.WithCancel(ctx)
	err = sub.Receive(cctx, func(ctx context.Context, msg *pubsub.Message) {
		var notificationMessage = new(securitycenterpb.NotificationMessage)
		jsonpb.Unmarshal(bytes.NewReader(msg.Data), notificationMessage)

		fmt.Fprintln(w, "Got finding: ", notificationMessage.GetFinding())
		msg.Ack()
		cancel()
	})
	if err != nil {
		return fmt.Errorf("Receive: %w", err)
	}

	return nil
}

Node.js

const {PubSub} = require('@google-cloud/pubsub');
const {StringDecoder} = require('string_decoder');

// projectId = 'your-project-id'
// subscriptionId = 'your-subscription-id'

const subscriptionName =
  'projects/' + projectId + '/subscriptions/' + subscriptionId;
const pubSubClient = new PubSub();

function listenForMessages() {
  const subscription = pubSubClient.subscription(subscriptionName);

  // message.data is a buffer array of json
  // 1. Convert buffer to normal string
  // 2. Convert json to NotificationMessage object
  const messageHandler = message => {
    const jsonString = new StringDecoder('utf-8').write(message.data);
    const parsedNotificationMessage = JSON.parse(jsonString);

    console.log(parsedNotificationMessage);
    console.log(parsedNotificationMessage.finding);

    // ACK when done with message
    message.ack();
  };

  subscription.on('message', messageHandler);

  // Set timeout to 10 seconds
  setTimeout(() => {
    subscription.removeListener('message', messageHandler);
  }, 10000);
}

listenForMessages();

PHP

use Google\Cloud\PubSub\PubSubClient;

/**
 * @param string $projectId             Your Cloud Project ID
 * @param string $subscriptionId        Your subscription ID
 */
function receive_notification(string $projectId, string $subscriptionId): void
{
    $pubsub = new PubSubClient([
        'projectId' => $projectId,
    ]);
    $subscription = $pubsub->subscription($subscriptionId);

    foreach ($subscription->pull() as $message) {
        printf('Message: %s' . PHP_EOL, $message->data());
        // Acknowledge the Pub/Sub message has been received, so it will not be pulled multiple times.
        $subscription->acknowledge($message);
    }
}

次のステップ