Crea y administra configuraciones de notificaciones

En esta página, se describe cómo usar la función de notificaciones de la API de Security Command Center, incluidos los siguientes ejemplos:

  • Crea una NotificationConfig
  • Obtén una NotificationConfig
  • Actualiza una NotificationConfig
  • Borra una NotificationConfig
  • Enumera NotificationConfig
  • Recibe notificaciones de Pub/Sub

Por otro lado, los clientes Premium de Security Command Center pueden configurar las exportaciones continuas para Pub/Sub en Security Command Center.

Antes de comenzar

Para usar los ejemplos de esta página, debes completar la guía para configurar las notificaciones de resultados

Para ejecutar los siguientes ejemplos, necesitas una función de administración de identidades y accesos (IAM) con los permisos adecuados:

  • Crear NotificationConfig: Parámetros de configuración de notificaciones del centro de seguridad Editor (roles/securitycenter.notificationConfigEditor)
  • Obtener y enumerar NotificationConfig: notificación del centro de seguridad Visualizador de configuraciones (roles/securitycenter.notificationConfigViewer) o Editor de configuraciones de notificación del centro de seguridad (roles/securitycenter.notificationConfigEditor)
  • Actualizar y borrar NotificationConfig: notificación del centro de seguridad Editor de configuraciones (roles/securitycenter.notificationConfigEditor)

Para otorgar los roles adecuados a una principal que accede a un notificationConfig, debes tener uno de los siguientes roles de IAM:

  • Administrador de la organización (roles/resourcemanager.organizationAdmin)
  • Administrador de IAM de carpeta (roles/resourcemanager.folderIamAdmin)
  • Administrador del proyecto de IAM (roles/resourcemanager.projectIamAdmin)

Los roles de IAM para Security Command Center se pueden otorgar a nivel de la organización, a nivel de carpeta o proyecto. Tu capacidad para ver, editar, crear o actualizar resultados, recursos, y las fuentes de seguridad dependen del nivel al que se te otorgue acceso. Para obtener más información Para los roles de Security Command Center, consulta Control de acceso.

Residencia de los datos y notificaciones

Si la residencia de datos para Security Command Center, los parámetros de configuración que definen las exportaciones continuas a Pub/Sub (notificationConfig recursos) están sujetos al control de residencia de datos y se almacenan en tu Ubicación de Security Command Center.

Para exportar los resultados de una ubicación de Security Command Center a Pub/Sub, debes configurar la infraestructura exportar en la misma ubicación de Security Command Center que los resultados.

Debido a que los filtros que se usan en las las exportaciones pueden contener datos sujetos a controles de residencia, asegúrate de especificar la ubicación correcta antes de crearlos. Security Command Center no restringe la ubicación que creas exportarás.

Las exportaciones continuas se almacenan solo en la ubicación en las que se crean y no se pueden ver ni editar en otras ubicaciones.

Después de crear una exportación continua, no puedes cambiar su ubicación. Para cambiar la ubicación, debes borrar la exportación continua y volver a crearla en la nueva ubicación.

Para recuperar una exportación continua mediante llamadas a la API, haz lo siguiente: debes especificar la ubicación en el nombre completo del recurso de la notificationConfig Por ejemplo:

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

Del mismo modo, para recuperar una exportación continua usando en gcloud CLI, debes especificar la ubicación en el nombre completo del recurso de la configuración o mediante --locations marca. Por ejemplo:

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

Crea un NotificationConfig

Para crear un NotificationConfig, debes tener lo siguiente:

  • Un tema de Pub/Sub existente al que desees enviar notificaciones.
  • Roles de IAM obligatorios para la principal que crea la notificationConfig

Para obtener más información, consulta el paso a configura un tema de Pub/Sub de la guía para configurar las notificaciones de resultados.

Antes de crear un NotificationConfig, ten en cuenta que cada organización puede tener una cantidad limitada de archivos NotificationConfig. Para obtener más información, consulta Cuotas y límites.

El NotificationConfig incluye un campo filter que limita las notificaciones a eventos útiles. Este campo acepta todos los filtros disponibles en la API de Security Command Center findings.list .

Cuando creas un NotificationConfig, especificas un elemento superior para el NotificationConfig de la jerarquía de recursos de Google Cloud, una organización, una carpeta o un proyecto. Si necesitas recuperar, actualizar o borrar la NotificationConfig más tarde, deberás incluir el ID numérico de la organización, la carpeta o el proyecto superior cuando hacer referencia a él.

Para crear el NotificationConfig con el lenguaje o la plataforma que elijas:

gcloud

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

