このトピックでは、Cloud Asset Inventory を使用して Secret Manager リソースを分析する方法について説明します。
これは Secret Manager の上級者向けのトピックです。このガイドを読む前に、次を確認することをおすすめします。
- プラットフォームの概要を確認して、Google Cloud の全体像を理解する
- Secret Manager のコンセプトの概要を確認して、Secret Manager を理解する
- Cloud Asset Inventory の概要を確認して、Cloud Asset Inventory を理解し、その包括的なアセット管理機能を確認する
概要
Secret Manager は、Google Cloud のマネージド メタデータ インベントリ システムである Cloud Asset Inventory と統合されています。この統合により、組織、フォルダ、プロジェクト全体でシークレットを特定して監査し、組織の要件に準拠していない構成を検出できます。このガイドでは、アセットのモニタリング、BigQuery へのアセットのエクスポート、Secret Manager リソースに対する Cloud Asset Inventory クエリのサンプルについて説明します。
メモ
- すべてのクエリには Google Cloud CLI と BigQuery で記述されたサンプルがありますが、シークレットとシークレット バージョンを BigQuery にエクスポートすることをおすすめします。アセットを BigQuery にエクスポートすると、SQL に似たクエリを作成し、有意な分析を作成して保存できます。
- Secret Manager は、Asset Search または Policy Analyzer と統合されていません。以下のクエリでは、Google Cloud CLI と BigQuery のネイティブ プロパティを使用してアセットを検索します。
- Cloud Asset Inventory は、過去 5 週間のスナップショットのエクスポートと一覧表示のみをサポートしています。
アセットの変更をモニタリングする
Cloud Asset Inventory はリアルタイムの更新を追跡し、これらの変更のモニタリングをサポートしています。リソースが変更されるたびに、一連の構成された Pub/Sub トピックに通知を送信するようにフィードを構成できます。また、Cloud Asset Inventory はフィードで条件の構成をサポートしているため、特定のアセットタイプの特定の変更をモニタリングすることができます。アセットの変更時にワークフローをトリガーする方法については、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 へのエクスポートをご覧ください。
サンプルクエリ
過去 2 週間以内に作成されたシークレット
過去 2 週間に組織に追加されたシークレット(およびそのプロパティ)を見つけます。
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"
自動的に複製されたシークレット
自動的に複製されたすべてのシークレットを検索します。
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
に複製されたすべてのシークレットを検索します。
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 日より前に作成されたすべてのシークレット バージョンを一覧表示します。
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 で暗号化されたすべてのシークレット(自動およびユーザー管理)を一覧表示します。
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 バージョンで暗号化された有効なシークレット バージョンをすべて一覧表示します。
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 日間に 1 回未満のローテーションがスケジュールされているすべてのシークレットを検索します。
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 日以内に期限切れになるシークレットを一覧表示します。
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 トピックが構成されているシークレット
少なくとも 1 つの 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 を使用する方法をご覧ください。