Menggunakan kunci enkripsi yang dikelola pelanggan (CMEK)

Halaman ini menjelaskan cara melakukan tugas yang terkait dengan kunci enkripsi yang dikelola pelanggan (CMEK) untuk Firestore. Untuk mengetahui informasi selengkapnya tentang CMEK secara umum, termasuk kapan dan mengapa harus mengaktifkannya, lihat dokumentasi Cloud KMS.

Menyiapkan kunci CMEK

Sebelum dapat membuat database Firestore yang dilindungi CMEK, Anda harus menyelesaikan langkah-langkah berikut:

  1. Membuat (atau mengambil) agen layanan Firestore.
  2. Buat kunci CMEK.
  3. Konfigurasikan setelan IAM untuk kunci tersebut.

Selesaikan langkah-langkah ini untuk setiap project yang akan berisi database Firestore yang dilindungi CMEK. Jika nantinya membuat kunci CMEK baru, Anda harus mengonfigurasi setelan IAM untuk kunci tersebut.

Membuat agen layanan Firestore

Sebelum membuat kunci CMEK, Anda harus memiliki agen layanan Firestore, yang merupakan jenis akun layanan yang dikelola Google yang digunakan Firestore untuk mengakses kunci tersebut.

Jalankan perintah services identity create untuk membuat agen layanan yang digunakan Firestore untuk mengakses kunci CMEK atas nama Anda. Perintah ini akan membuat akun layanan jika belum ada, lalu menampilkannya.

gcloud beta services identity create \
    --service=firestore.googleapis.com \
    --project FIRESTORE_PROJECT

Ganti FIRESTORE_PROJECT dengan project yang ingin Anda gunakan untuk database Firestore.

Perintah tersebut menampilkan ID agen layanan, yang diformat seperti alamat email. Catat {i>string<i} email {i>output<i}, karena Anda akan menggunakannya di langkah selanjutnya.

Service identity created:
service-xxx@gcp-sa-firestore.iam.gserviceaccount.com

Buat kunci

Anda dapat menggunakan kunci yang dibuat langsung di Cloud KMS atau kunci yang dikelola secara eksternal yang Anda sediakan dengan Cloud External Key Manager.

Lokasi kunci Cloud KMS harus sama dengan lokasi database Firestore yang akan digunakan.

  • Untuk lokasi database regional, gunakan nama lokasi yang sama untuk key ring, kunci, dan database karena nama lokasi memiliki pemetaan one-to-one.

    Misalnya, jika Anda ingin membuat database yang dilindungi CMEK di us-west1, buat key ring dan kunci di us-west1.

  • Untuk lokasi database multi-region, gunakan nama lokasi lokasi multi-region KMS:

    • Gunakan lokasi multi-region us Cloud KMS untuk lokasi multi-region nam5 Firestore.
    • Gunakan lokasi multi-region europe Cloud KMS untuk lokasi multi-region eur3 Firestore.

Di project Google Cloud tempat Anda ingin mengelola kunci, selesaikan langkah-langkah berikut:

  1. Aktifkan Cloud KMS API.

  2. Buat key ring dan kunci menggunakan salah satu opsi berikut:

Konfigurasi setelan IAM untuk kunci

Konsol

Untuk memberikan peran Cloud KMS kepada agen layanan Anda, lakukan hal berikut. Anda juga dapat memberikan izin pada tingkat kunci atau key-ring jika menginginkan tingkat perincian yang lebih rendah.

  1. Di konsol Google Cloud, buka halaman IAM.

    Buka halaman IAM

  2. Klik Tambahkan.

  3. Masukkan ID berformat email untuk agen layanan Firestore Anda.

  4. Pilih peran Cloud KMS CryptoKey Encrypter/Decrypter.

  5. Klik Save.

