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

このページでは、Cloud Asset Inventory を使用してシークレットをモニタリングし、分析用のデータをエクスポートし、必要な分析情報を取得するための強力なクエリを実行する方法について説明します。

概要

Cloud Asset Inventory は、 Google Cloud 環境を分析し、仮想マシン、データベース、ストレージ バケットなどのクラウド リソースの変更を記録します。このコンテキストでは、Secret Manager シークレットの変更も記録します。Secret Manager と Cloud Asset Inventory の統合により、次のことが可能になります。

  • クエリを実行する: 特定のシークレットを検索したり、シークレット全体でパターンを特定したりします。

  • アラートを設定する: シークレットの作成、変更、削除などの特定のイベントが発生したときに Pub/Sub に通知を送信するように Cloud Asset Inventory を構成します。

  • データをエクスポートする: 詳細な分析とレポート作成のために、シークレット インベントリを BigQuery にエクスポートします。

  • シークレットの管理と分析: プロジェクトと組織全体のすべてのシークレットを 1 か所で確認し、構成ミスの可能性があるシークレットや組織のセキュリティ ポリシーに違反している可能性があるシークレットを特定します。たとえば、定期的にローテーションされていないシークレットや、適切なアクセス制御が設定されていないシークレットを見つけることができます。

これは、Secret Manager ユーザー向けの高度なタスクです。このページを読む前に、次のドキュメントを読むことをおすすめします。

Secret Manager のクエリ

SQL に似たクエリでシークレットを分析するには、シークレットとシークレット バージョンを BigQuery にエクスポートすることをおすすめします。Secret Manager は、Asset Search または Policy Analyzer と統合されていません。これらのクエリでは、Google Cloud CLI と BigQuery を使用してアセットを検索します。

制限事項

Cloud Asset Inventory を使用して Secret Manager リソースを分析する場合、次の制限事項があります。

  • Cloud Asset Inventory では、過去 5 週間のみのスナップショットのエクスポートと一覧表示がサポートされています。

アセットの変更をモニタリングする

Cloud Asset Inventory はリアルタイムの更新を追跡し、これらの変更のモニタリングをサポートします。リソースが変更されるたびに、一連の構成された Pub/Sub トピックに通知を送信するようにフィードを構成できます。また、Cloud Asset Inventory はフィードで条件の構成をサポートしているため、特定のアセットタイプの特定の変更をモニタリングすることができます。アセットの変更時にワークフローをトリガーする方法については、Pub/Sub ドキュメントをご覧ください。

アセットを BigQuery にエクスポートする

シークレットとシークレット バージョンを BigQuery にエクスポートすると、大量のデータに対して SQL に似たクエリを実行し、アセットに関する有益な分析情報を生成できます。アセットをエクスポートする前に、データセットとサービス アカウントが正しく構成されていることを確認してください。

アセットをエクスポートするには、次のコマンドを実行します。

gcloud

後述のコマンドデータを使用する前に、次のように置き換えます。

  • CONTENT_TYPE: アセットのコンテンツ タイプ(RESOURCE)。
  • PROJECT_ID: 分析するシークレットを含むプロジェクトの ID。
  • SNAPSHOT_TIME: リソースのスナップショットを作成する時間。これは、現在の時刻から過去 5 週間以内にする必要があります。
  • BIGQUERY_PROJECT_ID: BigQuery テーブルが存在するプロジェクトの ID。
  • DATASET_ID: BigQuery データセットの ID。
  • TABLE_NAME: メタデータのエクスポート先のテーブル。存在しない場合は作成されます。

次のコマンドを実行します。

Linux、macOS、Cloud Shell

gcloud asset export \
  --content-type=CONTENT_TYPE \
  --project=PROJECT_ID \
  --snapshot-time=SNAPSHOT_TIME \
  --bigquery-table=projects/BIGQUERY_PROJECT_ID/datasets/DATASET_ID/tables/TABLE_NAME \
  --output-bigquery-force

