顧客管理の暗号鍵(CMEK)の有効化

このトピックでは、Secret Manager での顧客管理の暗号鍵(CMEK)のサポートについて説明します。

概要

Secret Manager には、アプリケーション内の機密データに保存、管理、アクセスするのためのツールが提供されています。

デフォルトでは、Secret Manager に保存されるシークレットは Google のデフォルトの暗号化で暗号化されます。Google のデフォルトの暗号化では、シークレット ペイロードは永続ストレージに書き込まれる前に Google が管理する鍵によって暗号化されます。構成は不要です。多くの組織では、Google のデフォルトの暗号化が最適です。

より細かく制御したい組織は、Secret Manager の CMEK サポートで、Secret Manager 内の保存データを保護する Cloud KMS 鍵を構成できます。CMEK 鍵を一時的に無効にしたり完全に破棄したりすると、その鍵で暗号化されたデータは復号できないため、アクセスできません。

Secret Manager での CMEK の仕組み

シークレット バージョンを特定のロケーションの永続ストレージに書き込む前に、Secret Manager は一意のデータ暗号鍵(DEK)を使用してデータを暗号化します。この DEK はその後、Secret Manager サービスが所有する鍵暗号鍵(KEK)と呼ばれるレプリカ固有の鍵で暗号化されます。

Secret Manager で CMEK を使用する場合、KEK は CMEK 鍵と呼ばれる、Cloud KMS 内で管理する対称鍵です。CMEK 鍵は、暗号化されたシークレット バージョン レプリカと同じ GCP ロケーションに存在している必要があります。

このガイドでは、CMEK を使用するために Secret Manager を構成する方法について説明します。CMEK 全般についての詳細は、Cloud Key Management Service のドキュメントをご覧ください。

制限事項

CMEK は、Secret Manager の v1 API と gCloud でのみ使用できます。

始める前に

すべてのリソースを同じプロジェクト内に保存することも、シークレットと鍵を別のプロジェクトに保存することもできます。この決定をより深く理解するために Cloud KMS の職掌分散をお読みください。

Secret Manager と Cloud KMS を設定するには、次の前提条件を満たす必要があります。

  • Secret Manager:

    • Secret Manager のリソースを保持するプロジェクトを作成するか、既存のプロジェクトを使用します。
    • 必要に応じて、Secret Manager クイックスタートの Secret Manager の構成セクションの手順を完了します。
  • Cloud KMS:

    • Cloud KMS のリソースを保持するプロジェクトを作成するか、既存のプロジェクトを使用します。
    • 必要に応じて、Cloud KMS API を有効化します。

次の変数を Secret Manager および Cloud KMS プロジェクトのプロジェクト ID に設定します。

コマンドライン

$ export SM_PROJECT_ID="..."
$ export KMS_PROJECT_ID="..."

Google Cloud に対して認証を行います。

gcloud

$ gcloud auth login

サービス アカウントの作成

顧客管理の暗号鍵が必要なプロジェクトごとにサービス アカウントを作成する必要があります。現在使用できるのは、gcloud コマンドライン ツールコマンドを使用して、顧客管理の暗号鍵に必要なサービス アカウントの種類を作成する方法だけです。

サービス アカウントを作成するには gcloud コマンドライン ツールで次のコマンドを実行します。

gcloud

$ gcloud beta services identity create \
    --service "secretmanager.googleapis.com" \
    --project "${SM_PROJECT_ID}"

このコマンドは、次の形式でサービス アカウント名を返します。

service-[PROJECT_NUMBER]@gcp-sa-secretmanager.iam.gserviceaccount.com

このサービス アカウントに、シークレットの暗号化と復号に使用する CMEK Cloud KMS 鍵へのアクセス権を付与します。

サービス アカウント名を環境変数として保存します。

コマンドライン

# This is from the output of the command above
$ export SM_SERVICE_ACCOUNT="service-...."

Secret Manager プロジェクト、Cloud KMS プロジェクト、Secret Manager サービス アカウントの環境変数は、この手順を完了するまで設定したままにする必要があります。

自動レプリケーションによる CMEK

このセクションでは、自動レプリケーション ポリシーを使用して構成されるシークレットについて説明します。

自動レプリケーション ポリシーを使用するシークレットの場合、CMEK 鍵はグローバルの Cloud KMS マルチリージョンに配置する必要があります。