gcloud

  1. Berikan peran cloudkms.cryptoKeyEncrypterDecrypter kepada agen layanan Anda:

    gcloud kms keys add-iam-policy-binding KMS_KEY \
        --keyring KMS_KEYRING\
        --location KMS_LOCATION \
        --member serviceAccount:SERVICE_AGENT_EMAIL \
        --role roles/cloudkms.cryptoKeyEncrypterDecrypter \
        --project KMS_PROJECT
    

    Berikan hal berikut:

    • KMS_KEY: nama yang Anda tetapkan ke kunci
    • KMS_KEYRING: key ring KMS yang berisi kunci
    • KMS_LOCATION : wilayah yang berisi key ring
    • SERVICE_AGENT_EMAIL: ID berformat email untuk agen layanan yang Anda beri akses
    • KMS_PROJECT: project yang berisi kunci

    Terminal akan menampilkan respons yang mirip dengan berikut ini:

    Updated IAM policy for key KMS_KEY.
    bindings:
    - members:
      - serviceAccount:
        service-{project-number}@gcp-sa-firestore.iam.gserviceaccount.com
    role: roles/cloudkms.cryptoKeyEncrypterDecrypter
    

Membuat database yang mendukung CMEK

Setelah kunci CMEK dibuat dan dikonfigurasi, Anda dapat membuat database yang dilindungi CMEK. Database Firestore yang ada dan dilindungi oleh enkripsi default Google tidak dapat dikonversi untuk menggunakan CMEK; Anda hanya dapat memilih jenis dan kunci enkripsi pada saat pembuatan.

gcloud

gcloud alpha firestore databases create --location=FIRESTORE_DATABASE_LOCATION \
      --database=DATABASE_ID \
      --kms-key-name=KMS_KEY_NAME \
      --project=FIRESTORE_PROJECT

Berikan hal berikut:

  • FIRESTORE_DATABASE_LOCATION: lokasi Firestore untuk database
  • DATABASE_ID: ID untuk database
  • KMS_KEY_NAME: nama yang Anda tetapkan ke kunci. Gunakan nama resource lengkap untuk kunci dalam format:

    projects/KMS_PROJECT/locations/KMS_LOCATION/keyRings/KMS_KEYRING_ID/cryptoKeys/KMS_KEY_ID

  • FIRESTORE_PROJECT: project yang akan digunakan untuk database Firestore Anda

REST API

Permintaan HTTP:

POST https://firestore.googleapis.com/v1/projects/{FIRESOTRE_PROJECT}/databases

Dalam isi permintaan, konfigurasikan CMEK di kolom cmek_config.kms_key_name.

Tetapkan ke ID resource lengkap kunci Cloud KMS. Hanya kunci yang berada di lokasi sama dengan database ini yang diizinkan.

Nilai ini harus berupa ID resource kunci Cloud KMS dalam format projects/{KMS_PROJECT}/locations/{KMS_LOCATION}/keyRings/{KMS_KEYRING_ID}/cryptoKeys/{KMS_KEY_ID}

Untuk mengetahui detail selengkapnya tentang kolom lain, lihat halaman database create.

Contoh permintaan:

curl -X POST 'https://firestore.googleapis.com/v1/projects/FIRESTORE_PROJECT/databases?databaseId={DATABASE_ID}' \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-type: application/json" \
-d '{
  "type":"FIRESTORE_NATIVE",
  "locationId":"{FIRESTORE_DATABASE_LOCATION}",
  "cmekConfig": {
    "kmsKeyName":"projects/KMS_PROJECT/locations/KMS_LOCATION/keyRings/KMS_KEYRING_ID/cryptoKeys/KMS_KEY_ID"
  }
}'

Terraform

Untuk membuat database yang mendukung CMEK, gunakan resource google_firestore_database. Untuk mengetahui informasi dan contoh selengkapnya, lihat google_firestore_database.

resource "google_firestore_database" "database" {
  project     = "FIRESTORE_PROJECT"
  name        = "DATABASE_ID"
  location_id = "FIRESTORE_DATABASE_LOCATION"
  type        = "DATABASE_TYPE"

  cmek_config {
    kms_key_name = "KMS_KEY_NAME"
  }

}

Berikan hal berikut:

  • FIRESTORE_PROJECT: project yang akan digunakan untuk database Firestore Anda
  • DATABASE_ID: ID untuk database
  • FIRESTORE_DATABASE_LOCATION: lokasi Firestore untuk database
  • DATABASE_TYPE: FIRESTORE_NATIVE untuk mode Native atau DATASTORE_MODE untuk mode Datastore.
  • KMS_KEY_NAME: nama yang Anda tetapkan ke kunci. Gunakan nama resource lengkap untuk kunci dalam format:

    projects/KMS_PROJECT/locations/KMS_LOCATION/keyRings/KMS_KEYRING_ID/cryptoKeys/KMS_KEY_ID