Windows(PowerShell)

gcloud asset export `
  --content-type=CONTENT_TYPE `
  --project=PROJECT_ID `
  --snapshot-time=SNAPSHOT_TIME `
  --bigquery-table=projects/BIGQUERY_PROJECT_ID/datasets/DATASET_ID/tables/TABLE_NAME `
  --output-bigquery-force

Windows(cmd.exe)

gcloud asset export ^
  --content-type=CONTENT_TYPE ^
  --project=PROJECT_ID ^
  --snapshot-time=SNAPSHOT_TIME ^
  --bigquery-table=projects/BIGQUERY_PROJECT_ID/datasets/DATASET_ID/tables/TABLE_NAME ^
  --output-bigquery-force

詳細については、BigQuery へのエクスポートをご覧ください。

サンプルクエリ

これらのサンプルクエリを使用して、特定のプロパティを持つシークレットとシークレット バージョンを検索します。

過去 2 週間以内に作成されたシークレット

過去 2 週間に組織に追加されたシークレット(およびそのプロパティ)を見つけます。

BigQuery

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

BIGQUERY_TABLE は、このドキュメントの [アセットを BigQuery にエクスポートする] セクションで、すべてのアセットをエクスポートした BigQuery テーブルへのフルパスに置き換えます。

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"
  

PROJECT_ID は、分析するシークレットを含むプロジェクトの ID に置き換えます。

自動的に複製されたシークレット

自動的に複製されたすべてのシークレットを検索します。

BigQuery

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

BIGQUERY_TABLE は、このドキュメントの [アセットを BigQuery にエクスポートする] セクションで、すべてのアセットをエクスポートした BigQuery テーブルへのフルパスに置き換えます。

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"
  

PROJECT_ID は、分析するシークレットを含むプロジェクトの ID に置き換えます。

特定の場所に複製されたシークレット

us-central1 などの特定のロケーションに保存されているすべてのシークレットを検索します。

BigQuery

    SELECT * FROM BIGQUERY_TABLE
    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;
  

BIGQUERY_TABLE は、このドキュメントの [アセットを BigQuery にエクスポートする] セクションで、すべてのアセットをエクスポートした BigQuery テーブルへのフルパスに置き換えます。

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=LOCATION"
  

次のように置き換えます。

  • PROJECT_ID: 分析するシークレットを含むプロジェクトの ID
  • LOCATION: シークレットの Google Cloud ロケーション

180 日より前に作成されたシークレット バージョン

180 日より前に作成されたすべてのシークレット バージョンを一覧表示します。

BigQuery

    SELECT * FROM BIGQUERY_TABLE
    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";
  

BIGQUERY_TABLE は、このドキュメントの [アセットを BigQuery にエクスポートする] セクションで、すべてのアセットをエクスポートした BigQuery テーブルへのフルパスに置き換えます。

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"
  

PROJECT_ID は、分析するシークレットを含むプロジェクトの ID に置き換えます。

CMEK が構成されていないシークレット

顧客管理暗号鍵(CMEK)で暗号化されていないすべてのシークレットを一覧表示します。

BigQuery

    SELECT * FROM BIGQUERY_TABLE
    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
      );
  

BIGQUERY_TABLE は、このドキュメントの [アセットを BigQuery にエクスポートする] セクションで、すべてのアセットをエクスポートした BigQuery テーブルへのフルパスに置き換えます。

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"
  

PROJECT_ID は、分析するシークレットを含むプロジェクトの ID に置き換えます。

CMEK が構成されているシークレット

CMEK で暗号化されたすべてのシークレットを一覧表示します。

BigQuery

    SELECT * FROM BIGQUERY_TABLE
    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
    );
  

BIGQUERY_TABLE は、このドキュメントの [アセットを BigQuery にエクスポートする] セクションで、すべてのアセットをエクスポートした BigQuery テーブルへのフルパスに置き換えます。

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"
  

PROJECT_ID は、分析するシークレットを含むプロジェクトの ID に置き換えます。

特定の CMEK で暗号化されたシークレット

特定の CMEK で暗号化されたシークレットを検索します。

BigQuery

    SELECT * FROM BIGQUERY_TABLE
    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
      );
  

次のように置き換えます。

  • BIGQUERY_TABLE: このドキュメントの [アセットを BigQuery にエクスポートする] セクションで、すべてのアセットをエクスポートした BigQuery テーブルへのフルパス。

  • KMS_KEY_NAME: 鍵の ID または完全修飾識別子

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"
  

次のように置き換えます。

  • PROJECT_ID: 分析するシークレットを含むプロジェクトの ID
  • KMS_KEY_NAME: 鍵の ID または完全修飾識別子

CMEK が構成されていないシークレット バージョン

CMEK で暗号化されていない有効なシークレット バージョンをすべて検索します。

BigQuery

    SELECT * FROM BIGQUERY_TABLE
    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";
  

BIGQUERY_TABLE は、このドキュメントの [アセットを BigQuery にエクスポートする] セクションで、すべてのアセットをエクスポートした BigQuery テーブルへのフルパスに置き換えます。

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"
  

PROJECT_ID は、分析するシークレットを含むプロジェクトの ID に置き換えます。

特定の CMEK で暗号化されたシークレット バージョン

特定の CMEK バージョンで暗号化された有効なシークレット バージョンをすべて一覧表示します。

BigQuery

    SELECT * FROM BIGQUERY_TABLE
    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";
  

次のように置き換えます。

  • BIGQUERY_TABLE: このドキュメントの [アセットを BigQuery にエクスポートする] セクションで、すべてのアセットをエクスポートした BigQuery テーブルへのフルパス。

  • KMS_KEY_VERSION_NAME: Cloud Key Management Service 鍵のバージョン番号

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"
  

次のように置き換えます。

  • PROJECT_ID: 分析するシークレットを含むプロジェクトの ID
  • KMS_KEY_VERSION_NAME: 鍵のバージョンの ID

ローテーションが構成されていないシークレット

ローテーション スケジュールがないすべてのシークレットを検索します。

BigQuery

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

BIGQUERY_TABLE は、このドキュメントの [アセットを BigQuery にエクスポートする] セクションで、すべてのアセットをエクスポートした BigQuery テーブルへのフルパスに置き換えます。

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"
  

PROJECT_ID は、分析するシークレットを含むプロジェクトの ID に置き換えます。

特定のローテーション期間を持つシークレット

90 日に 1 回未満の頻度でローテーションされるようにスケジュールされているすべてのシークレットを検索します。

BigQuery

    SELECT *
    FROM BIGQUERY_TABLE
    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)
  

BIGQUERY_TABLE は、このドキュメントの [アセットを BigQuery にエクスポートする] セクションで、すべてのアセットをエクスポートした BigQuery テーブルへのフルパスに置き換えます。

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"
  

PROJECT_ID は、分析するシークレットを含むプロジェクトの ID に置き換えます。

30 日以内に期限切れになるシークレット

30 日以内に期限切れになるシークレットを一覧表示します。

BigQuery

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

BIGQUERY_TABLE は、このドキュメントの [アセットを BigQuery にエクスポートする] セクションで、すべてのアセットをエクスポートした BigQuery テーブルへのフルパスに置き換えます。

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"
  

PROJECT_ID は、分析するシークレットを含むプロジェクトの ID に置き換えます。

Pub/Sub トピックが構成されているシークレット

少なくとも 1 つの Pub/Sub トピックが構成されているすべてのシークレットを一覧表示します。

BigQuery

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

BIGQUERY_TABLE は、このドキュメントの [アセットを BigQuery にエクスポートする] セクションで、すべてのアセットをエクスポートした BigQuery テーブルへのフルパスに置き換えます。

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"
  

PROJECT_ID は、分析するシークレットを含むプロジェクトの ID に置き換えます。

次のステップ