グローバル Cloud KMS リージョンで対称 Cloud KMS 鍵を作成するか、既存の鍵を使用します。この例では、secret-manager-cmek という新しいキーリングを作成し、my-cmek-key という新しい鍵を作成します。

gcloud

$ gcloud kms keyrings create "secret-manager-cmek" \
    --project "${KMS_PROJECT_ID}" \
    --location "global"

$ gcloud kms keys create "my-cmek-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "global" \
    --keyring "secret-manager-cmek" \
    --purpose "encryption"

鍵のリソース名を取得し、環境変数として設定します。

コマンドライン

$ export KMS_KEY_NAME="projects/${KMS_PROJECT_ID}/locations/global/keyRings/secret-manager-cmek/cryptoKeys/my-cmek-key"

サービス アカウントに Secret Manager へのアクセス許可を付与し、CMEK 鍵を使用して暗号化と復号を行います。このコマンドは、my-cmek-key Cloud KMS 鍵の Cloud KMS 暗号化 / 復号のロール(roles/cloudkms.cryptoKeyEncrypterDecrypter)をサービス アカウントに付与します。

gcloud

$ gcloud kms keys add-iam-policy-binding "my-cmek-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "global" \
    --keyring "secret-manager-cmek" \
    --member "serviceAccount:${SM_SERVICE_ACCOUNT}" \
    --role "roles/cloudkms.cryptoKeyEncrypterDecrypter"

自動レプリケーションを使用してシークレットを作成する。CMEK 鍵のリソース名がメタデータとして Secret に保存されます。

gcloud

$ gcloud beta secrets create my-secret \
    --replication-policy "automatic" \
    --kms-key-name "${KMS_KEY_NAME}" \
    --project "${SM_PROJECT_ID}"

API

replication.automatic.customerManagedEncryption.kmsKeyName の値を CMEK 鍵のリソース名に設定します。

$ curl "https://secretmanager.googleapis.com/v1/projects/${SM_PROJECT_ID}/secrets?secretId=my-secret" \
    --request "POST" \
    --header "Content-Type: application/json" \
    --header "Authorization: Bearer $(gcloud auth print-access-token)" \
    --data-binary @- <<EOF
{
  "replication":{
    "automatic":{
      "customerManagedEncryption":{
        "kmsKeyName": "${KMS_KEY_NAME}"
      }
    }
  }
}
EOF

これで、そのシークレットにシークレット バージョンが作成されるたびに、サービス アカウントが CMEK 鍵にアクセスできる限り、永続ストレージに書き込まれる前に、その鍵を使用してシークレット バージョンのペイロードが自動的に暗号化されます。サービス アカウントがアクセスできなくなったり、鍵が使用できなくなったりした場合、新しいシークレット バージョンを作成しようとしたり、既存のシークレット バージョンにアクセスしようとしたりするとエラーが返されます。

新しいシークレット バージョンを追加します。Cloud KMS 鍵のリソース名は指定しないでください。シークレットのメタデータから読み取ります。

gcloud

$ echo -n "abcd1234" | gcloud beta secrets versions add "my-secret" \
    --project "${SM_PROJECT_ID}" \
    --data-file -

呼び出し元に CMEK 鍵を使用する直接なアクセス権がない場合でも、シークレット バージョンが作成されます。呼び出し元ではなく、Secret Manager のサービス アカウントが、シークレットの読み取り時または書き込み時に暗号化と復号を行います。

同様に、シークレットにアクセスするために CMEK 鍵への直接なアクセス権は必要ありません。サービス アカウントがその鍵にアクセスし、ユーザーに代わってシークレットを暗号化または復号します。

作成したシークレット バージョンにアクセスするには:

gcloud

$ gcloud beta secrets versions access latest \
    --project "${SM_PROJECT_ID}" \
    --secret "my-secret"

CMEK 構成の更新

global Cloud KMS マルチリージョンで新しい対称 KMS 鍵を作成します。

gcloud

$ gcloud kms keys create "my-other-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "global" \
    --keyring "secret-manager-cmek" \
    --purpose "encryption"