Mengakses database yang dilindungi CMEK

Semua operasi baca, tulis, dan kueri yang dikirim ke database yang dilindungi CMEK harus berfungsi sama seperti database terenkripsi default Google. Anda tidak perlu, misalnya, menyediakan kunci untuk setiap permintaan.

Melihat kunci yang digunakan

gcloud

Anda dapat menggunakan perintah gcloud CLI databases explain untuk mengonfirmasi konfigurasi CMEK database:

gcloud firestore databases describe --database=DATABASE_ID --project=FIRESTORE_PROJECT

Anda akan melihat informasi CMEK di kolom cmekConfig dalam respons yang mirip dengan berikut ini:

cmekConfig:
    activeKeyVersion:
    - projects/PROJECT_ID/locations/us/keyRings/KEYRING_NAME/cryptoKeys/KEY_NAME/cryptoKeyVersions/1
    kmsKeyName: projects/PROJECT_ID/locations/us/keyRings/KEYRING_NAME/cryptoKeys/KEY_NAME
  locationId: nam5
  name: projects/PROJECT_ID/databases/DATABASE_ID

Respons mencakup informasi berikut:

  • kmsKeyName: nama resource kunci lengkap dari kunci yang digunakan untuk mengenkripsi database yang dilindungi CMEK.
  • activeKeyVersion: daftar semua versi kunci yang saat ini digunakan oleh database yang dilindungi CMEK. Selama rotasi kunci, mungkin terdapat beberapa versi kunci aktif.

REST API

Permintaan HTTP:

GET https://firestore.googleapis.com/v1/{name=projects/FIRESTORE_PROJECT/databases/DATABASE_ID}

Dalam isi permintaan, konfigurasikan CMEK di kolom cmek_config.kms_key_name. Tetapkan ke ID resource lengkap kunci Cloud KMS. Hanya kunci yang berada di lokasi sama dengan database ini yang diizinkan.

Nilai ini harus berupa ID resource kunci Cloud KMS dalam format projects/{KMS_PROJECT}/locations/{KMS_LOCATION}/keyRings/{KMS_KEYRING_ID}/cryptoKeys/{KMS_KEY_ID}

Untuk mengetahui detail selengkapnya tentang kolom lain, lihat halaman database create.

Contoh permintaan dan respons:

curl 'https://firestore.googleapis.com/v1/projects/FIRESTORE_PROJECT/databases/{DATABASE_ID}' \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-type: application/json"

—----------------------------------------- Response —--------------------------------------------
{
  "name": "projects/FIRESTORE_PROJECT/databases/{DATABASE_ID}",
  "locationId": "{FIRESTORE_DATABASE_LOCATION}",
  "type": "FIRESTORE_NATIVE",
  "cmekConfig": {
    "kmsKeyName": "projects/{KMS_PROJECT}/locations/{KMS_LOCATION}/keyRings/{KMS_KEYRING_ID}/cryptoKeys/{KMS_KEY_ID}",
    "activeKeyVersion": [
      "projects/{KMS_PROJECT}/locations/{KMS_LOCATION}/keyRings/{KMS_KEYRING_ID}/cryptoKeys/{KMS_KEY_ID}/cryptoKeyVersions/1"
    ]
  },
  ……
}

Menonaktifkan kunci

Untuk menonaktifkan kunci yang terkait dengan database, lakukan langkah-langkah berikut:

  1. Melihat versi kunci yang digunakan untuk database
  2. Menonaktifkan versi kunci tersebut
  3. Tunggu hingga perubahan diterapkan dan periksa apakah data tidak lagi dapat diakses. Perubahan biasanya diterapkan dalam beberapa menit, tetapi dapat memerlukan waktu hingga 3 jam.

Jika kunci yang digunakan oleh database dinonaktifkan, Anda akan menerima pengecualian FAILED_PRECONDITION dengan detail tambahan dalam pesan error, misalnya:

