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

Como alternativa, los clientes de Security Command Center Premium pueden configurar exportaciones continuas para Pub/Sub en el panel de Security Command Center.

Antes de comenzar

Para usar los ejemplos de esta página, debes completar la guía Configura la búsqueda de notificaciones.

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

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

Para otorgar los roles adecuados a una principal que accede a notificationConfig, debes tener una de las siguientes funciones 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)

Las funciones de IAM para Security Command Center se pueden otorgar a nivel de organización, carpeta o proyecto. Tu capacidad de ver, editar, crear o actualizar los resultados, los elementos y las fuentes de seguridad depende del nivel para el que se te otorgue acceso. Para obtener más información sobre las funciones de Security Command Center, consulta Control de acceso.

Residencia de datos y notificaciones

Si la residencia de datos está habilitada para Security Command Center, la configuración que define las exportaciones continuas a Pub/Sub (recursos notificationConfig) está sujeta al control de residencia de datos y se almacena 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 exportación continua en la misma ubicación de Security Command Center que los resultados.

Debido a que los filtros que se usan en las exportaciones continuas 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 en la que creas las exportaciones.

Las exportaciones continuas se almacenan solo en la ubicación en la que se crearon 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 ubicación nueva.

Para recuperar una exportación continua mediante llamadas a la API, debes especificar la ubicación en el nombre completo del recurso de 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 con gcloud CLId, debes especificar la ubicación, ya sea en el nombre completo del recurso de la configuración o con la marca --locations. 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 el notificationConfig.

Para obtener más información, consulta el paso Configura un tema de Pub/Sub en la guía Configura 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 el método findings.list de la API de Security Command Center.

Cuando creas un NotificationConfig, debes especificar un elemento superior para el NotificationConfig desde la jerarquía de recursos de Google Cloud, ya sea una organización, una carpeta o un proyecto. Si más adelante necesitas recuperar, actualizar o borrar el NotificationConfig, debes incluir el ID numérico de la organización, la carpeta o el proyecto superior cuando hagas referencia a ellos.

Para crear el NotificationConfig con el lenguaje o la plataforma que prefieras, sigue estos pasos:

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 solo puede contener caracteres alfanuméricos, guiones bajos o guiones.
  • PARENT: Es el alcance en la jerarquía de recursos al que se aplica la notificación, organization, folder o project.
  • PARENT_ID: Es el ID de la organización, la carpeta o el proyecto superior, especificado en el formato organizations/123, folders/456 o projects/789.
  • LOCATION: Si la residencia de datos está habilitada, especifica la ubicación de Security Command Center en la que se crea la notificación. El recurso notificationConfig resultante se almacena solo en esta ubicación. Solo los resultados que se emiten en esta ubicación se envían a Pub/Sub.

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

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

  • PUBSUB_TOPIC: Es el tema de 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. Si deseas modificar la muestra para v2, reemplaza v1 por v2 y agrega /locations/LOCATION al nombre del recurso.

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

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

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. Si deseas modificar la muestra para v2, reemplaza v1 por v2 y agrega /locations/LOCATION al nombre del recurso.

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

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


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. Si deseas modificar la muestra para v2, reemplaza v1 por v2 y agrega /locations/LOCATION al nombre del recurso.

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

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

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. Si deseas modificar la muestra para v2, reemplaza v1 por v2 y agrega /locations/LOCATION al nombre del recurso.

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

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

// 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. Si deseas modificar la muestra para v2, reemplaza v1 por v2 y agrega /locations/LOCATION al nombre del recurso.

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

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

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

Rita

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

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

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

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. Si deseas modificar la muestra para v2, reemplaza v1 por v2 y agrega /locations/LOCATION al nombre del recurso.

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

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


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 securitycenter.notificationServiceAgent en la política de IAM para PUBSUB_TOPIC cuando se crea la configuración de notificaciones. Se requiere este rol de cuenta de servicio 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 que se especificó en la configuración de notificaciones
  • PARENT_ID por el ID numérico del recurso superior
  • LOCATION: Es obligatorio si la residencia de datos está habilitada o si los recursos notificationConfig se crearon con la versión 2 de la API.

    Si la residencia de datos está habilitada, especifica la 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 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. Si deseas modificar la muestra para v2, reemplaza v1 por v2 y agrega /locations/LOCATION al nombre del recurso.

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

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

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. Si deseas modificar la muestra para v2, reemplaza v1 por v2 y agrega /locations/LOCATION al nombre del recurso.

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

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


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. Si deseas modificar la muestra para v2, reemplaza v1 por v2 y agrega /locations/LOCATION al nombre del recurso.

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

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

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. Si deseas modificar la muestra para v2, reemplaza v1 por v2 y agrega /locations/LOCATION al nombre del recurso.

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

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

