Analiza secretos con Cloud Asset Inventory

En esta página, se explica cómo usar Cloud Asset Inventory para supervisar tus secretos, exportar datos para el análisis y ejecutar consultas potentes para obtener las estadísticas que necesitas.

Descripción general

El Inventario de recursos de Cloud analiza tu Google Cloud entorno y registra cualquier cambio en tus recursos de la nube, como máquinas virtuales, bases de datos, buckets de almacenamiento y, en este contexto, los secretos de Secret Manager. La integración entre Secret Manager y Cloud Asset Inventory te ayuda a hacer lo siguiente:

  • Ejecutar consultas: Busca secretos específicos o identifica patrones en tus secretos.

  • Configura alertas: Configura Cloud Asset Inventory para que envíe notificaciones a Pub/Sub cuando ocurran eventos específicos, como cuando se creen, modifiquen o borren secretos.

  • Exporta datos: Exporta tu inventario secreto a BigQuery para obtener informes y análisis detallados.

  • Administra y analiza tus secretos: Consulta todos tus secretos en un solo lugar (en todos los proyectos y en toda tu organización) y, luego, identifica los que podrían estar mal configurados o incumplir las políticas de seguridad de tu organización. Por ejemplo, puedes encontrar secretos que no se rotan con regularidad o que carecen de controles de acceso adecuados.

Esta es una tarea avanzada para los usuarios de Secret Manager. Antes de leer esta página, te recomendamos que leas lo siguiente:

Cómo consultar Secret Manager

Para analizar tus secretos con consultas similares a las de SQL, te recomendamos que exportes tus secretos y versiones de secretos a BigQuery. Secret Manager no está integrado en Busca recursos ni en el Analizador de políticas. Estas consultas usan la CLI de Google Cloud y BigQuery para buscar tus recursos.

Limitaciones

El uso de Cloud Asset Inventory para analizar los recursos de Secret Manager tiene la siguiente limitación:

  • Cloud Asset Inventory es compatible con la exportación y la enumeración de instantáneas solo de las últimas cinco semanas.

Supervisa los cambios en los recursos

Cloud Asset Inventory realiza un seguimiento de las actualizaciones en tiempo real y admite la supervisión de estos cambios. Puedes configurar feeds para enviar notificaciones a un conjunto de temas de Pub/Sub configurados cada vez que haya una modificación en tus recursos. Además, Cloud Asset Inventory es compatible con la configuración de condiciones en tus feeds para que puedas supervisar cambios específicos en ciertos tipos de recursos. Si deseas obtener información para activar flujos de trabajo en los cambios de recursos, consulta la documentación de Pub/Sub.

Exportar elementos a BigQuery

Exportar tus secretos y versiones de secretos a BigQuery te permite ejecutar consultas similares a las de SQL sobre grandes cantidades de datos y producir estadísticas significativas sobre tus recursos. Antes de exportar tus recursos, asegúrate de que tus cuentas de servicio y conjunto de datos estén configuradas de forma correcta.

Para exportar tus recursos, ejecuta el siguiente comando:

gcloud

Antes de usar cualquiera de los datos de comando a continuación, realiza los siguientes reemplazos:

  • CONTENT_TYPE: Es el tipo de contenido del activo (RESOURCE).
  • PROJECT_ID: El ID del proyecto que contiene los secretos que se analizarán.
  • SNAPSHOT_TIME: Es la hora en la que se toman las instantáneas de los recursos. Puede ser entre la hora actual y las 5 semanas anteriores.
  • BIGQUERY_PROJECT_ID: Es el ID del proyecto en el que se encuentra la tabla de BigQuery.
  • DATASET_ID: el ID del conjunto de datos de BigQuery.
  • TABLE_NAME: Es la tabla a la que exportarás tus metadatos. Si no existe, se creará.

Ejecuta el siguiente comando:

Linux, macOS o Cloud Shell

gcloud asset export \
  --content-type=CONTENT_TYPE \
  --project=PROJECT_ID \
  --snapshot-time=SNAPSHOT_TIME \
  --bigquery-table=projects/BIGQUERY_PROJECT_ID/datasets/DATASET_ID/tables/TABLE_NAME \
  --output-bigquery-force