{
  "error": {
    "code": 400,
    "message": "The customer-managed encryption key required by the requested resource is not accessible. Error reason:  generic::permission_denied: Permission 'cloudkms.cryptoKeyVersions.useToEncrypt' denied on resource 'projects/FIRESTORE_PROJECT/locations/{KMS_LOCATION}/keyRings/{KMS_KEYRING_ID}/cryptoKeys/{KMS_KEY_ID}' (or it may not exist).",
    "status": "FAILED_PRECONDITION",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.DebugInfo",
        "detail": "The customer-managed encryption key required by the requested resource is not accessible. Error reason:  generic::permission_denied: Permission 'cloudkms.cryptoKeyVersions.useToEncrypt' denied on resource 'projects/FIRESTORE_PROJECT/locations/{KMS_LOCATION}/keyRings/{KMS_KEYRING_ID}/cryptoKeys/{KMS_KEY_ID}' (or it may not exist)"
      }
    ]
  }
}

Mengaktifkan kunci

Untuk mengaktifkan kembali kunci yang terkait dengan database, selesaikan hal berikut:

  1. Melihat versi kunci yang digunakan untuk database
  2. Mengaktifkan versi kunci tersebut
  3. Tunggu hingga perubahan diterapkan dan periksa apakah data tidak lagi dapat diakses. Perubahan biasanya diterapkan dalam beberapa menit, tetapi dapat memerlukan waktu hingga 3 jam.

Melihat log audit untuk kunci Cloud KMS

Sebelum mengaktifkan log audit Akses Data Cloud KMS, Anda harus memahami Cloud Audit Logs.

Log audit Akses Data Cloud KMS menunjukkan kepada Anda saat Firestore atau produk lain yang dikonfigurasi untuk menggunakan kunci CMEK Anda melakukan panggilan enkripsi/dekripsi ke Cloud KMS. Firestore tidak mengeluarkan panggilan enkripsi/dekripsi pada setiap permintaan data, melainkan mempertahankan polling yang memeriksa kunci secara berkala. Hasil polling akan muncul di log audit.

Anda dapat menyiapkan dan berinteraksi dengan log audit di Konsol Google Cloud:

  1. Pastikan logging diaktifkan untuk Cloud KMS API dalam project Anda.

  2. Buka Cloud Logging di konsol Google Cloud.

    Buka Cloud Logging

  3. Batasi entri log ke kunci Cloud KMS Anda dengan menambahkan baris berikut ke Builder kueri:

    resource.type="cloudkms_cryptokey"
    resource.labels.key_ring_id = KMS_KEYRING
    resource.labels.crypto_key_id = KMS_KEY
    resource.labels.location=KMS_LOCATION
    

    Berikan hal berikut:

    • KMS_KEY: nama kunci CMEK
    • KMS_KEYRING: key ring KMS yang berisi kunci
    • KMS_LOCATION: lokasi kunci dan key ring

    Log tersebut menampilkan beberapa entri log setiap lima menit per database. Entri log terlihat mirip dengan contoh berikut:

    Info 2021-03-20 08:02:24.869 EDT Cloudkms.googleapis.com Decrypt projects/cloud-kms-project/locations/us-central1/keyRings/firestore-keys/cryptoKeys/my-cmek-key service-123456789123@gcp-sa-firestore.iam.gserviceaccount.com
    audit_log, method: "Decrypt", principal_email: "service-1234567891011@gcp-sa-firestore.iam.gserviceaccount.com"
    
    Info 2021-03-20 08:02:24.913 EDT Cloudkms.googleapis.com Encrypt projects/cloud-kms-project/locations/us-central1/keyRings/firestore-keys/cryptoKeys/my-cmek-key service-123456789123@gcp-sa-firestore.iam.gserviceaccount.com
    audit_log, method: "Encrypt", principal_email: "service-123456789123@gcp-sa-firestore.iam.gserviceaccount.com"
    

Lihat Memahami log audit untuk detail tentang cara menafsirkan log audit.

Mengonfigurasi kebijakan organisasi CMEK

Untuk menentukan persyaratan kepatuhan enkripsi untuk database Firestore di organisasi Anda, gunakan batasan kebijakan organisasi CMEK.

Memerlukan perlindungan CMEK

Konfigurasi constraints/gcp.restrictNonCmekServices guna mewajibkan CMEK untuk pembuatan database Firestore. Tetapkan batasan ke deny, lalu tambahkan firestore.googleapis.com ke daftar tolak, misalnya:

 gcloud resource-manager org-policies deny gcp.restrictNonCmekServices  is:firestore.googleapis.com --project=FIRESTORE_PROJECT

