在本主题中,了解如何利用 Cloud Asset Inventory 来分析 Secret Manager 资源。
这是 Secret Manager 的高级主题。在阅读本指南之前, 建议您查看以下内容:
- Platform 概览,从整体上了解 Google Cloud
- Secret Manager 概览,了解 Secret Manager
- Cloud Asset Inventory 概览,了解 Cloud Asset Inventory 并查看其全面的资产管理功能
概览
Secret Manager 与 Cloud Asset Inventory(Google Cloud 的代管式元数据目录系统)集成。借助这一集成,您可以发现和审核 在整个组织、文件夹或项目中发现密钥,以及发现 不符合您组织要求的配置。本指南介绍了如何监控资产,将资产导出到 BigQuery,以及针对 Secret Manager 资源执行的 Cloud Asset Inventory 查询的示例。
备注
- 虽然所有查询都有使用 Google Cloud CLI 和 BigQuery 编写的示例,但我们建议将密钥和密钥版本导出到 BigQuery。将资产导出到 BigQuery 后,您可以编写类似 SQL 的查询,以生成和存储有意义的分析。
- Secret Manager 未与资源搜索或政策分析器集成。以下查询利用了 Google Cloud CLI 的原生属性, 使用 BigQuery 搜索资产。
- Cloud Asset Inventory 仅支持导出和列出过去 5 周内的快照。
监控资源更改
Cloud Asset Inventory 会跟踪实时更新,并支持监控这些更改。您可以配置 Feed 每次向一组已配置的 Pub/Sub 主题发送通知 需要修改资源此外,Cloud Asset Inventory 支持在 Feed 中配置条件,以便您监控特定资产类型的具体更改。请参阅 查看 Pub/Sub 文档,了解如何 触发有关素材资源更改的工作流程。
将资产导出到 BigQuery
通过将密文和密文版本导出到 BigQuery,您可以对大量数据运行类似 SQL 的查询,并生成资产有关的有意义的数据洞见。在导出资产之前,请确保数据集和服务账号已正确配置。如需导出资源,请运行以下命令:
gcloud
$ gcloud asset export \ --content-type CONTENT_TYPE \ --project PROJECT_ID \ --snapshot-time SNAPSHOT_TIME \ --bigquery-table BIGQUERY_TABLE \ --output-bigquery-force
其中:
- CONTENT_TYPE:资产内容类型 (
RESOURCE
)。 - PROJECT_ID:包含要监控的资产的项目 ID。
- SNAPSHOT_TIME:截取资源快照的时间。此时间范围为当前时间到过去 5 周内。
- BIGQUERY_TABLE:作为数据导出目标的表,格式为:
projects/PROJECT_ID/datasets/DATASET_ID/tables/TABLE_NAME
。
如需了解详情,请参阅 导出到 BigQuery。
示例查询
过去两周内创建的密文
发现过去两周内添加到您的组织的所有密文(及其属性):
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"
自动复制的密文
查找自动复制的所有 Secret:
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"
复制到指定区域的密文
查找复制到 us-central1
的所有 Secret:
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"
已启用超过 180 天的密文版本
列出创建时间超过 180 天的所有 Secret 版本:
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"
未配置 CMEK 的密文
列出未使用客户-管理员加密密钥 (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"
配置了 CMEK 的密文
列出使用 CMEK 加密的所有 Secret(自动和用户管理的 Secret):
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"
使用特定 CMEK 加密的密文
查找使用给定 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") = 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"
未配置 CMEK 的密文版本
查找未使用 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"
使用特定 CMEK 加密的密文版本
列出使用特定 CMEK 版本加密的所有已启用的 Secret 版本:
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"
未配置轮替的密文
查找没有轮替时间表的所有密文:
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"
具有特定轮替周期的密文
查找计划每 90 天轮替不到一次的所有密文:
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"
将在接下来的 30 天内过期的密文
列出将在接下来的 30 天内过期的 Secret:
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"
配置了 Pub/Sub 主题的密文
列出至少配置了一个 Pub/Sub 主题的所有密文:
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"
后续步骤
- 详细了解如何将 Secret Manager 与其他产品搭配使用。