๊ณ ๊ฐ ๊ด๋ฆฌ ์ํธํ ํค(CMEK) ์ฌ์ฉ
์ด ํ์ด์ง์์๋ Firestore์ฉ ๊ณ ๊ฐ ๊ด๋ฆฌ ์ํธํ ํค (CMEK)์ ๊ด๋ จ๋ ์์ ์ ์ํํ๋ ๋ฐฉ๋ฒ์ ์ค๋ช ํฉ๋๋ค. CMEK๋ฅผ ์ฌ์ฉ ์ค์ ํ๋ ์๊ธฐ์ ์ด์ ๋ฅผ ํฌํจํ ์ผ๋ฐ์ ์ธ CMEK์ ๋ํ ์์ธํ ๋ด์ฉ์ Cloud KMS ๋ฌธ์๋ฅผ ์ฐธ์กฐํ์ธ์.
CMEK ํค ์ค๋น
CMEK๋ก ๋ณดํธ๋๋ Firestore ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ง๋ค๋ ค๋ฉด ๋จผ์ ๋ค์ ๋จ๊ณ๋ฅผ ์๋ฃํด์ผ ํฉ๋๋ค.
- Firestore CMEK ๊ธฐ๋ฅ์ ๋ํ ์ก์ธ์ค๋ฅผ ์์ฒญํฉ๋๋ค.
- Firestore ์๋น์ค ์์ด์ ํธ๋ฅผ ๋ง๋ค๊ฑฐ๋ ๊ฐ์ ธ์ต๋๋ค.
- CMEK ํค๋ฅผ ๋ง๋ญ๋๋ค.
- ํด๋น ํค์ IAM ์ค์ ์ ๊ตฌ์ฑํฉ๋๋ค.
CMEK๋ก ๋ณดํธ๋๋ Firestore ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ํฌํจํ ํ๋ก์ ํธ๋ง๋ค ๋ค์ ๋จ๊ณ๋ฅผ ์๋ฃํฉ๋๋ค. ๋์ค์ ์ CMEK ํค๋ฅผ ๋ง๋ค๋ฉด ํด๋น ํค์ ๋ํ IAM ์ค์ ์ ๊ตฌ์ฑํด์ผ ํฉ๋๋ค.
์ก์ธ์ค ์์ฒญ
Firestore ์๋น์ค ์์ด์ ํธ๋ฅผ ๋ง๋ค๊ธฐ ์ ์ ์ด ์์์ ์์ฑํ์ฌ CMEK ๊ธฐ๋ฅ์ ๋ํ ์ก์ธ์ค๋ฅผ ์์ฒญํ์ธ์.
Firestore ์๋น์ค ์์ด์ ํธ ๋ง๋ค๊ธฐ
CMEK ํค๋ฅผ ๋ง๋ค๊ธฐ ์ ์ Firestore ์๋น์ค ์์ด์ ํธ๊ฐ ์์ด์ผ ํ๋๋ฐ ์ด๋ Firestore๊ฐ ํค์ ์ก์ธ์คํ๋ ๋ฐ ์ฌ์ฉํ๋ Google ๊ด๋ฆฌ ์๋น์ค ๊ณ์ ์ ์ ํ์ ๋๋ค.
services identity create ๋ช ๋ น์ด๋ฅผ ์คํํ์ฌ Firestore์์ ์ฌ์ฉ์ ๋์ CMEK ํค์ ์ก์ธ์คํ๋ ๋ฐ ์ฌ์ฉํ๋ ์๋น์ค ์์ด์ ํธ๋ฅผ ๋ง๋ญ๋๋ค. ์ด ๋ช ๋ น์ด๋ ์๋น์ค ๊ณ์ ์ด ์์ง ์กด์ฌํ์ง ์๋ ๊ฒฝ์ฐ ํด๋น ๊ณ์ ์ ๋ง๋ ํ ํ์ํฉ๋๋ค.
gcloud beta services identity create \ --service=firestore.googleapis.com \ --project FIRESTORE_PROJECT
FIRESTORE_PROJECT
๋ฅผ Firestore ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฌ์ฉํ ํ๋ก์ ํธ๋ก ๋ฐ๊ฟ๋๋ค.
์ด ๋ช ๋ น์ด๋ ์ด๋ฉ์ผ ์ฃผ์์ ๊ฐ์ ํ์์ ์๋น์ค ์์ด์ ํธ ID๋ฅผ ํ์ํฉ๋๋ค. ๋์ค ๋จ๊ณ์์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ์ถ๋ ฅ ์ด๋ฉ์ผ ๋ฌธ์์ด์ ๊ธฐ๋กํฉ๋๋ค.
Service identity created: service-xxx@gcp-sa-firestore.iam.gserviceaccount.com
ํค ๋ง๋ค๊ธฐ
Cloud KMS์์ ์ง์ ์์ฑ๋ ํค ๋๋ Cloud ์ธ๋ถ ํค ๊ด๋ฆฌ์์์ ์ฌ์ฉํ ์ ์๋ ์ธ๋ถ ๊ด๋ฆฌ ํค๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
Cloud KMS ํค ์์น๋ ํจ๊ป ์ฌ์ฉํ Firestore ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์์น์ ๋์ผํด์ผ ํฉ๋๋ค.
๋ฆฌ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์น์ ๊ฒฝ์ฐ ์์น ์ด๋ฆ์ ์ผ๋์ผ ๋งคํ์ด ์์ผ๋ฏ๋ก ํค๋ง, ํค, ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋์ผํ ์์น ์ด๋ฆ์ ์ฌ์ฉํฉ๋๋ค.
์๋ฅผ ๋ค์ด
us-west1
์ CMEK๋ก ๋ณดํธ๋๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ง๋ค๋ ค๋ฉดus-west1
์ ํค๋ง๊ณผ ํค๋ฅผ ๋ง๋ญ๋๋ค.๋ฉํฐ ๋ฆฌ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์น์ ๊ฒฝ์ฐ์๋ KMS ๋ฉํฐ ๋ฆฌ์ ์์น์ ์์น ์ด๋ฆ์ ์ฌ์ฉํฉ๋๋ค.
- Firestore
nam5
๋ฉํฐ ๋ฆฌ์ ์์น์ Cloud KMSus
๋ฉํฐ ๋ฆฌ์ ์์น๋ฅผ ์ฌ์ฉํฉ๋๋ค. - Firestore
eur3
๋ฉํฐ ๋ฆฌ์ ์์น์ Cloud KMSeurope
๋ฉํฐ ๋ฆฌ์ ์์น๋ฅผ ์ฌ์ฉํฉ๋๋ค.
- Firestore
ํค๋ฅผ ๊ด๋ฆฌํ Google Cloud ํ๋ก์ ํธ์์ ๋ค์์ ์๋ฃํฉ๋๋ค.
๋ค์ ์ต์ ์ค ํ๋๋ฅผ ์ฌ์ฉํ์ฌ ํค๋ง๊ณผ ํค๋ฅผ ๋ง๋ญ๋๋ค.
- Cloud KMS์์ ์ง์ ํค๋ง๊ณผ ํค๋ฅผ ๋ง๋ญ๋๋ค.
- ์ธ๋ถ ๊ด๋ฆฌ ํค๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ธ๋ถ ํค๋ฅผ ๋ง๋ ํ Cloud EKM ํค๋ฅผ ์์ฑํ์ฌ Cloud KMS๋ฅผ ํตํด ํค๋ฅผ ์ ๊ณตํฉ๋๋ค.
ํค์ IAM ์ค์ ๊ตฌ์ฑ
์ฝ์
์๋น์ค ์์ด์ ํธ์ Cloud KMS ์ญํ ์ ๋ถ์ฌํ๋ ค๋ฉด ๋ค์์ ์ํํฉ๋๋ค. ๋ ๋ฎ์ ์ธ๋ถํ๋ฅผ ์ํ๋ ๊ฒฝ์ฐ ํค ๋๋ ํค๋ง ์์ค์์ ๊ถํ์ ๋ถ์ฌํ ์๋ ์์ต๋๋ค.
Google Cloud ์ฝ์์์ IAM ํ์ด์ง๋ก ์ด๋ํฉ๋๋ค.
์ถ๊ฐ๋ฅผ ํด๋ฆญํฉ๋๋ค.
Firestore ์๋น์ค ์์ด์ ํธ์ ์ด๋ฉ์ผ ํ์ ID๋ฅผ ์ ๋ ฅํฉ๋๋ค.
Cloud KMS CryptoKey ์ํธํ/๋ณตํธํ ์ญํ ์ ์ ํํฉ๋๋ค.
์ ์ฅ์ ํด๋ฆญํฉ๋๋ค.
gcloud
์๋น์ค ์์ด์ ํธ์ cloudkms.cryptoKeyEncrypterDecrypter
์ญํ ์ ๋ถ์ฌํฉ๋๋ค.
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
๋ค์์ ๋ฐ๊ฟ๋๋ค.
KMS_KEY
: ํค์ ํ ๋นํ ์ด๋ฆKMS_KEYRING
: ํค๊ฐ ํฌํจ๋ KMS ํค๋งKMS_LOCATION
:ํค๋ง์ด ํฌํจ๋ ๋ฆฌ์ SERVICE_AGENT_EMAIL
: ์ก์ธ์ค ๊ถํ์ ๋ถ์ฌํ๋ ์๋น์ค ์์ด์ ํธ์ ์ด๋ฉ์ผ ํ์ ์๋ณ์KMS_PROJECT
: ํค๊ฐ ํฌํจ๋ ํ๋ก์ ํธ
ํฐ๋ฏธ๋์ ๋ค์๊ณผ ์ ์ฌํ ์๋ต์ด ํ์๋ฉ๋๋ค.
Updated IAM policy for key KMS_KEY.
bindings:
- members:
- serviceAccount:
service-{project-number}@gcp-sa-firestore.iam.gserviceaccount.com
role: roles/cloudkms.cryptoKeyEncrypterDecrypter
CMEK ์ง์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ง๋ค๊ธฐ
CMEK ํค๋ฅผ ๋ง๋ค๊ณ ๊ตฌ์ฑํ ํ์๋ CMEK๋ก ๋ณดํธ๋๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค. Google ๊ธฐ๋ณธ ์ํธํ๋ก ๋ณดํธ๋๋ ๊ธฐ์กด Firestore ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ CMEK๋ฅผ ์ฌ์ฉํ๋๋ก ๋ณํํ ์ ์์ต๋๋ค.
CMEK ์ง์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ง๋ค ๋๋ง ์ํธํ ์ ํ๊ณผ ํค๋ฅผ ์ ํํ ์ ์์ต๋๋ค.
์ฝ์
Google Cloud ์ฝ์์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ์ด์ง๋ก ์ด๋ํฉ๋๋ค.
๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ง๋ค๊ธฐ๋ฅผ ํด๋ฆญํฉ๋๋ค.
๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ชจ๋๋ฅผ ์ ํํฉ๋๋ค. ๊ณ์์ ํด๋ฆญํฉ๋๋ค.
๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ตฌ์ฑ ํ์ด์ง์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ID๋ฅผ ์ ๋ ฅํฉ๋๋ค.
์ง์ญ์ ์ ํํฉ๋๋ค.
์ํธํ ์ต์ ํ์๋ฅผ ํด๋ฆญํ ๋ค์ Cloud KMS ํค๋ฅผ ์ ํํฉ๋๋ค.
๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฌ์ฉํ CMEK ํค์ ๋ฆฌ์์ค ์ด๋ฆ์ ์ ํํ๊ฑฐ๋ ์ ๋ ฅํฉ๋๋ค.
ํค ๋ชฉ๋ก์ ํ์ฌ Google Cloud ํ๋ก์ ํธ ๋ฐ ์ ํํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์น๋ก ์ ํ๋ฉ๋๋ค. ๋ค๋ฅธ Google Cloud ํ๋ก์ ํธ์ ํค๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด ํ๋ก์ ํธ ์ ํ ๋๋ ํค ์๋ ์ ๋ ฅ์ ํด๋ฆญํฉ๋๋ค.
Firestore ์๋น์ค ๊ณ์ ์ ํค ๊ถํ์ ๋ถ์ฌํ๋ผ๋ ๋ฉ์์ง๊ฐ ํ์๋๋ฉด ๊ถํ ๋ถ์ฌ๋ฅผ ํด๋ฆญํฉ๋๋ค. CMEK ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ง๋ค๋ ค๋ฉด Firestore ์๋น์ค ๊ณ์ ์
cloudkms.cryptoKeyEncrypterDecrypter
์ญํ ์ด ๋ถ์ฌ๋์ด์ผ ํฉ๋๋ค.๋ชจ๋ฐ์ผ ๋ฐ ์น ํด๋ผ์ด์ธํธ์ ๋ณด์ ๊ท์น์ ์ ํํฉ๋๋ค.
๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ง๋ค๊ธฐ๋ฅผ ํด๋ฆญํฉ๋๋ค.
๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ์์ฑ๋๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ธ๋ถ์ ๋ณด๋ฅผ ํ์ธํ์ฌ ํด๋น ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ CMEK ์ฌ์ฉ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ธ์ง ํ์ธํ ์ ์์ต๋๋ค.
- ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ CMEK๋ก ๋ณดํธ๋๋ ๊ฒฝ์ฐ ์ํธํ ์ ํ ํ๋๊ฐ ๊ณ ๊ฐ ๊ด๋ฆฌ๋ก ํ์๋๊ณ ์ํธํ ํค ํ๋์๋ ํด๋น Cloud KMS์ ์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ณดํธํ๋ ๋ฐ ์ฌ์ฉ๋๋ ํค ๋ฒ์ ์ด ํ์๋ฉ๋๋ค.
- ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ CMEK๋ก ๋ณดํธ๋์ง ์์ผ๋ฉด ์ํธํ ์ ํ ํ๋๊ฐ Google ๊ด๋ฆฌ๋ก ํ์๋ฉ๋๋ค.
gcloud
Google Cloud CLI๋ก CMEK ์ง์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ง๋ค๊ธฐ ์ ์ ์ต์ ๋ฒ์ ์ ์ค์นํ๊ณ gcloud CLI๋ฅผ ์น์ธํฉ๋๋ค. ์์ธํ ๋ด์ฉ์ gcloud CLI ์ค์น๋ฅผ ์ฐธ์กฐํ์ธ์.
gcloud firestore databases create --location=FIRESTORE_DATABASE_LOCATION \
--database=DATABASE_ID \
--kms-key-name=KMS_KEY_NAME \
--project=FIRESTORE_PROJECT
๋ค์์ ๋ฐ๊ฟ๋๋ค.
FIRESTORE_DATABASE_LOCATION
: ๋ฐ์ดํฐ๋ฒ ์ด์ค์ Firestore ์์นDATABASE_ID
: ๋ฐ์ดํฐ๋ฒ ์ด์ค์ IDKMS_KEY_NAME
: ํค์ ํ ๋นํ ์ด๋ฆ ๋ค์ ํ์์ผ๋ก ๋ ํค์ ์ ์ฒด ๋ฆฌ์์ค ์ด๋ฆ์ ์ฌ์ฉํฉ๋๋ค.projects/KMS_PROJECT/locations/KMS_LOCATION/keyRings/KMS_KEYRING_ID/cryptoKeys/KMS_KEY_ID
FIRESTORE_PROJECT
: Firestore ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฌ์ฉํ ํ๋ก์ ํธ
REST API
HTTP ์์ฒญ:
POST https://firestore.googleapis.com/v1/projects/{FIRESTORE_PROJECT}/databases
์์ฒญ ๋ณธ๋ฌธ์ cmek_config.kms_key_name
ํ๋์์ CMEK๋ฅผ ๊ตฌ์ฑํฉ๋๋ค.
Cloud KMS ํค์ ์ ์ฒด ๋ฆฌ์์ค ID๋ก ์ค์ ํฉ๋๋ค. ์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋์ผํ ์์น์ ํค๋ง ํ์ฉ๋๊ธฐ ๋๋ฌธ์ ๋๋ค.
์ด ๊ฐ์ projects/{KMS_PROJECT}/locations/{KMS_LOCATION}/keyRings/{KMS_KEYRING_ID}/cryptoKeys/{KMS_KEY_ID}
ํ์์ Cloud KMS ํค ๋ฆฌ์์ค ID์ฌ์ผ ํฉ๋๋ค.
๋ค๋ฅธ ํ๋์ ๊ดํ ์์ธํ ๋ด์ฉ์ database create
ํ์ด์ง๋ฅผ ์ฐธ๊ณ ํ์ธ์.
์์ฒญ ์์:
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"
}
}'
Firebase CLI
CMEK ์ง์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ง๋ค๋ ค๋ฉด KMS ํค ์ด๋ฆ ํ๋๋ฅผ ์ฌ์ฉํ์ธ์. --kms-key-name
ํ๋ผ๋ฏธํฐ๋ฅผ ์ง์ ํ์ง ์์ผ๋ฉด Firestore์์ ๊ธฐ๋ณธ์ ์ผ๋ก CMEK๊ฐ ์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ง๋ญ๋๋ค.
firebase firestore:databases:create DATABASE_ID
--location LOCATION
--kms-key-name projects/KMS_PROJECT/locations/KMS_LOCATION/keyRings/KMS_KEYRING_ID/cryptoKeys/KMS_KEY_ID
--project FIRESTORE_PROJECT
๋ค์์ ๋ฐ๊ฟ๋๋ค.
DATABASE_ID
: ๋ฐ์ดํฐ๋ฒ ์ด์ค IDLOCATION
: ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์นKMS_PROJECT
: CMEK ํค๊ฐ ํฌํจ๋ ํ๋ก์ ํธKMS_LOCATION
: CMEK ํค ๋ฐ ํค๋ง์ด ํฌํจ๋ ์์นKMS_KEYRING_ID
: CMEK ํค๋ง์ IDFIRESTORE_PROJECT
: Firestore ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฌ์ฉํ ํ๋ก์ ํธ
Firestore ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ Firebase CLI๋ก ๋ณดํธ๋๋์ง ํ์ธํฉ๋๋ค.
firebase firestore:databases:get DATABASE_ID --project FIRESTORE_PROJECT
์๋ต ๋ฉ์์ง์ ๋ค์ CMEK ์ ๋ณด๊ฐ ํ์๋ฉ๋๋ค.
- KMS ํค ์ด๋ฆ ํ๋๋ Firestore CMEK ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ํธํํ๋ ๋ฐ ์ฌ์ฉ๋๋ ์ ์ฒด ํค ๋ฆฌ์์ค ์ด๋ฆ์ ์ ๊ณตํฉ๋๋ค.
- ํ์ฑ ํค ๋ฒ์ ํ๋๋ ์ด CMEK ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ํ์ฌ ์ฌ์ฉ ์ค์ธ ๋ชจ๋ ํค ๋ฒ์ ์ ๋ชฉ๋ก์ ์ ๊ณตํฉ๋๋ค. ํค ์ํ ์ค์ ์ฌ๋ฌ ํ์ฑ ํค ๋ฒ์ ์ด ์์ ์ ์์ต๋๋ค.
Terraform
CMEK ์ง์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ง๋ค๋ ค๋ฉด google_firestore_database
๋ฆฌ์์ค๋ฅผ ์ฌ์ฉํ์ธ์. ์์ธํ ๋ด์ฉ ๋ฐ ์๋ 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"
}
}
๋ค์์ ๋ฐ๊ฟ๋๋ค.
FIRESTORE_PROJECT
: Firestore ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฌ์ฉํ ํ๋ก์ ํธDATABASE_ID
: ๋ฐ์ดํฐ๋ฒ ์ด์ค์ IDFIRESTORE_DATABASE_LOCATION
: ๋ฐ์ดํฐ๋ฒ ์ด์ค์ Firestore ์์นDATABASE_TYPE
: ๊ธฐ๋ณธ ๋ชจ๋์ ๊ฒฝ์ฐFIRESTORE_NATIVE
, Datastore ๋ชจ๋์ ๊ฒฝ์ฐDATASTORE_MODE
KMS_KEY_NAME
: ํค์ ํ ๋นํ ์ด๋ฆ ๋ค์ ํ์์ผ๋ก ๋ ํค์ ์ ์ฒด ๋ฆฌ์์ค ์ด๋ฆ์ ์ฌ์ฉํฉ๋๋ค.projects/KMS_PROJECT/locations/KMS_LOCATION/keyRings/KMS_KEYRING_ID/cryptoKeys/KMS_KEY_ID
CMEK ๋ณดํธ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ก์ธ์ค
CMEK ๋ณดํธ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ก ์ ์ก๋๋ ๋ชจ๋ ์ฝ๊ธฐ, ์ฐ๊ธฐ, ์ฟผ๋ฆฌ ์์ ์ Google ๊ธฐ๋ณธ ์ํธํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์์ ๋์ผํ๊ฒ ์๋ํด์ผ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด ๊ฐ ์์ฒญ์ ๋ํ ํค๋ฅผ ์ ๊ณตํ ํ์๊ฐ ์์ต๋๋ค.
CMEK ๋ณดํธ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ณต์
๋ฐฑ์ ์์ CMEK ๋ณดํธ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ณต์ํ๊ธฐ ์ ์ ๋ค์์ ์ํํฉ๋๋ค.
- ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ CMEK ์ํธํ๋ก ๋ณต์ํ ์ง, Google์ ๊ธฐ๋ณธ ์ํธํ(CMEK๊ฐ ์๋)๋ก ๋ณต์ํ ์ง, ๋ฐฑ์ ๊ณผ ๋์ผํ ์ํธํ๋ก ๋ณต์ํ ์ง ๊ฒฐ์ ํฉ๋๋ค.
๋ฐฑ์ ์ ์ํธํํ๋ ๋ฐ ์ฌ์ฉํ ํค(primary-version)์ ํค ๋ฒ์ ์ ์ค๋นํฉ๋๋ค. ํค์ ํค ๋ฒ์ ์ ๋ชจ๋ ์ฌ์ฉ ์ค์ ํฉ๋๋ค.
gcloud
CMEK ๋ณดํธ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ CMEK ์ํธํ๋ก ๋ณต์
CMEK ์ํธํ๋ก ๋ณต์ํ๋ ค๋ฉด ์ ํ์ฌํญ์ธ encryption-type
๋ฐ kms-key-name
ํ๋๊ทธ์ ํจ๊ป gcloud firestore databases restore ๋ช
๋ น์ด๋ฅผ ์คํํ์ฌ ๋ณต์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ํธํ ์ ํ์ ๊ตฌ์ฑํฉ๋๋ค. ์ํธํ ์ ํ์ ์ง์ ํ์ง ์์ผ๋ฉด ๋ณต์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๋ฐฑ์
๊ณผ ๋์ผํ ์ํธํ ๊ตฌ์ฑ์ ์ฌ์ฉํฉ๋๋ค.
gcloud firestore databases restore
--encryption-type=customer-managed-encryption
--kms-key-name=KMS_KEY_NAME
KMS_KEY_NAME
์ ํค์ ํ ๋นํ ์ด๋ฆ์ผ๋ก ๋ฐ๊ฟ๋๋ค. ๋ค์ ํ์์ผ๋ก ๋ ํค์ ์ ์ฒด ๋ฆฌ์์ค ์ด๋ฆ์ ์ฌ์ฉํฉ๋๋ค.
projects/KMS_PROJECT/locations/KMS_LOCATION/keyRings/KMS_KEYRING_ID/cryptoKeys/KMS_KEY_ID
CMEK ๋ณดํธ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๊ธฐ๋ณธ ์ํธํ๋ก ๋ณต์
Google์ ๊ธฐ๋ณธ ์ํธํ(CMEK๊ฐ ์๋)๋ก ๋ณต์ํ๋ ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด encryption-type
ํ๋๊ทธ๋ฅผ ์ค์ ํฉ๋๋ค.
gcloud firestore databases restore
--encryption-type=google-default-encryption
CMEK ๋ณดํธ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ฐฑ์ ๊ณผ ๋์ผํ ์ํธํ ์ ํ์ผ๋ก ๋ณต์
๋ฐฑ์
๊ณผ ๋์ผํ ์ํธํ ์ ํ์ผ๋ก ๋ณต์ํ๋ ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด encryption-type
ํ๋๊ทธ๋ฅผ ์ค์ ํ์ธ์.
gcloud firestore databases restore --encryption-type=use-source-encryption
Firebase CLI
CMEK ๋ณดํธ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ CMEK ์ํธํ๋ก ๋ณต์
CMEK ์ํธํ๋ก ๋ณต์ํ๋ ค๋ฉด ์ ํ์ encryption-type
๋ฐ kms-key-name
ํ๋๊ทธ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
์ํธํ ์ ํ์ ์ง์ ํ์ง ์์ผ๋ฉด ๋ณต์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๋ฐฑ์
๊ณผ ๋์ผํ ์ํธํ ๊ตฌ์ฑ์ ์ฌ์ฉํฉ๋๋ค.
firebase firestore:databases:restore \
--database DATABASE_ID \
--backup 'projects/FIRESTORE_PROJECT/locations/FIRESTORE_LOCATION/backups/BACKUP_ID' \
--encryption-type CUSTOMER_MANAGED_ENCRYPTION \
--kms-key-name projects/KMS_PROJECT/locations/KMS_LOCATION/keyRings/KMS_KEYRING_ID/cryptoKeys/KMS_KEY_ID \
--project FIRESTORE_PROJECT
๋ค์์ ๋ฐ๊ฟ๋๋ค.
DATABASE_ID
: ๋ฐ์ดํฐ๋ฒ ์ด์ค IDFIRESTORE_PROJECT
: Firestore ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฌ์ฉํ ํ๋ก์ ํธFIRESTORE_LOCATION
: Firestore ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์์นBACKUP_ID
: ๋ฐฑ์ ์ IDKMS_PROJECT
: CMEK ํค๊ฐ ํฌํจ๋ ํ๋ก์ ํธKMS_LOCATION
: CMEK ํค ๋ฐ ํค๋ง์ด ํฌํจ๋ ์์นKMS_KEYRING_ID
: CMEK ํค๋ง์ ID
๋ณต์๋ Firestore ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ CMEK๋ก ์ํธํ๋์๋์ง ํ์ธํฉ๋๋ค.
firebase firestore:databases:get DATABASE_ID --project FIRESTORE_PROJECT
CMEK ๋ณดํธ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๊ธฐ๋ณธ ์ํธํ๋ก ๋ณต์
Google์ ๊ธฐ๋ณธ ์ํธํ(CMEK๊ฐ ์๋)๋ก ๋ณต์ํ๋ ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด encryption-type
ํ๋๊ทธ๋ฅผ ์ค์ ํฉ๋๋ค.
firebase firestore:databases:restore \
--database DATABASE_ID \
--backup 'projects/FIRESTORE_PROJECT/locations/FIRESTORE_LOCATION/backups/BACKUP_ID' \
--encryption-type GOOGLE_DEFAULT_ENCRYPTION \
--project FIRESTORE_PROJECT
๋ค์์ ๋ฐ๊ฟ๋๋ค.
DATABASE_ID
: ๋ฐ์ดํฐ๋ฒ ์ด์ค IDFIRESTORE_PROJECT
: Firestore ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฌ์ฉํ ํ๋ก์ ํธFIRESTORE_LOCATION
: Firestore ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์์นBACKUP_ID
: ๋ฐฑ์ ์ ID
CMEK ๋ณดํธ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ฐฑ์ ๊ณผ ๋์ผํ ์ํธํ ์ ํ์ผ๋ก ๋ณต์
๋ฐฑ์
๊ณผ ๋์ผํ ์ํธํ ์ ํ์ผ๋ก ๋ณต์ํ๋ ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด encryption-type
ํ๋๊ทธ๋ฅผ ์ค์ ํ์ธ์.
firebase firestore:databases:restore \
--database DATABASE_IDD \
--backup 'projects/FIRESTORE_PROJECT/locations/FIRESTORE_LOCATION/backups/BACKUP_ID' \
--encryption-type USE_SOURCE_ENCRYPTION
๋ค์์ ๋ฐ๊ฟ๋๋ค.
DATABASE_ID
: ๋ฐ์ดํฐ๋ฒ ์ด์ค IDFIRESTORE_PROJECT
: Firestore ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฌ์ฉํ ํ๋ก์ ํธFIRESTORE_LOCATION
: Firestore ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์์นBACKUP_ID
: ๋ฐฑ์ ์ ID
CMEK ๋ณดํธ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํด๋ก
CMEK ๋ณดํธ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ํด๋ก ํ๊ธฐ ์ ์ ๋ค์์ ์ํํฉ๋๋ค.
- ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ CMEK ์ํธํ๋ก ํด๋ก ํ ์ง, Google์ ๊ธฐ๋ณธ ์ํธํ (CMEK๊ฐ ์๋)๋ก ํด๋ก ํ ์ง, ์์ค ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋์ผํ ์ํธํ๋ก ํด๋ก ํ ์ง ๊ฒฐ์ ํฉ๋๋ค.
์์ค ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ํธํํ๋ ๋ฐ ์ฌ์ฉํ ํค (primary-version)์ ํค ๋ฒ์ ์ ์ค๋นํฉ๋๋ค. ํค์ ํค ๋ฒ์ ์ ๋ชจ๋ ์ฌ์ฉ ์ค์ ํฉ๋๋ค.
gcloud
CMEK ๋ณดํธ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ CMEK ์ํธํ๋ก ํด๋ก
CMEK ์ํธํ๋ก ํด๋ก ํ๋ ค๋ฉด ์ ํ์ฌํญ์ธ encryption-type
๋ฐ kms-key-name
ํ๋๊ทธ์ ํจ๊ป gcloud alpha firestore databases clone ๋ช
๋ น์ด๋ฅผ ์คํํ์ฌ ํด๋ก ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ํธํ ์ ํ์ ๊ตฌ์ฑํฉ๋๋ค. ์ํธํ ์ ํ์ ์ง์ ํ์ง ์์ผ๋ฉด ํด๋ก ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์์ค ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋์ผํ ์ํธํ ๊ตฌ์ฑ์ ์ฌ์ฉํฉ๋๋ค.
gcloud alpha firestore databases clone \
--encryption-type=customer-managed-encryption \
--kms-key-name=KMS_KEY_NAME
KMS_KEY_NAME
์ ํค์ ํ ๋นํ ์ด๋ฆ์ผ๋ก ๋ฐ๊ฟ๋๋ค. ๋ค์ ํ์์ผ๋ก ๋ ํค์ ์ ์ฒด ๋ฆฌ์์ค ์ด๋ฆ์ ์ฌ์ฉํฉ๋๋ค.
projects/KMS_PROJECT/locations/KMS_LOCATION/keyRings/KMS_KEYRING_ID/cryptoKeys/KMS_KEY_ID
CMEK ๋ณดํธ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๊ธฐ๋ณธ ์ํธํ๋ก ํด๋ก
Google์ ๊ธฐ๋ณธ ์ํธํ (CMEK๊ฐ ์๋)๋ก ํด๋ก ํ๋ ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด encryption-type
ํ๋๊ทธ๋ฅผ ์ค์ ํฉ๋๋ค.
gcloud alpha firestore databases clone \
--encryption-type=google-default-encryption
CMEK ๋ณดํธ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์์ค ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋์ผํ ์ํธํ ์ ํ์ผ๋ก ํด๋ก
์์ค ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋์ผํ ์ํธํ ์ ํ์ผ๋ก ํด๋ก ํ๋ ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด encryption-type
ํ๋๊ทธ๋ฅผ ์ค์ ํ์ธ์.
gcloud alpha firestore databases clone \
--encryption-type=use-source-encryption
์ฌ์ฉ ์ค์ธ ํค ๋ณด๊ธฐ
gcloud
databases describe gcloud CLI ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค CMEK ๊ตฌ์ฑ์ ํ์ธํ ์ ์์ต๋๋ค.
gcloud firestore databases describe --database=DATABASE_ID --project=FIRESTORE_PROJECT
์๋ต์ cmekConfig
ํ๋์ ๋ค์๊ณผ ์ ์ฌํ CMEK ์ ๋ณด๊ฐ ํ์๋ฉ๋๋ค.
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
์๋ต์๋ ๋ค์ ์ ๋ณด๊ฐ ํฌํจ๋ฉ๋๋ค.
kmsKeyName
: CMEK๋ก ๋ณดํธ๋๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ํธํํ๋ ๋ฐ ์ฌ์ฉ๋๋ ํค์ ์ ์ฒด ํค ๋ฆฌ์์ค ์ด๋ฆ.activeKeyVersion
: CMEK๋ก ๋ณดํธ๋๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ํ์ฌ ์ฌ์ฉ ์ค์ธ ๋ชจ๋ ํค ๋ฒ์ ์ ๋ชฉ๋ก. ํค ์ํ ์ค์ ์ฌ๋ฌ ํ์ฑ ํค ๋ฒ์ ์ด ์์ ์ ์์ต๋๋ค. ํค ์ํ ์ค์ ์ด์ ํค ๋ฒ์ ๊ณผ ์ ํค ๋ฒ์ ์ ๋ชจ๋ ์ฌ์ฉํ ์ ์์ด์ผ ํฉ๋๋ค. ์ด์ ํค ๋ฒ์ ์ด ๋ ์ด์activeKeyVersion
ํ๋์ ํ์๋์ง ์์ ๋๊น์ง๋ ์ฌ์ฉ ์ค์งํ์ง ๋ง์ธ์.
REST API
HTTP ์์ฒญ:
GET https://firestore.googleapis.com/v1/{name=projects/FIRESTORE_PROJECT/databases/DATABASE_ID}
์์ฒญ ๋ณธ๋ฌธ์ cmek_config.kms_key_name
ํ๋์์ CMEK๋ฅผ ๊ตฌ์ฑํฉ๋๋ค.
Cloud KMS ํค์ ์ ์ฒด ๋ฆฌ์์ค ID๋ก ์ค์ ํฉ๋๋ค. ์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋์ผํ ์์น์ ํค๋ง ํ์ฉ๋๊ธฐ ๋๋ฌธ์
๋๋ค.
์ด ๊ฐ์ projects/{KMS_PROJECT}/locations/{KMS_LOCATION}/keyRings/{KMS_KEYRING_ID}/cryptoKeys/{KMS_KEY_ID}
ํ์์ Cloud KMS ํค ๋ฆฌ์์ค ID์ฌ์ผ ํฉ๋๋ค.
๋ค๋ฅธ ํ๋์ ๊ดํ ์์ธํ ๋ด์ฉ์ database create
ํ์ด์ง๋ฅผ ์ฐธ๊ณ ํ์ธ์.
์์ฒญ ๋ฐ ์๋ต ์์:
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"
]
},
โฆโฆ
}
ํค ์ค์ง
๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฐ๊ฒฐ๋ ํค๋ฅผ ์ฌ์ฉ ์ค์งํ๋ ค๋ฉด ๋ค์ ๋จ๊ณ๋ฅผ ์๋ฃํ์ธ์.
- ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฌ์ฉ ์ค์ธ ํค ๋ฒ์ ๋ณด๊ธฐ
- ์ฌ์ฉ ์ค์ธ ํค ๋ฒ์ ์ฌ์ฉ ์ค์ง
- ๋ณ๊ฒฝ์ฌํญ์ด ์ ์ฉ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฐ ํ ๋ฐ์ดํฐ์ ๋ ์ด์ ์ก์ธ์คํ ์ ์๋์ง ํ์ธํฉ๋๋ค. ๋ณ๊ฒฝ์ฌํญ์ ์ผ๋ฐ์ ์ผ๋ก ๋ช ๋ถ ๋ด์ ์ ์ฉ๋์ง๋ง ์ต๋ 3์๊ฐ์ด ๊ฑธ๋ฆด ์ ์์ต๋๋ค.
๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ฌ์ฉํ๋ ํค๊ฐ ์ฌ์ฉ ์ค์ง๋๋ฉด ์ค๋ฅ ๋ฉ์์ง๋ก ์ถ๊ฐ ์ธ๋ถ์ ๋ณด์ ํจ๊ป FAILED_PRECONDITION
์์ธ๊ฐ ์์ ๋ฉ๋๋ค. ์๋ฅผ ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
{ "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)" } ] } }
ํค ์ฌ์ฉ ์ค์
๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฐ๊ฒฐ๋ ํค๋ฅผ ๋ค์ ์ฌ์ฉ ์ค์ ํ๋ ค๋ฉด ๋ค์ ๋จ๊ณ๋ฅผ ์๋ฃํ์ธ์.
- ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฌ์ฉ ์ค์ธ ํค ๋ฒ์ ๋ณด๊ธฐ
- ์ฌ์ฉ ์ค์ธ ํค ๋ฒ์ ์ฌ์ฉ ์ค์
- ๋ณ๊ฒฝ์ฌํญ์ด ์ ์ฉ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฐ ํ ๋ฐ์ดํฐ์ ๋ ์ด์ ์ก์ธ์คํ ์ ์๋์ง ํ์ธํฉ๋๋ค. ๋ณ๊ฒฝ์ฌํญ์ ์ผ๋ฐ์ ์ผ๋ก ๋ช ๋ถ ๋ด์ ์ ์ฉ๋์ง๋ง ์ต๋ 3์๊ฐ์ด ๊ฑธ๋ฆด ์ ์์ต๋๋ค.
Cloud KMS ํค์ ๊ฐ์ฌ ๋ก๊ทธ ๋ณด๊ธฐ
Cloud KMS ๋ฐ์ดํฐ ์ก์ธ์ค ๊ฐ์ฌ ๋ก๊ทธ๋ฅผ ์ฌ์ฉ ์ค์ ํ๊ธฐ ์ ์ Cloud ๊ฐ์ฌ ๋ก๊ทธ๋ฅผ ์์งํด์ผ ํฉ๋๋ค.
Cloud KMS ๋ฐ์ดํฐ ์ก์ธ์ค ๊ฐ์ฌ ๋ก๊ทธ๋ Firestore ๋๋ CMEK ํค๋ฅผ ์ฌ์ฉํ๋๋ก ๊ตฌ์ฑ๋ ๋ค๋ฅธ ์ ํ์ด Cloud KMS์ ์ํธํ/๋ณตํธํ ํธ์ถ์ ํ๋ ์์ ์ ๋ณด์ฌ์ค๋๋ค. Firestore๋ ๋ชจ๋ ๋ฐ์ดํฐ ์์ฒญ์ ์ํธํ/๋ณตํธํ ํธ์ถ์ ์คํํ์ง ์์ผ๋ฉฐ, ๋์ ์ ์ ๊ธฐ์ ์ผ๋ก ํค๋ฅผ ํ์ธํ๋ ํด๋ฌ๋ฅผ ์ ์งํฉ๋๋ค. ํด๋ง ๊ฒฐ๊ณผ๋ ๊ฐ์ฌ ๋ก๊ทธ์ ํ์๋ฉ๋๋ค.
Google Cloud ์ฝ์์์ ๊ฐ์ฌ ๋ก๊ทธ๋ฅผ ์ค์ ํ๊ณ ์ํธ์์ฉํ ์ ์์ต๋๋ค.
ํ๋ก์ ํธ์์ Cloud KMS API์ ๋ํด ๋ก๊น ์ด ์ฌ์ฉ ์ค์ ๋์๋์ง ํ์ธํฉ๋๋ค.
Google Cloud ์ฝ์์์ Cloud Logging์ผ๋ก ์ด๋ํฉ๋๋ค.
์ฟผ๋ฆฌ ๋น๋์ ๋ค์ ์ค์ ์ถ๊ฐํ์ฌ ๋ก๊ทธ ํญ๋ชฉ์ Cloud KMS๋ก ์ ํํฉ๋๋ค.
resource.type="cloudkms_cryptokey" resource.labels.key_ring_id = KMS_KEYRING resource.labels.crypto_key_id = KMS_KEY resource.labels.location=KMS_LOCATION
๋ค์์ ๋ฐ๊ฟ๋๋ค.
KMS_KEY
: CMEK ํค ์ด๋ฆKMS_KEYRING
: ํค๊ฐ ํฌํจ๋ KMS ํค๋งKMS_LOCATION
: ํค ๋ฐ ํค๋ง์ ์์น
๋ก๊ทธ์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋น ์ฝ 5๋ถ๋ง๋ค ์ผ๋ถ ๋ก๊ทธ ํญ๋ชฉ์ด ํ์๋ฉ๋๋ค. ๋ก๊ทธ ํญ๋ชฉ์ ๋ค์ ์์์ ์ ์ฌํ๊ฒ ํ์๋ฉ๋๋ค.
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"
๊ฐ์ฌ ๋ก๊ทธ ํด์์ ๋ํ ์์ธํ ๋ด์ฉ์ ๊ฐ์ฌ ๋ก๊ทธ ์ดํด๋ฅผ ์ฐธ์กฐํ์ธ์.
CMEK ์กฐ์ง ์ ์ฑ ๊ตฌ์ฑ
์กฐ์ง์ Firestore ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ํ ์ํธํ ๊ท์ ์ค์ ์๊ตฌ์ฌํญ์ ์ง์ ํ๋ ค๋ฉด CMEK ์กฐ์ง ์ ์ฑ ์ ์ฝ์กฐ๊ฑด์ ์ฌ์ฉํ์ธ์.
CMEK ๋ณดํธ ์๊ตฌ
Firestore ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ง๋ค๊ธฐ์ CMEK๋ฅผ ์๊ตฌํ๋๋ก constraints/gcp.restrictNonCmekServices
๋ฅผ ๊ตฌ์ฑํฉ๋๋ค. ์ ์ฝ์กฐ๊ฑด์ deny
๋ก ์ค์ ํ๊ณ ๊ฑฐ๋ถ ๋ชฉ๋ก์ firestore.googleapis.com
์ ์ถ๊ฐํฉ๋๋ค. ์๋ฅผ ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
gcloud resource-manager org-policies deny gcp.restrictNonCmekServices is:firestore.googleapis.com --project=FIRESTORE_PROJECT
FIRESTORE_PROJECT
๋ฅผ ์ ํํ ํ๋ก์ ํธ๋ก ๋ฐ๊ฟ๋๋ค.
์กฐ์ง ์ ์ฑ ๊ตฌ์ฑ์ ๋ํ ์์ธํ ๋ด์ฉ์ ์ ์ฑ ๋ง๋ค๊ธฐ ๋ฐ ์์ ์ ์ฐธ๊ณ ํ์ธ์.
์ ์ฑ
์ด ์ ์ฉ๋ ํ ์ํฅ์ ๋ฐ๋ ํ๋ก์ ํธ์ CMEK๊ฐ ์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ง๋ค๋ ค๊ณ ํ๋ฉด FAILED_PRECONDITION
์์ธ ๋ฐ ์ค๋ฅ ๋ฉ์์ง๊ฐ ํ์๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด ๋ค์๊ณผ ๊ฐ์ ์์ธ๊ฐ ์์ ๋ฉ๋๋ค.
{ "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." } ]
CMEK์ ๋ํ ํค ์ฌ์ฉ ์ ํ
CMEK ๋ณดํธ๋ฅผ ์ํด ์ฌ์ฉ๋๋ Cloud KMS ํค๋ฅผ ์ ํํ๋ ค๋ฉด constraints/gcp.restrictCmekCryptoKeyProjects
์ ์ฝ์กฐ๊ฑด์ ๊ตฌ์ฑํฉ๋๋ค.
๋ชฉ๋ก ์ ์ฝ์กฐ๊ฑด์ผ๋ก์ ํ์ฉ๋๋ ๊ฐ์ ๋ฆฌ์์ค ๊ณ์ธต ๊ตฌ์กฐ ํ์๊ธฐ์
๋๋ค(์:projects/PROJECT_ID
,under:folders/FOLDER_ID
, under:organizations/ORGANIZATION_ID
). ๋ฆฌ์์ค ๊ณ์ธต ๊ตฌ์กฐ ํ์๊ธฐ ๋ชฉ๋ก์ ๊ตฌ์ฑํ๊ณ ์ ์ฝ์กฐ๊ฑด์ ํ์ฉ์ผ๋ก ์ค์ ํ์ฌ ์ด ์ ์ฝ์กฐ๊ฑด์ ์ฌ์ฉํฉ๋๋ค.
์ด ๊ตฌ์ฑ์ ๋์ด๋ ํ๋ก์ ํธ, ํด๋, ์กฐ์ง์์๋ง CMEK ํค๋ฅผ ์ ํํ ์ ์๋๋ก ์ง์๋๋ ์๋น์ค๋ฅผ ์ ํํฉ๋๋ค. ํ์ฉ๋๋ ๋ฆฌ์์ค ์ค ํ๋์์ Firestore ํค๋ฅผ ์ฌ์ฉํ์ง ์์ผ๋ฉด ๊ตฌ์ฑ๋ ์๋น์ค์์ CMEK๋ก ๋ณดํธ๋๋ ๋ฆฌ์์ค๋ฅผ ๋ง๋ค๊ธฐ ์ํ ์์ฒญ์ด ์คํจํฉ๋๋ค.
๋ค์ ์์์์๋ ์ง์ ๋ ํ๋ก์ ํธ์ CMEK๋ก ๋ณดํธ๋๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ํด ALLOWED_KEY_PROJECT_ID์ ํค๋ง ํ์ฉํฉ๋๋ค.
gcloud resource-manager org-policies allow gcp.restrictCmekCryptoKeyProjects \ under:projects/ALLOWED_KEY_PROJECT_ID \ --project=FIRESTORE_PROJECT
์ ์ฑ
์ด ์ ์ฉ๋ ํ ์ ์ฝ์กฐ๊ฑด์ ์๋ฐํ๋ฉด FAILED_PRECONDITION
์์ธ ๋ฐ ์ค๋ฅ ๋ฉ์์ง๊ฐ ํ์๋ฉ๋๋ค. ๋ค์๊ณผ ๊ฐ์ ์์ธ๊ฐ ์์ ๋ฉ๋๋ค.
{ "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." } ] } ] } }