Cloud Asset Inventory でシークレットを分析する

このトピックでは、Cloud Asset Inventory を利用して Secret Manager リソースを分析する方法について説明します。

これは Secret Manager の高度なトピックです。このガイドを読む前に、次を確認することをおすすめします。

概要

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 beta 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 beta 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 beta 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 beta 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 beta 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 beta 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 beta 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 beta 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 beta 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 beta 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)

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 beta 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 beta asset list --project=PROJECT_ID \
    --asset-types='secretmanager.googleapis.com/Secret' \
    --snapshot-time=$NOW \
    --content-type='resource' \
    --filter="resource.data.topics !=NULL"

次のステップ