Crear y gestionar la configuración 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:

  • Crear un NotificationConfig
  • Obtener una NotificationConfig
  • Actualizar un NotificationConfig
  • Eliminar un NotificationConfig
  • Lista NotificationConfig
  • Recibir notificaciones de Pub/Sub

También puede configurar exportaciones continuas a Pub/Sub en Security Command Center.

Antes de empezar

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 un rol de Gestió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: lector 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 eliminar NotificationConfig: editor de configuraciones de notificaciones del centro de seguridad (roles/securitycenter.notificationConfigEditor)

Para asignar los roles adecuados a un principal que acceda a un notificationConfig, debes tener uno de los siguientes roles de gestión de identidades y accesos:

  • Administrador de la organización (roles/resourcemanager.organizationAdmin)
  • Administrador de gestión de identidades y accesos de carpetas (roles/resourcemanager.folderIamAdmin)
  • Administrador de gestión de identidades y accesos de proyectos (roles/resourcemanager.projectIamAdmin)

Los roles de gestión de identidades y accesos de Security Command Center se pueden conceder a nivel de organización, carpeta o proyecto. La posibilidad de ver, editar, crear o actualizar hallazgos, recursos y fuentes de seguridad depende del nivel de acceso que se te haya concedido. Para obtener más información sobre los roles de Security Command Center, consulta Control de acceso.

Residencia de datos y notificaciones