Windows (PowerShell)

gcloud asset export `
  --content-type=CONTENT_TYPE `
  --project=PROJECT_ID `
  --snapshot-time=SNAPSHOT_TIME `
  --bigquery-table=projects/BIGQUERY_PROJECT_ID/datasets/DATASET_ID/tables/TABLE_NAME `
  --output-bigquery-force

Windows (cmd.exe)

gcloud asset export ^
  --content-type=CONTENT_TYPE ^
  --project=PROJECT_ID ^
  --snapshot-time=SNAPSHOT_TIME ^
  --bigquery-table=projects/BIGQUERY_PROJECT_ID/datasets/DATASET_ID/tables/TABLE_NAME ^
  --output-bigquery-force

Para obtener más información, consulta Exporta a BigQuery.

Consultas de muestra

Usa estas consultas de muestra para encontrar secretos y versiones de secretos con propiedades específicas.

Secretos creados en las últimas dos semanas

Busca secretos (y sus propiedades) que se agregaron a tu organización en las últimas dos semanas.

BigQuery

  SELECT name, FROM BIGQUERY_TABLE
  WHERE asset_type='secretmanager.googleapis.com/Secret' AND
  DATE(JSON_VALUE(resource.data, '$.createTime')) > DATE_SUB(CURRENT_DATE(), INTERVAL 2 WEEK);
  

Reemplaza BIGQUERY_TABLE por la ruta de acceso completa a la tabla de BigQuery a la que exportaste todos los recursos en la sección Exportar recursos a BigQuery de este documento.

gcloud

    NOW=$(TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ")
    gcloud asset list --project=PROJECT_ID \
        --asset-types='secretmanager.googleapis.com/Secret' \
        --snapshot-time=$NOW \
        --content-type='resource' \
        --filter="resource.data.createTime>-P2W"
  

Reemplaza PROJECT_ID por el ID del proyecto que contiene los secretos que se analizarán.

Secretos replicados automáticamente

Busca todos los secretos replicados automáticamente.

BigQuery

    SELECT * FROM BIGQUERY_TABLE
    WHERE asset_type='secretmanager.googleapis.com/Secret' AND
    JSON_EXTRACT(resource.data, '$.replication.automatic') IS NOT NULL;
  

Reemplaza BIGQUERY_TABLE por la ruta de acceso completa a la tabla de BigQuery a la que exportaste todos los recursos en la sección Exportar recursos a BigQuery de este documento.

gcloud

    NOW=$(TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ")
    gcloud asset list --project=PROJECT_ID \
        --asset-types='secretmanager.googleapis.com/Secret' \
        --snapshot-time=$NOW \
        --content-type='resource' \
        --filter="resource.data.replication.automatic != NULL"
  

Reemplaza PROJECT_ID por el ID del proyecto que contiene los secretos que se analizarán.

Secretos replicados en una ubicación específica

Encuentra todos los secretos almacenados en una ubicación específica, como us-central1.

BigQuery

    SELECT * FROM BIGQUERY_TABLE
    WHERE
    (
      SELECT * FROM
      UNNEST(JSON_EXTRACT_ARRAY(resource.data, '$.replication.userManaged.replicas')) AS location
      WHERE JSON_VALUE(JSON_EXTRACT(location, '$.location')) = "us-central1"
    )
    IS NOT NULL;
  

Reemplaza BIGQUERY_TABLE por la ruta de acceso completa a la tabla de BigQuery a la que exportaste todos los recursos en la sección Exportar recursos a BigQuery de este documento.

gcloud

    NOW=$(TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ")
    gcloud asset list --project=PROJECT_ID \
        --asset-types='secretmanager.googleapis.com/Secret' \
        --snapshot-time=$NOW \
        --content-type='resource' \
        --filter="resource.data.replication.userManaged.replicas.location=LOCATION"
  

Reemplaza lo siguiente:

  • PROJECT_ID: El ID del proyecto que contiene los secretos que se analizarán
  • LOCATION: Es la Google Cloud ubicación del secreto.

Versiones de Secrets creadas hace más de 180 días

Enumera todas las versiones de los secretos que se crearon hace más de 180 días.

BigQuery

    SELECT * FROM BIGQUERY_TABLE
    WHERE asset_type='secretmanager.googleapis.com/SecretVersion' AND
      DATE(JSON_VALUE(resource.data, '$.createTime')) < DATE_SUB(CURRENT_DATE(), INTERVAL 180 DAY) AND
      JSON_VALUE(resource.data, '$.state') = "ENABLED";
  

Reemplaza BIGQUERY_TABLE por la ruta de acceso completa a la tabla de BigQuery a la que exportaste todos los recursos en la sección Exportar recursos a BigQuery de este documento.

gcloud

    NOW=$(TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ")
    gcloud asset list --project=PROJECT_ID \
        --asset-types='secretmanager.googleapis.com/SecretVersion' \
        --snapshot-time=$NOW \
        --content-type='resource' \
        --filter="resource.data.createTime < P6M AND resource.data.state=ENABLED"
  

Reemplaza PROJECT_ID por el ID del proyecto que contiene los secretos que se analizarán.

Secretos sin CMEK configurado

Enumera todos los secretos que no están encriptados con claves de encriptación de administrador del cliente (CMEK):

BigQuery

    SELECT * FROM BIGQUERY_TABLE
    WHERE asset_type='secretmanager.googleapis.com/Secret'
      AND (
        JSON_VALUE(resource.data, "$.replication.automatic.customerManagedEncryption.kmsKeyName") IS NULL
        AND JSON_VALUE(resource.data, "$.replication.userManaged.replicas[0].customerManagedEncryption.kmsKeyName") IS NULL
      );
  

Reemplaza BIGQUERY_TABLE por la ruta de acceso completa a la tabla de BigQuery a la que exportaste todos los recursos en la sección Exportar recursos a BigQuery de este documento.

gcloud

    NOW=$(TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ")
    gcloud asset list --project=PROJECT_ID \
        --asset-types='secretmanager.googleapis.com/SecretVersion' \
        --snapshot-time=$NOW \
        --content-type='resource' \
        --filter="resource.data.createTime < P6M AND resource.data.state=ENABLED"
  

Reemplaza PROJECT_ID por el ID del proyecto que contiene los secretos que se analizarán.

Secretos con CMEK configurado

Enumera todos los secretos que se encriptan con CMEK.

BigQuery

    SELECT * FROM BIGQUERY_TABLE
    WHERE asset_type='secretmanager.googleapis.com/Secret'
    AND (
      JSON_VALUE(resource.data, "$.replication.automatic.customerManagedEncryption.kmsKeyName") IS NOT NULL
      OR JSON_VALUE(resource.data, "$.replication.userManaged.replicas[0].customerManagedEncryption.kmsKeyName") IS NOT NULL
    );
  

Reemplaza BIGQUERY_TABLE por la ruta de acceso completa a la tabla de BigQuery a la que exportaste todos los recursos en la sección Exportar recursos a BigQuery de este documento.

gcloud

    NOW=$(TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ")
    gcloud asset list --project=PROJECT_ID \
        --asset-types='secretmanager.googleapis.com/Secret' \
        --snapshot-time=$NOW \
        --content-type='resource' \
        --filter="resource.data.replication.userManaged.replicas.customerManagedEncryption != NULL OR resource.data.replication.automatic.customerManagedEncryption!=NULL"
  

Reemplaza PROJECT_ID por el ID del proyecto que contiene los secretos que se analizarán.

Secretos encriptados con una CMEK específica

Busca secretos que estén encriptados con una CMEK específica.

BigQuery

    SELECT * FROM BIGQUERY_TABLE
    WHERE asset_type='secretmanager.googleapis.com/Secret'
      AND (
        JSON_VALUE(resource.data, "$.replication.automatic.customerManagedEncryption.kmsKeyName") = KMS_KEY_NAME
        OR JSON_VALUE(resource.data, "$.replication.userManaged.replicas[0].customerManagedEncryption.kmsKeyName") = KMS_KEY_NAME
      );
  

Reemplaza lo siguiente:

  • BIGQUERY_TABLE: Es la ruta de acceso completa a la tabla de BigQuery a la que exportaste todos los recursos en la sección Cómo exportar recursos a BigQuery de este documento.

  • KMS_KEY_NAME: El ID de la clave o el identificador completamente calificado de la clave

gcloud

    NOW=$(TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ")
    gcloud asset list --project=PROJECT_ID \
        --asset-types='secretmanager.googleapis.com/Secret' \
        --snapshot-time=$NOW \
        --content-type='resource' \
        --filter="resource.data.replication.userManaged.replicas.customerManagedEncryption.kmsKeyName=KMS_KEY_NAME"
  

Reemplaza lo siguiente:

  • PROJECT_ID: El ID del proyecto que contiene los secretos que se analizarán
  • KMS_KEY_NAME: El ID de la clave o el identificador completamente calificado de la clave

Versiones de secretos sin CMEK configuradas

Busca todas las versiones de secretos habilitadas que no estén encriptadas con CMEK.

BigQuery

    SELECT * FROM BIGQUERY_TABLE
    WHERE asset_type='secretmanager.googleapis.com/SecretVersion'
    AND (
      JSON_VALUE(resource.data, "$.replicationStatus.automatic.customerManagedEncryption.kmsKeyVersionName") IS NULL
      AND JSON_VALUE(resource.data, "$.replicationStatus.userManaged.replicas[0].customerManagedEncryption.kmsKeyVersionName") IS NULL
    )
    AND JSON_VALUE(resource.data, "$.state") = "ENABLED";
  

Reemplaza BIGQUERY_TABLE por la ruta de acceso completa a la tabla de BigQuery a la que exportaste todos los recursos en la sección Exportar recursos a BigQuery de este documento.

gcloud

    NOW=$(TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ")
    gcloud asset list --project=PROJECT_ID \
        --asset-types='secretmanager.googleapis.com/SecretVersion' \
        --snapshot-time=$NOW \
        --content-type='resource' \
        --filter="(resource.data.replicationStatus.userManaged.replicas.customerManagedEncryption = NULL OR resource.data.replicationStatus.automatic.customerManagedEncryption=NULL) AND resource.data.state=ENABLED"
  

Reemplaza PROJECT_ID por el ID del proyecto que contiene los secretos que se analizarán.

Versiones de los secretos encriptadas con una CMEK específica

Enumera todas las versiones de secretos habilitadas que se encriptaron con una versión de CMEK específica.

BigQuery

    SELECT * FROM BIGQUERY_TABLE
    WHERE asset_type='secretmanager.googleapis.com/SecretVersion'
    AND (
      JSON_VALUE(resource.data, "$.replicationStatus.automatic.customerManagedEncryption.kmsKeyVersionName") = KMS_KEY_VERSION_NAME
      OR JSON_VALUE(resource.data, "$.replicationStatus.userManaged.replicas[0].customerManagedEncryption.kmsKeyVersionName") = KMS_KEY_VERSION_NAME
    )
    AND JSON_VALUE(resource.data,"$.state")="ENABLED";
  

Reemplaza lo siguiente:

  • BIGQUERY_TABLE: Es la ruta de acceso completa a la tabla de BigQuery a la que exportaste todos los recursos en la sección Cómo exportar recursos a BigQuery de este documento.

  • KMS_KEY_VERSION_NAME: El número de versión de la clave de Cloud Key Management Service

gcloud

    NOW=$(TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ")
    gcloud asset list --project=PROJECT_ID \
        --asset-types='secretmanager.googleapis.com/SecretVersion' \
        --snapshot-time=$NOW \
        --content-type='resource' \
        --filter="resource.data.replicationStatus.userManaged.replicas.customerManagedEncryption.kmsKeyVersionName=$FULL_KMS_KEY_VERSION_RESOURCE_NAME AND resource.data.status=ENABLED"
  

Reemplaza lo siguiente:

  • PROJECT_ID: Es el ID del proyecto que contiene los secretos que se analizarán.
  • KMS_KEY_VERSION_NAME: Es el ID de la versión de la clave.

Secretos sin rotación configurada

Busca todos los secretos que no tengan un programa de rotación.

BigQuery

    SELECT * FROM BIGQUERY_TABLE
    WHERE asset_type='secretmanager.googleapis.com/Secret' AND
       JSON_EXTRACT(resource.data, '$.rotation') IS NULL;
  

Reemplaza BIGQUERY_TABLE por la ruta de acceso completa a la tabla de BigQuery a la que exportaste todos los recursos en la sección Exportar recursos a BigQuery de este documento.

gcloud

  NOW=$(TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ")
  gcloud asset list --project=PROJECT_ID \
      --asset-types='secretmanager.googleapis.com/Secret' \
      --snapshot-time=$NOW \
      --content-type='resource' \
      --filter="resource.data.rotation=NULL"
  

Reemplaza PROJECT_ID por el ID del proyecto que contiene los secretos que se analizarán.

Secretos con un período de rotación específico

Busca todos los secretos programados para rotar menos de una vez cada 90 días:

BigQuery

    SELECT *
    FROM BIGQUERY_TABLE
    WHERE
      CAST(
        TRIM(
          JSON_VALUE(JSON_EXTRACT(resource.data, "$.rotation.rotationPeriod")),"s")
        AS INT64)
    < 86400 * 90 #Rotation period in seconds (86400s in 1 day * 90 days)
  

Reemplaza BIGQUERY_TABLE por la ruta de acceso completa a la tabla de BigQuery a la que exportaste todos los recursos en la sección Exportar recursos a BigQuery de este documento.

gcloud

  NOW=$(TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ")
  ROTATION_PERIOD_SECONDS=$((90 * 24 * 60 * 60))
  gcloud asset list --project=PROJECT_ID \
      --asset-types='secretmanager.googleapis.com/Secret' \
      --snapshot-time=$NOW \
      --content-type='resource' \
      --filter="resource.data.rotation != null AND resource.data.rotation.rotationPeriod < ${ROTATION_PERIOD_SECONDS}s"
  

Reemplaza PROJECT_ID por el ID del proyecto que contiene los secretos que se analizarán.

Los secretos que vencerán en los próximos 30 días

Enumera los secretos que vencerán en los próximos 30 días.

BigQuery

    SELECT * FROM BIGQUERY_TABLE
    WHERE asset_type='secretmanager.googleapis.com/Secret' AND
      DATE(JSON_VALUE(resource.data, '$.expireTime')) < DATE_ADD(CURRENT_DATE(), INTERVAL 30 DAY);
  

Reemplaza BIGQUERY_TABLE por la ruta de acceso completa a la tabla de BigQuery a la que exportaste todos los recursos en la sección Exportar recursos a BigQuery de este documento.

gcloud

  NOW=$(TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ")
  gcloud asset list --project=PROJECT_ID \
      --asset-types='secretmanager.googleapis.com/Secret' \
      --snapshot-time=$NOW \
      --content-type='resource' \
      --filter="resource.data.expireTime < PD30"
  

Reemplaza PROJECT_ID por el ID del proyecto que contiene los secretos que se analizarán.

Secretos con un tema de Pub/Sub configurado

Enumera todos los secretos que tengan al menos un tema de Pub/Sub configurado.

BigQuery

    SELECT name, ARRAY_LENGTH(JSON_EXTRACT_ARRAY(resource.data, '$.topics')) AS topics_count,
    FROM BIGQUERY_TABLE
    WHERE asset_type='secretmanager.googleapis.com/Secret' AND
      ARRAY_LENGTH(JSON_EXTRACT_ARRAY(resource.data, '$.topics')) > 0
  

Reemplaza BIGQUERY_TABLE por la ruta de acceso completa a la tabla de BigQuery a la que exportaste todos los recursos en la sección Exportar recursos a BigQuery de este documento.

gcloud

  NOW=$(TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ")
  gcloud asset list --project=PROJECT_ID \
      --asset-types='secretmanager.googleapis.com/Secret' \
      --snapshot-time=$NOW \
      --content-type='resource' \
      --filter="resource.data.topics !=NULL"
  

Reemplaza PROJECT_ID por el ID del proyecto que contiene los secretos que se analizarán.

¿Qué sigue?