Reemplaza lo siguiente:

  • NOTIFICATION_NAME: Es el nombre de la notificación. Debe tener entre 1 y 128 caracteres, y contener caracteres alfanuméricos solo caracteres, guiones bajos o guiones.
  • PARENT: Es el permiso en la jerarquía de recursos. a la que se aplica la notificación, organization, folder o project.
  • PARENT_ID: Es el ID de la organización superior. carpeta o proyecto, especificada en el formato de organizations/123, folders/456 o projects/789.
  • LOCATION: Si la residencia de datos está habilitada, especifica el Ubicación de Security Command Center en la que se creará la notificación. El notificationConfig resultante recurso se almacena solo en esta ubicación. Solo los resultados que son emitidas en esta ubicación se envían a Pub/Sub.

    Especifica la marca --location si la residencia de datos no está habilitada crea la notificación con la API de Security Command Center v2 el único valor válido para la marca es global.

  • NOTIFICATION_DESCRIPTION: Es una descripción de la de no más de 1,024 caracteres.

  • PUBSUB_TOPIC: el Pub/Sub que recibirá notificaciones. Su formato es projects/PROJECT_ID/topics/TOPIC.

  • FILTER: Es la expresión que defines para seleccionar. qué resultados se envían a Pub/Sub. Por ejemplo, state="ACTIVE"

Python

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.

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

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.


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

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.

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

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.

// 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

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.

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

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.

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#

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.


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;
    }
}

Las notificaciones ahora se publican en el tema de Pub/Sub que especificaste.

Para publicar notificaciones, se crea una cuenta de servicio para ti con el formato service-org-ORGANIZATION_ID@gcp-sa-scc-notification.iam.gserviceaccount.com. Esta cuenta de servicio se crea cuando creas tu primer NotificationConfig y se le otorga automáticamente el rol de securitycenter.notificationServiceAgent en la política de IAM de PUBSUB_TOPIC cuando se crea la configuración de notificaciones. Este rol de la cuenta de servicio es obligatorio para que funcionen las notificaciones.

Obtén una NotificationConfig

Para obtener una NotificationConfig, debes tener una función de IAM que incluya el permiso securitycenter.notification.get.

gcloud

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

Reemplaza lo siguiente:

  • PARENT_TYPE con organizations, folders, o projects, según el nivel de la jerarquía de recursos se especifican en la configuración de notificaciones.
  • PARENT_ID por el ID numérico del recurso superior
  • LOCATION: Obligatorio si cualquiera de las opciones de residencia de los datos está habilitado o los recursos notificationConfig se crearon con el Versión 2 de la API.

    Si la residencia de datos está habilitada, especifica Ubicación de Security Command Center en la que se almacenan las notificaciones.

    Si la residencia de datos no está habilitada, incluye /locations/LOCATION solo si El recurso notificationConfig se creó con el Security Command Center API v2, en cuyo caso, la única ubicación válida es global.

  • NOTIFICATION_NAME: Es el nombre de la notificación.

Python

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.

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

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.


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

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.

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

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.

// 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

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.

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

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.

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#

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.


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;
    }
}

Actualiza una NotificationConfig

Para actualizar una NotificationConfig, debes tener una función de IAM que incluya el permiso securitycenter.notification.update.

Cuando actualizas con una máscara de campo, solo se actualizan los campos que especificas. Si no usas una máscara de campo, todos los campos mutables de NotificationConfig se reemplazan por los valores nuevos. Puedes usar una máscara de campo para actualizar el tema y la descripción de Pub/Sub.

Para completar este ejemplo, debes suscribirte al tema nuevo y tu cuenta de servicio de notificaciones debe tener el permiso pubsub.topics.setIamPolicy en el tema.

Después de otorgar los permisos necesarios, actualiza NotificationConfig. descripción, tema de Pub/Sub y filtro usando el lenguaje de tu opción:

gcloud

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

Reemplaza lo siguiente:

  • PARENT_TYPE con organizations, folders, o projects, según el nivel de la jerarquía de recursos se especifican en la configuración de notificaciones.
  • PARENT_ID por el ID numérico del recurso superior
  • LOCATION: Obligatorio si cualquiera de las opciones de residencia de los datos está habilitada, o bien la notificationConfig se creó con el Versión 2 de la API.

    Si la residencia de datos está habilitada, especifica Ubicación de Security Command Center en la que se almacena la notificación.

    Si la residencia de datos no está habilitada, incluye /locations/LOCATION en el nombre completo o especifica la marca --location solo si el notificationConfig recurso se creó con la API de Security Command Center v2, en cuyo caso, la única ubicación válida es global.

  • NOTIFICATION_NAME: Es el nombre de la notificación.

  • NOTIFICATION_DESCRIPTION: Es una descripción de la de no más de 1,024 caracteres.

  • PUBSUB_TOPIC: Es el Pub/Sub. que recibirá notificaciones. Su formato es projects/PROJECT_ID/topics/TOPIC.

  • FILTER: Es la expresión que defines para seleccionar. qué resultados se envían a Pub/Sub. Por ejemplo, state="ACTIVE"