Si la residencia de datos está habilitada en Security Command Center, las configuraciones que definen las exportaciones continuas a recursos de Pub/Sub (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.

Como los filtros que se usan en las exportaciones continuas pueden contener datos sujetos a controles de residencia, asegúrese 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 solo se almacenan en la ubicación en la que se crean y no se pueden ver ni editar en otras ubicaciones.

Una vez que hayas creado una exportación continua, no podrás cambiar su ubicación. Para cambiar la ubicación, debes eliminar la exportación continua y volver a crearla en la nueva ubicación.

Para saber cómo usar Security Command Center cuando la residencia de datos está habilitada, consulta Endpoints regionales de Security Command Center.

Crear NotificationConfig

Para crear un NotificationConfig, debes tener lo siguiente:

  • Un tema de Pub/Sub que ya tengas y al que quieras enviar notificaciones.
  • Roles de gestión de identidades y accesos necesarios para la entidad 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 las notificaciones de búsqueda.

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

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

Cuando creas un NotificationConfig, debes especificar un elemento superior para el NotificationConfig en la jerarquía de recursos Google Cloud , que puede ser una organización, una carpeta o un proyecto. Si necesitas recuperar, actualizar o eliminar el NotificationConfig más adelante, debes incluir el ID numérico de la organización, la carpeta o el proyecto principal cuando hagas referencia a él.

En la consola de Google Cloud , algunos recursos de NotificationConfig pueden tener la etiqueta Antiguo, que indica que se crearon con la API Security Command Center v1. Puedes gestionar estos recursos de NotificationConfig Google Cloud con la consola, la CLI de gcloud, la API de Security Command Center v1 o las bibliotecas de cliente v1 de Security Command Center.

Para gestionar estos recursos de NotificationConfig con gcloud CLI, no debes especificar una ubicación al ejecutar el comando gcloud CLI.

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

gcloud

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

Haz los cambios siguientes:

  • NOTIFICATION_NAME: 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: el ámbito de 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 principal, especificado en el formato organizations/123, folders/456 o projects/789.
  • LOCATION: la ubicación de Security Command Center en la que se va a crear un NotificationConfig. Si la residencia de datos está habilitada, usa eu, sa o us. De lo contrario, usa el valor global.
  • NOTIFICATION_DESCRIPTION: una descripción de la notificación de no más de 1024 caracteres.
  • PUBSUB_TOPIC: el tema de Pub/Sub que recibirá las notificaciones. Su formato es projects/PROJECT_ID/topics/TOPIC.
  • FILTER: la expresión que defines para seleccionar qué resultados se envían a Pub/Sub. Por ejemplo, state=\"ACTIVE\".

Terraform

Para crear un NotificationConfig para una organización, sigue estos pasos:

resource "google_pubsub_topic" "scc_v2_organization_notification_config" {
  name = "my-topic"
}

resource "google_scc_v2_organization_notification_config" "custom_organization_notification_config" {
  config_id    = "my-config"
  organization = "123456789"
  location     = "global"
  description  = "My custom Cloud Security Command Center Finding Organization Notification Configuration"
  pubsub_topic = google_pubsub_topic.scc_v2_organization_notification_config.id

  streaming_config {
    filter = "category = \"OPEN_FIREWALL\" AND state = \"ACTIVE\""
  }
}

Para crear un NotificationConfig de una carpeta, sigue estos pasos:

resource "google_folder" "folder" {
  parent       = "organizations/123456789"
  display_name = "folder-name"
}

resource "google_pubsub_topic" "scc_v2_folder_notification_config" {
  name = "my-topic"
}

resource "google_scc_v2_folder_notification_config" "custom_notification_config" {
  config_id    = "my-config"
  folder       = google_folder.folder.folder_id
  location     = "global"
  description  = "My custom Cloud Security Command Center Finding Notification Configuration"
  pubsub_topic =  google_pubsub_topic.scc_v2_folder_notification_config.id

  streaming_config {
    filter = "category = \"OPEN_FIREWALL\" AND state = \"ACTIVE\""
  }
}

Crear un NotificationConfig para un proyecto:

resource "google_pubsub_topic" "scc_v2_project_notification" {
  name = "my-topic"
}

resource "google_scc_v2_project_notification_config" "custom_notification_config" {
  config_id    = "my-config"
  project      = "my-project-name"
  location     = "global"
  description  = "My custom Cloud Security Command Center Finding Notification Configuration"
  pubsub_topic =  google_pubsub_topic.scc_v2_project_notification.id

  streaming_config {
    filter = "category = \"OPEN_FIREWALL\" AND 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 se publican en el tema de Pub/Sub que has especificado.

Para publicar notificaciones, se crea una cuenta de servicio 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 asigna automáticamente el rol securitycenter.notificationServiceAgent en la política de gestión de identidades y accesos de PUBSUB_TOPIC al crear la configuración de notificaciones. Este rol de cuenta de servicio es necesario para que funcionen las notificaciones.

Obtener NotificationConfig

Para obtener un NotificationConfig, debes tener un rol de gestión de identidades y accesos que incluya el permiso securitycenter.notification.get.

gcloud

gcloud scc notifications describe NOTIFICATION_NAME \
  --PARENT_TYPE=PARENT_ID \
  --location=LOCATION

Haz los cambios siguientes:

  • NOTIFICATION_NAME: el nombre de la configuración de la notificación.
  • PARENT_TYPE el nivel de la jerarquía de recursos en el que se especifica la configuración. Usa organization, folder o project.
  • PARENT_ID: ID numérico del recurso principal.
  • LOCATION: la ubicación de Security Command Center en la que se va a obtener el NotificationConfig. Si la residencia de datos está habilitada, usa eu, sa o us. De lo contrario, usa el valor global.

Actualizar NotificationConfig

Para actualizar un NotificationConfig, debes tener un rol de gestión de identidades y accesos que incluya el permiso securitycenter.notification.update.

Cuando actualizas datos mediante una máscara de campo, solo se actualizan los campos que especifiques. Si no usa una máscara de campo, todos los campos mutables de NotificationConfig se sustituirán por los nuevos valores. 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 nuevo tema y tu cuenta de servicio de notificaciones debe tener el permiso pubsub.topics.setIamPolicy en el tema.

Después de conceder los permisos necesarios, actualice la NotificationConfig descripción, el tema de Pub/Sub y el filtro con el idioma que prefiera:

gcloud

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

Haz los cambios siguientes:

  • NOTIFICATION_NAME: el nombre de la configuración de la notificación.
  • PARENT_TYPE el nivel de la jerarquía de recursos en el que se especifica la configuración. Usa organization, folder o project.
  • PARENT_ID: ID numérico del recurso principal.
  • LOCATION: la ubicación de Security Command Center en la que se va a actualizar el NotificationConfig. Si la residencia de datos está habilitada, usa eu, sa o us. De lo contrario, usa el valor global.
  • NOTIFICATION_DESCRIPTION: una descripción de la notificación de no más de 1024 caracteres.
  • PUBSUB_TOPIC: el tema de Pub/Sub que recibirá las notificaciones. Su formato es projects/PROJECT_ID/topics/TOPIC.
  • FILTER: la expresión que defines para seleccionar qué resultados se envían a Pub/Sub. Por ejemplo, state="ACTIVE".

Eliminar NotificationConfig

Para eliminar un NotificationConfig, debes tener un rol de gestión de identidades y accesos que incluya el permiso securitycenter.notification.delete.

Cuando eliminas un NotificationConfig, el rol securitycenter.notificationServiceAgent permanece en el tema de Pub/Sub. Si no utilizas el tema de Pub/Sub en ningún otro NotificationConfig, elimina el rol del tema. Para obtener más información, consulta Control de acceso.

Elimina un NotificationConfig con el idioma que quieras:

gcloud

gcloud scc notifications delete NOTIFICATION_NAME \
  --PARENT_TYPE=PARENT_ID \
  --location=LOCATION

Haz los cambios siguientes:

  • NOTIFICATION_NAME: el nombre de la configuración de la notificación.
  • PARENT_TYPE el nivel de la jerarquía de recursos en el que se especifica la configuración. Usa organization, folder o project.
  • PARENT_ID: ID numérico del recurso principal.
  • LOCATION: la ubicación de Security Command Center en la que se va a eliminar el NotificationConfig. Si la residencia de datos está habilitada, usa eu, sa o us. De lo contrario, usa el valor global.

Mostrar NotificationConfigs

Para enumerar NotificationConfigs, debes tener un rol de gestión de identidades y accesos que incluya el permiso securitycenter.notification.list.

Todas las listas de APIs de Security Command Center están paginadas. Cada respuesta devuelve una página de resultados y un token para devolver la página siguiente. El valor predeterminado pageSize es 10. Puedes configurar el tamaño de la página con un mínimo de 1 y un máximo de 1000.

Lista NotificationConfigs en el idioma que elijas:

gcloud

gcloud scc notifications list PARENT_TYPE/PARENT_ID \
  --location=LOCATION

Haz los cambios siguientes:

  • PARENT_TYPE el nivel de la jerarquía de recursos en el que se especifica la configuración. Usa organizations, folders o projects.
  • PARENT_ID: ID numérico del recurso principal.
  • LOCATION: la ubicación de Security Command Center en la que se deben enumerar los recursos de NotificationConfig. Si la residencia de datos está habilitada, usa eu, sa o us. De lo contrario, usa el valor global.

Recibir notificaciones de Pub/Sub

En esta sección se proporciona un mensaje de notificación de ejemplo y ejemplos que muestran cómo convertir un mensaje de Pub/Sub en un NotificationMessage que contenga un hallazgo.

Las notificaciones se publican en Pub/Sub con el formato JSON. A continuación, se muestra un ejemplo de 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 idioma que elijas:

gcloud

La CLI de gcloud no admite la conversión de un mensaje de Pub/Sub en un NotificationMessage. Puedes usar la CLI gcloud para obtener un NotificationMessage e 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

Haz los cambios siguientes:

  • PROJECT_ID por el ID del proyecto.
  • SUBSCRIPTION_ID con 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
}

Siguientes pasos