サービス アカウントに Secret Manager へのアクセス権を付与し、新しい CMEK 鍵を使用して暗号化と復号を行います。このコマンドは、my-other-key Cloud KMS 鍵の Cloud KMS 暗号化 / 復号のロール(roles/cloudkms.cryptoKeyEncrypterDecrypter)をサービス アカウントに付与します。

gcloud

$ gcloud kms keys add-iam-policy-binding "my-other-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "global" \
    --keyring "secret-manager-cmek" \
    --member "serviceAccount:${SM_SERVICE_ACCOUNT}" \
    --role "roles/cloudkms.cryptoKeyEncrypterDecrypter"

新しい Cloud KMS 鍵のリソース名でシークレットのレプリケーションを更新し、シークレットの CMEK 構成を変更します。

gcloud

$ gcloud beta secrets replication update my-secret \
    --set-kms-key="projects/${KMS_PROJECT_ID}/locations/global/keyRings/secret-manager-cmek/cryptoKeys/my-other-key" \
    --project "${SM_PROJECT_ID}"

API

$ curl "https://secretmanager.googleapis.com/v1/projects/${SM_PROJECT_ID}/secrets/my-secret?updateMask=replication" \
    --request "PATCH" \
    --header "Authorization: Bearer $(gcloud auth print-access-token)" \
    --header "Content-Type: application/json" \
    --data-binary @- <<EOF
{
  "replication": {
    "automatic":{
      "customerManagedEncryption":{
        "kmsKeyName": "projects/${KMS_PROJECT_ID}/locations/global/keyRings/secret-manager-cmek/cryptoKeys/my-other-key"
      }
    }
  }
}
EOF

ユーザー管理のレプリケーションによる CMEK

このセクションでは、ユーザーが管理するレプリケーション ポリシーで構成されたシークレットについて説明します。ユーザー管理のレプリケーション ポリシーでは、シークレットが保存される GCP のロケーションを制御します。シークレットには、すべての GCP ロケーションからいつでもアクセスできます。

ユーザー管理のレプリケーション ポリシーを使用したシークレットは、シークレット バージョンが保存されている場所を正確にマッピングする Cloud KMS 鍵を使用する必要があります。このガイドでは、シークレットを us-east1、us-central1 の 2 つの場所に保存しています。シークレットへのアクセス リクエストは、次のいずれかの場所にルーティングされます。

2 つの各リージョンで、暗号化目的でキーリングと Cloud KMS 鍵を作成するか、既存の鍵を使用します。この例では、secret-manager-cmek という新しいキーリングを作成し、各リージョンに「my-cmek-key」という鍵を作成します。

gcloud

# us-east1
$ gcloud kms keyrings create "secret-manager-cmek" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-east1"

$ gcloud kms keys create "my-cmek-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-east1" \
    --keyring "secret-manager-cmek" \
    --purpose "encryption"

# us-central1
$ gcloud kms keyrings create "secret-manager-cmek" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-central1"

$ gcloud kms keys create "my-cmek-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-central1" \
    --keyring "secret-manager-cmek" \
    --purpose "encryption"

サービス アカウントに Secret Manager の権限を付与し、個別の CMEK 鍵ごと、またはプロジェクトのすべての鍵に Cloud KMS 暗号化 / 復号のロール(roles/cloudkms.cryptoKeyEncrypterDecrypter)を付与することで、CMEK 鍵を使用して暗号化と復号を行います。

gcloud

# us-east1
$ gcloud kms keys add-iam-policy-binding "my-cmek-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-east1" \
    --keyring "secret-manager-cmek" \
    --member "serviceAccount:${SM_SERVICE_ACCOUNT}" \
    --role "roles/cloudkms.cryptoKeyEncrypterDecrypter"

# us-central1
$ gcloud kms keys add-iam-policy-binding "my-cmek-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-central1" \
    --keyring "secret-manager-cmek" \
    --member "serviceAccount:${SM_SERVICE_ACCOUNT}" \
    --role "roles/cloudkms.cryptoKeyEncrypterDecrypter"

ユーザー管理のレプリケーションで CMEK を有効化した シークレットを作成します。CMEK 鍵のリソース名がメタデータとして Secret に保存されます。

gcloud

