Secrets mit Cloud Asset Inventory analysieren

In diesem Thema erfahren Sie, wie Sie Cloud Asset Inventory verwenden, um Secret Manager-Ressourcen zu analysieren.

Dies ist ein Secret Manager-Thema für Fortgeschrittene. Bevor Sie diesen Leitfaden lesen, sollten Sie sich Folgendes ansehen:

Übersicht

Secret Manager ist in Cloud Asset Inventory eingebunden, das verwaltete Metadaten-Inventarsystem von Google Cloud. Durch diese Integration können Sie in Ihrer gesamten Organisation, Ihrem Ordner oder Ihrem Projekt und ermitteln Sie alle Konfigurationen, die nicht den Anforderungen Ihrer Organisation entsprechen. In dieser Anleitung werden das Monitoring von Assets, das Exportieren von Assets nach BigQuery sowie Beispiele für Cloud Asset Inventory-Abfragen über Secret Manager-Ressourcen erläutert.

Hinweise

  • Alle Abfragen enthalten Beispiele, die mit der Google Cloud CLI und BigQuery geschrieben wurden. Wir empfehlen jedoch, Ihr Secret und Ihre Secret-Versionen nach BigQuery zu exportieren. Durch den Export Ihrer Assets nach BigQuery können Sie SQL-ähnliche Abfragen schreiben, um aussagekräftige Analysen zu erstellen und zu speichern.
  • Secret Manager ist nicht in Asset Search oder Policy Analyzer eingebunden. Die folgenden Abfragen nutzen native Attribute der Google Cloud CLI und von BigQuery, um in Assets zu suchen.
  • Cloud Asset Inventory unterstützt das Exportieren und Auflisten von Snapshots nur für die letzten fünf Wochen.

Asset-Änderungen überwachen

Cloud Asset Inventory verfolgt Echtzeit-Updates und unterstützt das Monitoring dieser Änderungen. Sie können Feeds konfigurieren, um jedes Mal, wenn sich Ihre Ressourcen ändern, Benachrichtigungen an eine Reihe von konfigurierten Pub/Sub-Themen zu senden. Darüber hinaus unterstützt Cloud Asset Inventory das Konfigurieren von Bedingungen für Ihre Feeds, sodass Sie bestimmte Änderungen für bestimmte Asset-Typen überwachen können. In der Pub/Sub-Dokumentation erfahren Sie, wie Sie Workflows bei Asset-Änderungen auslösen.

Assets in BigQuery exportieren

Wenn Sie Ihre Secrets und Secret-Versionen nach BigQuery exportieren, SQL-ähnliche Abfragen für große Datenmengen ausführen und aussagekräftige Erkenntnisse gewinnen zu Ihren Assets. Prüfen Sie vor dem Export Ihrer Assets, ob Ihr Dataset und Ihre Dienstkonten ordnungsgemäß konfiguriert sind. Führen Sie den folgenden Befehl aus, um Ihre Assets zu exportieren:

gcloud

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

wobei

  • CONTENT_TYPE: Asset-Inhaltstyp (RESOURCE).
  • PROJECT_ID: Projekt-ID mit Assets, die überwacht werden sollen.
  • SNAPSHOT_TIME: Zeitpunkt, für den ein Ressourcen-Snapshot erstellt werden soll. Dieser liegt zwischen jetzt und 5 Wochen in der Vergangenheit.
  • BIGQUERY_TABLE: Tabelle, in die Daten exportiert werden sollen, im Format projects/PROJECT_ID/datasets/DATASET_ID/tables/TABLE_NAME.

Weitere Informationen finden Sie unter Nach BigQuery exportieren.

Beispielabfragen

Secret wurde in den letzten zwei Wochen erstellt

Entdecken Sie alle Secrets (und ihre Attribute), die Ihrer Organisation in den letzten zwei Wochen hinzugefügt wurden:

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"

Automatisch replizierte Secrets

Alle Secrets finden, die automatisch repliziert wurden:

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 wurde in eine bestimmte Region repliziert

Alle Secrets suchen, die nach us-central1 repliziert wurden:

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"

Aktivierte Secret-Versionen, die über 180 Tage alt sind

Listen Sie alle Secret-Versionen auf, die vor mehr als 180 Tagen erstellt wurden:

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 ohne konfigurierten CMEK

Listen Sie alle Secrets (automatische und nutzerverwaltete) auf, die nicht mit vom Kunden verwalteten Verschlüsselungsschlüsseln (CMEK) verschlüsselt wurden:

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 mit konfiguriertem CMEK

Listen Sie alle Secrets (automatische und vom Nutzer verwaltete) auf, die mit einem CMEK verschlüsselt wurden:

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"

Mit einem bestimmten CMEK verschlüsselte Secrets

Secrets suchen, die verschlüsselte Secret-Versionen mit einem bestimmten CMEK wurden:

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"

Secret-Versionen ohne konfigurierten CMEK

Alle aktivierten Secret-Versionen finden, die nicht mit einem CMEK verschlüsselt wurden:

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"

Secret-Versionen, die mit einem bestimmten CMEK verschlüsselt wurden

Alle aktivierten Secret-Versionen auflisten, die mit einer bestimmten CMEK-Version verschlüsselt wurden:

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 ohne konfigurierte Rotation

Nach Secrets suchen, die keinen Rotationsplan haben:

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 mit einem bestimmten Rotationszeitraum

Alle Secrets suchen, die planmäßig weniger als einmal alle 90 Tage rotiert werden:

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, die in den nächsten 30 Tagen ablaufen

Secrets auflisten, die in den nächsten 30 Tagen ablaufen:

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 mit einem konfigurierten Pub/Sub-Thema

Alle Secrets auflisten, für die mindestens ein Pub/Sub-Thema konfiguriert ist:

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"

Nächste Schritte