// 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. Si deseas modificar la muestra para v2, reemplaza v1 por v2 y agrega /locations/LOCATION al nombre del recurso.

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

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

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

Rita

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

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

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

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. Si deseas modificar la muestra para v2, reemplaza v1 por v2 y agrega /locations/LOCATION al nombre del recurso.

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

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


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 la descripción NotificationConfig, el tema de Pub/Sub y filtra con el lenguaje que prefieras:

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 que se especificó en la configuración de notificaciones
  • PARENT_ID por el ID numérico del recurso superior
  • LOCATION: Es obligatorio si la residencia de datos está habilitada o si se creó notificationConfig con la versión 2 de la API.

    Si la residencia de datos está habilitada, especifica la 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 recurso 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.

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

  • PUBSUB_TOPIC: Es el tema de 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. Si deseas modificar la muestra para v2, reemplaza v1 por v2 y agrega /locations/LOCATION al nombre del recurso.

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

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

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. Si deseas modificar la muestra para v2, reemplaza v1 por v2 y agrega /locations/LOCATION al nombre del recurso.

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

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


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. Si deseas modificar la muestra para v2, reemplaza v1 por v2 y agrega /locations/LOCATION al nombre del recurso.

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

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

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. Si deseas modificar la muestra para v2, reemplaza v1 por v2 y agrega /locations/LOCATION al nombre del recurso.

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

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

// 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. Si deseas modificar la muestra para v2, reemplaza v1 por v2 y agrega /locations/LOCATION al nombre del recurso.

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

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

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

Rita

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

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

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

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. Si deseas modificar la muestra para v2, reemplaza v1 por v2 y agrega /locations/LOCATION al nombre del recurso.

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

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


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 que se especificó en la configuración de notificaciones
  • PARENT_ID por el ID numérico del recurso superior
  • LOCATION: Es obligatorio si la residencia de datos está habilitada o si se creó notificationConfig con la versión 2 de la API.

    Si la residencia de datos está habilitada, especifica la 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 la 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. Si deseas modificar la muestra para v2, reemplaza v1 por v2 y agrega /locations/LOCATION al nombre del recurso.

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

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

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. Si deseas modificar la muestra para v2, reemplaza v1 por v2 y agrega /locations/LOCATION al nombre del recurso.

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

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


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. Si deseas modificar la muestra para v2, reemplaza v1 por v2 y agrega /locations/LOCATION al nombre del recurso.

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

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

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. Si deseas modificar la muestra para v2, reemplaza v1 por v2 y agrega /locations/LOCATION al nombre del recurso.

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

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

// 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. Si deseas modificar la muestra para v2, reemplaza v1 por v2 y agrega /locations/LOCATION al nombre del recurso.

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

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

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

Rita

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

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

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

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. Si deseas modificar la muestra para v2, reemplaza v1 por v2 y agrega /locations/LOCATION al nombre del recurso.

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

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


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 alcance en el que necesites enumerar las notificaciones.
  • PARENT_ID por el ID numérico del recurso superior
  • LOCATION: Es obligatorio si la residencia de datos está habilitada o si los recursos notificationConfig se crearon con la versión 2 de la API.

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

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

Python

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

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

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

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. Si deseas modificar la muestra para v2, reemplaza v1 por v2 y agrega /locations/LOCATION al nombre del recurso.

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

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


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. Si deseas modificar la muestra para v2, reemplaza v1 por v2 y agrega /locations/LOCATION al nombre del recurso.

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

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

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. Si deseas modificar la muestra para v2, reemplaza v1 por v2 y agrega /locations/LOCATION al nombre del recurso.

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

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

// 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. Si deseas modificar la muestra para v2, reemplaza v1 por v2 y agrega /locations/LOCATION al nombre del recurso.

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

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

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

Rita

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

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

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

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. Si deseas modificar la muestra para v2, reemplaza v1 por v2 y agrega /locations/LOCATION al nombre del recurso.

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

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


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?