$ cat <<EOF > replication-policy.json
{
  "userManaged":{
    "replicas":[
      {
        "location":"us-east1",
        "customerManagedEncryption":{
          "kmsKeyName":"projects/${KMS_PROJECT_ID}/locations/us-east1/keyRings/secret-manager-cmek/cryptoKeys/my-cmek-key"
        }
      },
      {
        "location":"us-central1",
        "customerManagedEncryption":{
          "kmsKeyName":"projects/${KMS_PROJECT_ID}/locations/us-central1/keyRings/secret-manager-cmek/cryptoKeys/my-cmek-key"
        }
      }
    ]
  }
}
EOF

$ gcloud beta secrets create my-ummr-secret \
    --replication-policy-file replication-policy.json \
    --project "${SM_PROJECT_ID}"

API

replication.userManaged.replicas.customerManagedEncryption.kmsKeyName の値を CMEK 鍵のリソース名に設定します。

$ curl "https://secretmanager.googleapis.com/v1/projects/${SM_PROJECT_ID}/secrets?secretId=my-ummr-secret" \
--request "POST" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $(gcloud auth print-access-token)" \
--data-binary @- <<EOF
{
  "replication":{
    "userManaged":{
      "replicas":[
        {
          "location":"us-east1",
          "customerManagedEncryption":{
            "kmsKeyName":"projects/${KMS_PROJECT_ID}/locations/us-east1/keyRings/secret-manager-cmek/cryptoKeys/my-cmek-key"
          }
        },
        {
          "location":"us-central1",
          "customerManagedEncryption":{
            "kmsKeyName":"projects/${KMS_PROJECT_ID}/locations/us-central1/keyRings/secret-manager-cmek/cryptoKeys/my-cmek-key"
          }
        }
      ]
    }
  }
}
EOF

これで、そのシークレットにシークレット バージョンが作成されるたびに、サービス アカウントが CMEK 鍵にアクセスできる限り、永続ストレージに書き込まれる前に、その鍵を使用してシークレット バージョンのペイロードが自動的に暗号化されます。サービス アカウントがアクセスできなくなったり、鍵が使用できなくなったりした場合、新しいシークレット バージョンを作成しようとしたり、既存のシークレット バージョンにアクセスしようとしたりするとエラーが返されます。

新しいシークレット バージョンを追加します。Cloud KMS 鍵のリソース名は指定しないでください。シークレットのメタデータから読み取ります。

gcloud

$ echo -n "abcd1234" | gcloud beta secrets versions add "my-ummr-secret" \
    --project "${SM_PROJECT_ID}" \
    --data-file -

呼び出し元に CMEK 鍵を使用する直接なアクセス権がない場合でも、シークレット バージョンが作成されます。呼び出し元ではなく、Secret Manager のサービス アカウントが、シークレットの読み取り時または書き込み時に暗号化と復号を行います。

同様に、シークレットにアクセスするために CMEK 鍵への直接なアクセス権は必要ありません。サービス アカウントがその鍵にアクセスし、ユーザーに代わってシークレットを暗号化または復号します。

作成したシークレット バージョンにアクセスします。

gcloud

$ gcloud beta secrets versions access latest \
    --project "${SM_PROJECT_ID}" \
    --secret "my-ummr-secret"

CMEK 構成の更新

シークレットと同じリージョンに 2 つの新しい対称 KMS 鍵を作成します。

gcloud

# us-east1
$ gcloud kms keys create "my-other-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-east1" \
    --keyring "secret-manager-cmek" \
    --purpose "encryption"

# us-central1
$ gcloud kms keys create "my-other-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-central1" \
    --keyring "secret-manager-cmek" \
    --purpose "encryption"

サービス アカウントに Secret Manager のアクセス権を付与し、新しい CMEK 鍵を使用して暗号化と復号を行います。このコマンドは、my-other-key Cloud KMS 鍵の Cloud KMS 暗号化 / 復号のロール(roles/cloudkms.cryptoKeyEncrypterDecrypter)をサービス アカウントに付与します。

gcloud

# us-east1
$ gcloud kms keys add-iam-policy-binding "my-other-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-east1" \
    --keyring "secret-manager-cmek" \
    --member "serviceAccount:${SM_SERVICE_ACCOUNT}" \
    --role "roles/cloudkms.cryptoKeyEncrypterDecrypter"