Python

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.

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

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.


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

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.

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

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.

// 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

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.

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

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.

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#

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.


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;
    }
}

Borra una NotificationConfig

Para borrar una NotificationConfig, debes tener una función de IAM que incluya el permiso securitycenter.notification.delete.

Cuando borras una NotificationConfig, la función securitycenter.notificationServiceAgent permanece en el tema de Pub/Sub. Si no usas el tema de Pub/Sub en ningún otro NotificationConfig, quita la función del tema. Para obtener más información, consulta control de acceso.

Borra un NotificationConfig con el lenguaje que elijas:

gcloud

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

Reemplaza lo siguiente:

  • PARENT_TYPE con organizations, folders, o projects, según el nivel de la jerarquía de recursos se especifican en la configuración de notificaciones.
  • PARENT_ID por el ID numérico del recurso superior
  • LOCATION: Obligatorio si cualquiera de las opciones de residencia de los datos está habilitada, o bien la notificationConfig se creó con el Versión 2 de la API.

    Si la residencia de datos está habilitada, especifica Ubicación de Security Command Center en la que se almacena la notificación.

    Si la residencia de datos no está habilitada, incluye /locations/LOCATION en el nombre completo o especifica la marca --location solo si el notificationConfig se creó con la API de Security Command Center v2, en cuyo caso, la única ubicación válida es global.

  • NOTIFICATION_NAME: Es el nombre de la notificación.

Python

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.

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

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.


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

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.

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

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.

// 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

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.

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

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.

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#

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.


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;
    }
}

Enumera NotificationConfigs

Para enumerar NotificationConfigs, debes tener una función de IAM que incluya el permiso securitycenter.notification.list.

Se paginan todas las listas de la API de Security Command Center. Cada respuesta muestra una página de resultados y un token para mostrar la página siguiente. El valor predeterminado pageSize es 10. Puedes configurar el tamaño de la página a un mínimo de 1 y un máximo de 1,000.

Enumera NotificationConfigs con el lenguaje que elijas:

gcloud

gcloud scc notifications list PARENT_TYPE/PARENT_ID/locations/LOCATION

Reemplaza lo siguiente:

  • PARENT_TYPE con organizations, folders, o projects, según el permiso en el que necesites enumerar notificaciones.
  • PARENT_ID por el ID numérico del elemento superior recurso.
  • LOCATION: Obligatorio si cualquiera de las opciones de residencia de los datos está habilitado o los recursos notificationConfig se crearon con el Versión 2 de la API.

    Si la residencia de datos está habilitada, especifica Ubicación de Security Command Center en la que se almacenan las notificaciones.

    Si la residencia de datos no está habilitada, /locations/LOCATION en el nombre o la marca --location en el comando solo enumera los notificationConfig recursos creados con el Security Command Center API v2 y la única ubicación válida es global.

Python

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.

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

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.


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

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.

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

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.

// 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

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.

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

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.

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#

En el siguiente ejemplo, se usa la API v1. Para modificar la muestra para la v2, reemplaza v1 por v2 y agrega /locations/LOCATION para el nombre del recurso

Para la mayoría de los recursos, agrega /locations/LOCATION al el nombre del recurso después de /PARENT/PARENT_ID, donde PARENT es organizations, folders, o projects.

Para los resultados, agrega /locations/LOCATION al recurso nombre después de /sources/SOURCE_ID, donde SOURCE_ID es el ID del Servicio de Security Command Center que emitió el hallazgo.


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;
    }
}

Recibe notificaciones de Pub/Sub

En esta sección, se proporciona un mensaje de notificación de muestra y ejemplos que muestran cómo convertir un mensaje de Pub/Sub en una NotificationMessage que contiene un resultado.

Las notificaciones se publican en Pub/Sub en formato JSON. A continuación, se incluye un ejemplo de un mensaje de notificación:

{
   "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"
   }
 }

Convierte un mensaje de Pub/Sub en un NotificationMessage con el lenguaje que elijas:

gcloud

La CLI de gcloud no admite la conversión de un mensaje de Pub/Sub a NotificationMessage. Puedes usar la CLI de gcloud para obtener un NotificationMessage y, luego, imprimir el JSON directamente en tu terminal:

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

  gcloud pubsub subscriptions pull $PUBSUB_SUBSCRIPTION

Reemplaza lo siguiente:

  • PROJECT_ID por el ID del proyecto
  • SUBSCRIPTION_ID por tu ID de suscripción.

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);
    }
}

¿Qué sigue?