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 Security Command Center.

Antes de comenzar

Para usar los ejemplos de esta página, debes completar la guía para configurar 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 configuraciones 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 configuración de notificaciones del centro de seguridad (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 de Security Command Center se pueden otorgar a nivel de organización, carpeta o proyecto. Tu capacidad para ver, editar, crear o actualizar resultados, recursos y fuentes de seguridad depende del nivel al que se te otorga acceso. Para obtener más información sobre los roles de Security Command Center, consulta Control de acceso.

Notificaciones y residencia de datos

Si la residencia de datos está habilitada para Security Command Center, las configuraciones que definen las exportaciones continuas a Pub/Sub (recursos notificationConfig) están sujetas al control de residencia de datos y se almacenan en tu ubicación de Security Command Center.

Para exportar 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 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 ubicación nueva.

Para recuperar una exportación continua con 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/organizations/123/locations/eu/notificationConfigs/my-pubsub-export-01

Del mismo modo, para recuperar una exportación continua con gcloud CLI, debes especificar la ubicación con la marca --location. Por ejemplo:

gcloud scc notifications describe myContinuousExport --organization=123 \
    --location=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 el principal que crea el notificationConfig

Para obtener más información, consulta el paso para configurar un tema de Pub/Sub en la guía para configurar notificaciones de búsqueda.

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, especificas un elemento superior para el NotificationConfig de la jerarquía de recursos de Google Cloud, ya sea una organización, una carpeta o un proyecto. Si necesitas recuperar, actualizar o borrar el NotificationConfig más adelante, debes incluir el ID numérico de la organización, la carpeta o el proyecto superior cuando hagas referencia a él.

En la consola de Google Cloud, es posible que algunos recursos NotificationConfig tengan la etiqueta Heredado, que indica que se crearon con la API de Security Command Center v1. Puedes administrar estos recursos de NotificationConfig con la consola de Google Cloud, gcloud CLI, la API de Security Command Center v1 o las bibliotecas cliente de Security Command Center v1.

Para administrar estos recursos NotificationConfig con gcloud CLI, no debes especificar una ubicación cuando ejecutes el comando de gcloud CLI.

Para crear la NotificationConfig con el lenguaje o la plataforma que prefieras, haz lo siguiente:

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 solo caracteres alfanuméricos, guiones bajos o guiones.
  • PARENT: Es el permiso en la jerarquía de recursos al que se aplica la notificación, organization, folder o project.
  • PARENT_ID: 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, la ubicación de Security Command Center en la que se creará un NotificationConfig. Si la residencia de datos no está habilitada, usa el valor 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\"

Go

import (
	"context"
	"fmt"
	"io"

	securitycenter "cloud.google.com/go/securitycenter/apiv2"
	"cloud.google.com/go/securitycenter/apiv2/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}/locations/global"
		//		"projects/{projectId}/locations/global"
		//		"folders/{folderId}/locations/global"
		Parent:   fmt.Sprintf("organizations/%s/locations/global", 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
}

Java


package vtwo.notifications;

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

public class CreateNotification {

  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 = "{parent-id}";
    String topicName = "{your-topic}";
    String notificationConfigId = "{your-notification-id}";
    // Specify the location of the notification config.
    String location = "global";

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

  // Crete a notification config.
  // Ensure the ServiceAccount has the "pubsub.topics.setIamPolicy" permission on the new topic.
  public static NotificationConfig createNotificationConfig(
      String parentId, String location, String topicName, 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()) {

      String pubsubTopic = String.format("projects/%s/topics/%s", parentId, topicName);

      NotificationConfig notificationConfig = NotificationConfig.newBuilder()
          .setDescription("Java notification config")
          .setPubsubTopic(pubsubTopic)
          .setStreamingConfig(
              NotificationConfig.StreamingConfig.newBuilder().setFilter("state = \"ACTIVE\"")
                  .build())
          .build();

      NotificationConfig response = client.createNotificationConfig(
          LocationName.of(parentId, location), notificationConfig, notificationConfigId);

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

Node.js

// npm install '@google-cloud/security-center'
const {SecurityCenterClient} = require('@google-cloud/security-center').v2;
const uuidv1 = require('uuid').v1;

const client = new SecurityCenterClient();
/*
 *  Required. Resource name of the new notification config's parent. Its format
 *  is "organizations/[organization_id]/locations/[location_id]",
 *  "folders/[folder_id]/locations/[location_id]", or
 *  "projects/[project_id]/locations/[location_id]".
 */
const parent = `projects/${projectId}/locations/${location}`;

/**
 *  Required.
 *  Unique identifier provided by the client within the parent scope.
 *  It must be between 1 and 128 characters and contain alphanumeric
 *  characters, underscores, or hyphens only.
 */
const configId = 'notif-config-test-node-create-' + uuidv1();

// pubsubTopic = "projects/{your-project}/topics/{your-topic}";
const pubsubTopic = `projects/${projectId}/topics/${topicName}`;

/**
 *  Required. The notification config being created. The name and the service
 *  account will be ignored as they are both output only fields on this
 *  resource.
 */
const notificationConfig = {
  description: 'Sample config for node v2',
  pubsubTopic: pubsubTopic,
  streamingConfig: {filter: 'state = "ACTIVE"'},
};

// Build the request.
const createNotificationRequest = {
  parent: parent,
  configId: configId,
  notificationConfig: notificationConfig,
};

async function createNotificationConfig() {
  const [response] = await client.createNotificationConfig(
    createNotificationRequest
  );
  console.log('Notification configuration creation successful: %j', response);
}

await createNotificationConfig();

Python

def create_notification_config(
    parent_id, location_id, pubsub_topic, notification_config_id
) -> NotificationConfig:
    """
    This method is used to create the Notification Config.
    Args:
        parent_id: must be in one of the following formats:
            "organizations/{organization_id}"
            "projects/{project_id}"
            "folders/{folder_id}"
        location_id: "global"
        pubsub_topic: "projects/{your-project-id}/topics/{your-topic-id}"
        notification_config_id: "your-config-id"


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

    client = securitycenter_v2.SecurityCenterClient()
    parent_id = parent_id + "/locations/" + location_id
    response = 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(f"create notification config response:{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 te otorga de forma automática el rol securitycenter.notificationServiceAgent en la política de IAM para PUBSUB_TOPIC cuando creas la configuración de notificaciones. Esta función de cuenta de servicio es obligatoria para que las notificaciones funcionen.

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 NOTIFICATION_NAME \
  --PARENT_TYPE=PARENT_ID \
  --location=LOCATION

Reemplaza lo siguiente:

  • NOTIFICATION_NAME: Es el nombre de la configuración de notificaciones.
  • PARENT_TYPE es el nivel de la jerarquía de recursos en el que se especifica la configuración. Usa organization, folder o project.
  • PARENT_ID: Es el ID numérico del recurso superior.
  • LOCATION: Si la residencia de datos está habilitada, la ubicación de Security Command Center en la que se obtiene NotificationConfig. Si la residencia de datos no está habilitada, usa el valor global.

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 el filtro con el lenguaje que prefieras:

gcloud

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

Reemplaza lo siguiente:

  • NOTIFICATION_NAME: Es el nombre de la configuración de notificaciones.
  • PARENT_TYPE es el nivel de la jerarquía de recursos en el que se especifica la configuración. Usa organization, folder o project.
  • PARENT_ID: Es el ID numérico del recurso superior.
  • LOCATION: Si la residencia de datos está habilitada, la ubicación de Security Command Center en la que se actualizará el NotificationConfig. Si la residencia de datos no está habilitada, usa el valor 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"

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 NOTIFICATION_NAME \
  --PARENT_TYPE=PARENT_ID \
  --location=LOCATION

Reemplaza lo siguiente:

  • NOTIFICATION_NAME: Es el nombre de la configuración de notificaciones.
  • PARENT_TYPE es el nivel de la jerarquía de recursos en el que se especifica la configuración. Usa organization, folder o project.
  • PARENT_ID: Es el ID numérico del recurso superior.
  • LOCATION: Si la residencia de datos está habilitada, la ubicación de Security Command Center en la que se debe borrar NotificationConfig. Si la residencia de datos no está habilitada, usa el valor global.

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 \
  --location=LOCATION

Reemplaza lo siguiente:

  • PARENT_TYPE es el nivel de la jerarquía de recursos en el que se especifica la configuración. Usa organizations, folders o projects.
  • PARENT_ID: Es el ID numérico del recurso superior.
  • LOCATION: Si la residencia de datos está habilitada, la ubicación de Security Command Center en la que se enumeran los recursos NotificationConfig. Si la residencia de datos no está habilitada, usa el valor global.

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.

Go

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

	"cloud.google.com/go/pubsub"
	"cloud.google.com/go/securitycenter/apiv2/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
}

¿Qué sigue?