# us-central1
$ gcloud kms keys add-iam-policy-binding "my-other-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-central1" \
    --keyring "secret-manager-cmek" \
    --member "serviceAccount:${SM_SERVICE_ACCOUNT}" \
    --role "roles/cloudkms.cryptoKeyEncrypterDecrypter"

新しい Cloud KMS 鍵のリソース名でシークレットのレプリケーションを更新し、シークレットの CMEK 構成を変更します。

gcloud

$ gcloud beta secrets replication update my-ummr-secret \
    --set-kms-key="projects/${KMS_PROJECT_ID}/locations/us-east1/keyRings/secret-manager-cmek/cryptoKeys/my-other-key" \
    --location=us-east1 \
    --project "${SM_PROJECT_ID}"

$ gcloud beta secrets replication update my-ummr-secret \
    --set-kms-key="projects/${KMS_PROJECT_ID}/locations/us-central1/keyRings/secret-manager-cmek/cryptoKeys/my-other-key" \
    --location=us-central1 \
    --project "${SM_PROJECT_ID}"

シークレットの複数のキーを同時に更新するには、ファイル経由でレプリケーション ポリシーを取得して設定します。

gcloud

$ gcloud beta secrets replication get my-ummr-secret --project "${SM_PROJECT_ID}" --format=json > replication-policy.json

# update the file to reflect desired CMEK configuration
$ edit replication-policy json

$ gcloud beta secrets replication set my-ummr-secret \
    --replication-policy-file=replication-policy.json \
    --project "${SM_PROJECT_ID}"

API

$ curl "https://secretmanager.googleapis.com/v1/projects/${SM_PROJECT_ID}/secrets/my-ummr-secret?updateMask=replication" \
    --request "PATCH" \
    --header "Authorization: Bearer $(gcloud auth print-access-token)" \
    --header "Content-Type: application/json" \
    --data-binary @- <<EOF
{
  "replication":{
    "userManaged":{
      "replicas":[
        {
          "location":"us-east1",
          "customerManagedEncryption":{
            "kmsKeyName":"projects/${KMS_PROJECT_ID}/locations/us-east1/keyRings/secret-manager-cmek/cryptoKeys/my-other-key"
          }
        },
        {
          "location":"us-central1",
          "customerManagedEncryption":{
            "kmsKeyName":"projects/${KMS_PROJECT_ID}/locations/us-central1/keyRings/secret-manager-cmek/cryptoKeys/my-other-key"
          }
        }]
      }
    }
  }
EOF

シークレット バージョンの CMEK 構成の表示

シークレット バージョンが CMEK 対応かどうか、および CMEK 鍵のバージョンのリソース名を含む、シークレット バージョンのメタデータを検査し、そのメタデータを表示します。

gcloud

$ gcloud beta secrets versions describe latest --secret my-secret --project "${SM_PROJECT_ID}"

API

$ curl "https://secretmanager.googleapis.com/v1/projects/${SM_PROJECT_ID}/secrets/my-secret/versions/latest" \
    --request "GET" \
    --header "Authorization: Bearer $(gcloud auth print-access-token)" \
    --header "Content-Type: application/json"

これにより、シークレット バージョンの暗号化に使用された鍵バージョンの Cloud KMS リソース名全体が返されます。

{
  "name": "projects/[PROJECT_NUMBER]/secrets/my-secret/versions/1",
  "createTime": "2020-07-...",
  "state": "ENABLED",
  "replicationStatus": {
    "automatic": {
      "customerManagedEncryption": {
        "kmsKeyVersionName": "projects/[KMS_PROJECT]/locations/global/keyRings/secret-manager-cmek/cryptoKeys/my-cmek-key/cryptoKeyVersions/1"
      }
    }
  }
}

CMEK の無効化

レプリケーション ポリシーを更新して、シークレットから CMEK 構成を削除します。

gcloud

$ gcloud beta secrets replication update my-secret --remove-cmek --project "${SM_PROJECT_ID}"

API

$ curl "https://secretmanager.googleapis.com/v1/projects/${SM_PROJECT_ID}/secrets/my-secret?updateMask=replication" \
    --request "PATCH" \
    --header "Authorization: Bearer $(gcloud auth print-access-token)" \
    --header "Content-Type: application/json" \
    --data-binary @- <<EOF
{
  "replication":{
    "automatic":{}
  }
}
EOF

次のステップ

  • CMEK の詳細を見る。