Ganti FIRESTORE_PROJECT dengan project yang akan dibatasi.

Untuk mempelajari lebih lanjut cara mengonfigurasi kebijakan organisasi, lihat Membuat dan mengedit kebijakan.

Setelah kebijakan berlaku, Anda akan menerima pengecualian dan pesan error FAILED_PRECONDITION jika mencoba membuat database non-CMEK pada project yang terpengaruh. Misalnya, pengecualian akan terlihat seperti ini:

{
  "error": {
    "code": 400,
    "message": "Constraint 'constraints/gcp.restrictNonCmekServices' violated for 'projects/FIRESTORE_PROJECT' attempting to perform the operation 'google.firestore.admin.v1.FirestoreAdmin.CreateDatabase' with violated value 'firestore.googleapis.com'. See https://cloud.google.com/resource-manager/docs/organization-policy/org-policy-constraints for more information.",
    "status": "FAILED_PRECONDITION",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.PreconditionFailure",
        "violations": [
          {
            "type": "constraints/gcp.restrictNonCmekServices",
            "subject": "orgpolicy:projects/FIRESTORE_PROJECT",
            "description": "Constraint 'constraints/gcp.restrictNonCmekServices' violated for 'projects/FIRESTORE_PROJECT' attempting to perform the operation 'google.firestore.admin.v1.FirestoreAdmin.CreateDatabase' with violated value 'firestore.googleapis.com'. See https://cloud.google.com/resource-manager/docs/organization-policy/org-policy-constraints for more information."
          }
        ]

Membatasi penggunaan kunci untuk CMEK

Untuk membatasi kunci Cloud KMS yang digunakan untuk perlindungan CMEK, konfigurasikan batasan constraints/gcp.restrictCmekCryptoKeyProjects.

Sebagai batasan daftar, nilai yang diterima adalah indikator hierarki resource (misalnya projects/PROJECT_ID, under:folders/FOLDER_ID, dan under:organizations/ORGANIZATION_ID). Gunakan batasan ini dengan mengonfigurasi daftar indikator hierarki resource dan menetapkan batasan ke Izinkan. Konfigurasi ini membatasi layanan yang didukung sehingga kunci CMEK hanya dapat dipilih dari project, folder, dan organisasi yang tercantum. Permintaan untuk membuat resource yang dilindungi CMEK dalam layanan yang dikonfigurasi tidak akan berhasil tanpa kunci Firestore dari salah satu resource yang diizinkan.

Contoh berikut hanya mengizinkan kunci dari ALLOWED_KEY_PROJECT_ID untuk database yang dilindungi CMEK dalam project yang ditentukan:

gcloud resource-manager org-policies allow gcp.restrictCmekCryptoKeyProjects \
under:projects/ALLOWED_KEY_PROJECT_ID \
--project=FIRESTORE_PROJECT

Setelah kebijakan berlaku, Anda akan menerima pengecualian dan pesan error FAILED_PRECONDITION jika melanggar batasan. Pengecualian akan terlihat seperti berikut:

{
  "error": {
    "code": 400,
    "message": "Constraint 'constraints/gcp.restrictCmekCryptoKeyProjects' violated for 'projects/FIRESTORE_PROJECT' attempting to perform the operation 'google.firestore.admin.v1.FirestoreAdmin.CreateDatabase' with violated value 'projects/{NOT_ALLOWED_KEY_PROJECT}'. See https://cloud.google.com/resource-manager/docs/organization-policy/org-policy-constraints for more information.",
    "status": "FAILED_PRECONDITION",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.PreconditionFailure",
        "violations": [
          {
            "type": "constraints/gcp.restrictCmekCryptoKeyProjects",
            "subject": "orgpolicy:projects/FIRESTORE_PROJECT",
            "description": "Constraint 'constraints/gcp.restrictCmekCryptoKeyProjects' violated for 'projects/FIRESTORE_PROJECT' attempting to perform the operation 'google.firestore.admin.v1.FirestoreAdmin.CreateDatabase' with violated value 'projects/{NOT_ALLOWED_KEY_PROJECT}'. See https://cloud.google.com/resource-manager/docs/organization-policy/org-policy-constraints for more information."
          }
        ]
      }
    ]
  }
}

Langkah selanjutnya