Analyser les secrets avec Cloud Asset Inventory

Dans cette rubrique, vous allez apprendre à utiliser Cloud Asset Inventory pour analyser des ressources de Secret Manager.

Cette rubrique est une rubrique avancée pour Secret Manager. Avant de lire ce guide, nous vous recommandons de consulter les ressources suivantes:

Présentation

Secret Manager est intégré à Cloud Asset Inventory, le système d'inventaire de métadonnées géré de Google Cloud. Grâce à cette intégration, vous pouvez identifier et auditer les secrets au sein de votre organisation, votre dossier ou votre projet, et découvrir toutes les configurations non conformes aux exigences de votre organisation. Ce guide explique comment surveiller vos éléments, exporter des éléments vers BigQuery et des exemples de requêtes Cloud Asset Inventory sur des ressources Secret Manager.

Remarques

  • Bien que toutes les requêtes contiennent des exemples écrits avec la Google Cloud CLI et BigQuery, nous vous recommandons d'exporter vos secrets et versions de secrets vers BigQuery. En exportant vos éléments vers BigQuery, vous pouvez écrire des requêtes de type SQL pour produire et stocker une analyse significative.
  • Secret Manager n'est pas intégré à Asset Search ni à Policy Analyzer. Les requêtes ci-dessous exploitent les propriétés natives de la Google Cloud CLI et de BigQuery pour effectuer une recherche dans des éléments.
  • Cloud Asset Inventory ne permet d'exporter et de répertorier les instantanés qu'au cours des cinq dernières semaines.

Contrôler les modifications apportées aux éléments

L'inventaire des éléments cloud suit les mises à jour en temps réel et permet de surveiller ces modifications. Vous pouvez configurer des flux pour envoyer des notifications à un ensemble de sujets Pub/Sub configurés chaque fois que vos ressources sont modifiées. De plus, Cloud Asset Inventory accepte la configuration de conditions sur vos flux, ce qui vous permet de surveiller des modifications spécifiques pour certains types d'éléments. Consultez la documentation Pub/Sub pour découvrir comment déclencher des workflows sur les modifications d'éléments.

Exporter des éléments vers BigQuery

L'exportation de vos secrets et de vos versions de secrets vers BigQuery vous permet d'exécuter des requêtes de type SQL sur de grandes quantités de données et de générer des insights pertinents sur vos éléments. Avant d'exporter vos éléments, assurez-vous que votre ensemble de données et vos comptes de service sont correctement configurés. Pour exporter vos éléments, exécutez la commande suivante:

gcloud

$ gcloud asset export \
   --content-type CONTENT_TYPE \
   --project PROJECT_ID \
   --snapshot-time SNAPSHOT_TIME \
   --bigquery-table BIGQUERY_TABLE \
   --output-bigquery-force

où :

  • CONTENT_TYPE : Type de contenu d'un élément (RESOURCE).
  • PROJECT_ID : ID du projet contenant les éléments à surveiller.
  • SNAPSHOT_TIME : heure à laquelle prendre un instantané des ressources. La période est comprise entre maintenant les cinq dernières semaines.
  • BIGQUERY_TABLE : table vers laquelle exporter les données, au format : projects/PROJECT_ID/datasets/DATASET_ID/tables/TABLE_NAME.

Pour en savoir plus, consultez la page Exporter vers BigQuery.

Exemples de requêtes

Secret créé au cours des deux dernières semaines

Découvrez les secrets (et leurs propriétés) qui ont été ajoutés à votre organisation au cours des deux dernières semaines :

BigQuery

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

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"

Secrets répliqués automatiquement

Recherchez tous les secrets répliqués automatiquement :

BigQuery

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

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"

Secret répliqué dans une région spécifiée

Recherchez tous les secrets répliqués sur us-central1 :

BigQuery

SELECT * FROM PROJECT_ID.DATASET_ID.TABLE_NAME
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;

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=us-central1"

Versions de secrets activées il y a plus de 180 jours

Répertoriez toutes les versions de secrets créées il y a plus de 180 jours :

BigQuery

SELECT * FROM PROJECT_ID.DATASET_ID.TABLE_NAME
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";

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"

Secret sans CMEK configuré

Répertoriez tous les secrets (automatiques et gérés par l'utilisateur) qui ne sont pas chiffrés avec des clés de chiffrement Customer-Manager (CMEK) :

BigQuery

SELECT * FROM PROJECT_ID.DATASET_ID.TABLE_NAME
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
  );

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"

Secret avec CMEK configuré

Répertoriez tous les secrets (automatiques et gérés par l'utilisateur) qui sont chiffrés avec CMEK :

BigQuery

SELECT * FROM PROJECT_ID.DATASET_ID.TABLE_NAME
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
);

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"

Secrets chiffrés avec une clé CMEK spécifique

Recherchez les secrets qui sont des versions chiffrées de secrets avec une clé CMEK donnée :

BigQuery

SELECT * FROM PROJECT_ID.DATASET_ID.TABLE_NAME
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
  );

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"

Versions des secrets sans clé CMEK configurée

Recherchez toutes les versions de secrets activées qui ne sont pas chiffrées avec CMEK :

BigQuery

SELECT * FROM PROJECT_ID.DATASET_ID.TABLE_NAME
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";

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"

Versions de secrets chiffrées avec une clé CMEK spécifique

Répertoriez toutes les versions de secrets activées chiffrées avec une version de CMEK spécifique :

BigQuery

SELECT * FROM PROJECT_ID.DATASET_ID.TABLE_NAME
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";

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"

Secrets sans rotation configurée

Recherchez tous les secrets qui ne disposent pas d'un calendrier de rotation :

BigQuery

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

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"

Secrets avec une période de rotation spécifique

Recherchez tous les secrets dont la rotation est prévue moins d'une fois tous les 90 jours :

BigQuery

SELECT *
FROM PROJECT_ID.DATASET_ID.TABLE_NAME
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)

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"

Secrets qui expireront dans les 30 prochains jours

Répertoriez les secrets qui expireront dans les 30 prochains jours :

BigQuery

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

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"

Secrets avec un sujet Pub/Sub configuré

Répertoriez tous les secrets pour lesquels au moins un sujet Pub/Sub est configuré :

BigQuery

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

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"

Étape suivante