Cloud KMS 키로 데이터 보호

기본적으로 BigQuery는 미사용 상태로 저장된 고객 콘텐츠를 암호화합니다. BigQuery는 사용자의 추가 작업 없이 이 기본 암호화를 처리하고 관리합니다. 먼저 BigQuery 테이블에 있는 데이터는 데이터 암호화 키를 사용하여 암호화됩니다. 그럼 다음 이 데이터 암호화 키는 봉투 암호화라고 하는 키 암호화 키로 암호화됩니다. 키 암호화 키는 직접 데이터를 암호화하지는 않지만 Google에서 사용자의 데이터를 암호화할 때 사용하는 데이터 암호화 키를 암호화하는 데 사용됩니다. 자세한 내용은 키 관리를 참조하세요.

암호화를 직접 제어하려면 BigQuery용 고객 관리 암호화 키(CMEK)를 사용합니다. Google에서 사용자 데이터를 보호하는 키 암호화 키를 관리하지 않고 사용자가 Cloud KMS에서 키 암호화 키를 제어하고 관리할 수 있습니다. 이 주제에서는 이 기술에 대해 자세히 설명합니다.

Google Cloud Platform의 암호화 옵션에 대해 자세히 알아보세요.

시작하기 전에

  1. 데이터세트, 테이블, 쿼리를 파악합니다.

  2. BigQuery와 Cloud KMS를 동일한 GCP 프로젝트에서 실행할지 서로 다른 프로젝트에서 실행할지 결정합니다. 이 문서의 예시에서는 다음 규칙을 적용합니다.

    • [PROJECT_ID]는 BigQuery를 실행하는 프로젝트의 프로젝트 ID입니다.
    • [PROJECT_NUMBER]는 BigQuery를 실행하는 프로젝트의 프로젝트 번호입니다.
    • [KMS_PROJECT_ID]는 Cloud KMS를 실행하는 프로젝트의 프로젝트 ID입니다(BigQuery를 실행하는 프로젝트와 같은 경우도 해당).
    GCP 프로젝트 ID와 프로젝트 번호에 대한 자세한 내용은 프로젝트 확인을 참조하세요.

  3. 새 프로젝트에서는 BigQuery가 자동으로 사용 설정됩니다. 기존 프로젝트를 이용해 BigQuery를 실행하려면 BigQuery API를 사용 설정해야 합니다.

  4. Cloud KMS를 실행하는 GCP 프로젝트:

    1. Cloud KMS API를 사용 설정합니다.
    2. 키링 및 키 만들기에 설명된 대로 키링과 키를 만듭니다. BigQuery 데이터세트의 위치와 일치하는 위치에서 키링을 만듭니다.
      • 모든 다중 리전 데이터세트는 일치하는 위치의 다중 리전 키링을 사용해야 합니다. 예를 들어 US 리전에 있는 데이터세트는 us 리전의 키링으로 보호해야 하고, EU 리전에 있는 데이터세트는 europe 리전의 키링으로 보호해야 합니다.
      • 각 리전의 데이터세트는 일치하는 리전 키를 사용해야 합니다. 예를 들어 asia-northeast1 리전의 데이터세트는 asia-northeast1 리전의 키링으로 보호해야 합니다.
      • global 리전은 BigQuery로 사용할 수 없습니다.
      BigQuery와 Cloud KMS가 지원하는 위치에 대한 자세한 내용은 Cloud 위치를 참조하세요.

암호화 사양

BigQuery의 데이터 보호에 사용하는 Cloud KMS 키는 AES-256 키입니다. 이러한 키는 BigQuery에서 키 암호화 키로 사용되며, 사용자의 데이터를 암호화하는 데이터 암호화 키를 암호화하는 역할을 합니다.

암호화 및 복호화 권한 부여

Google Cloud Platform Console을 사용하여 BigQuery 서비스 계정 ID를 확인하고 Cloud KMS를 이용한 암호화 및 복호화에 필요한 역할을 서비스 계정에 부여하세요.

서비스 계정 ID 확인

웹 UI

  1. BigQuery 웹 UI로 이동합니다.

    BigQuery 웹 UI로 이동

  2. 탐색 창에서 프로젝트 이름 옆의 아래쪽 화살표 아이콘(아래쪽 화살표 아이콘)을 클릭한 다음 고객 관리 암호화를 클릭합니다.

  3. 그러면 암호화 및 복호화 권한이 필요한 서비스 계정을 안내하는 사용자 대화상자가 열립니다.

    서비스 계정 ID

  4. 서비스 계정 ID를 클립보드에 복사하려면 복사를 클릭하고 사용자 대화상자를 닫으려면 확인을 클릭합니다.

명령줄

bq show 명령어와 --encryption_service_account 플래그를 함께 사용하여 서비스 계정 ID를 확인할 수 있습니다.

bq show --encryption_service_account

이 명령어는 서비스 계정 ID를 표시합니다.

                       ServiceAccountID
     -------------------------------------------------------------
      bq-[PROJECT_NUMBER]@bigquery-encryption.iam.gserviceaccount.com

암호화/복호화 역할 할당

Cloud KMS CryptoKey Encrypter/Decrypter 역할을 클립보드에 복사한 BigQuery 시스템 서비스 계정에 할당합니다. 이 계정의 형식은 다음과 같습니다.

bq-[PROJECT_NUMBER]@bigquery-encryption.iam.gserviceaccount.com

웹 UI

  1. GCP Console에서 보안 페이지를 엽니다.

    보안 암호화 키 페이지를 엽니다.

  2. 프로젝트를 선택하고 계속을 클릭합니다.

  3. 역할을 추가할 암호화 키를 찾습니다.

    • bq-[PROJECT_NUMBER]@bigquery-encryption.iam.gserviceaccount.com 서비스 계정이 구성원 목록에 없으면 어떤 역할도 할당되지 않았다는 의미입니다. 구성원 추가를 클릭하고 서비스 계정의 이메일 주소 bq-[PROJECT_NUMBER]@bigquery-encryption.iam.gserviceaccount.com을 입력합니다.
    • 서비스 계정이 구성원 목록에 이미 있는 경우 기존 역할이 있는 것입니다. bq-[PROJECT_NUMBER]@bigquery-encryption.iam.gserviceaccount.com 서비스 계정의 현재 역할 드롭다운 목록을 클릭합니다.
  4. 역할의 드롭다운 목록에서 Cloud KMS를 클릭한 다음 Cloud KMS CryptoKey 암호화/복호화 역할을 클릭합니다.

  5. 추가 또는 저장을 클릭하여 역할을 bq-[PROJECT_NUMBER]@bigquery-encryption.iam.gserviceaccount.com 서비스 계정에 적용합니다.

명령줄

gcloud 명령줄 도구로 역할을 할당할 수 있습니다.

gcloud kms keys add-iam-policy-binding \
--project=[KMS_PROJECT_ID] \
--member serviceAccount:bq-[PROJECT_NUMBER]@bigquery-encryption.iam.gserviceaccount.com \
--role roles/cloudkms.cryptoKeyEncrypterDecrypter \
--location=[KMS_KEY_LOCATION] \
--keyring=[KMS_KEY_RING] \
[KMS_KEY]

[KMS_PROJECT_ID]를 Cloud KMS를 실행하는 GCP 프로젝트의 ID로 바꾸고 [PROJECT_NUMBER]를 BigQuery를 실행하는 GCP 프로젝트의 프로젝트 번호(프로젝트 ID가 아님)로 바꿉니다. [KMS_KEY_LOCATION], [KMS_KEY_RING], [KMS_KEY_RING], [KMS_KEY]는 Cloud KMS 키의 위치, 키링 및 키 이름으로 바꿉니다.

Cloud KMS로 보호되는 테이블 만들기

Cloud KMS로 보호되는 빈 테이블 만들기

Cloud KMS로 보호되는 테이블을 만드는 방법:

웹 UI

  1. BigQuery 웹 사용자 인터페이스에서 데이터세트 이름 옆의 아래쪽 화살표 아이콘(아래쪽 화살표 아이콘)을 클릭한 다음 새 테이블 만들기를 클릭합니다.

  2. 테이블 만들기 페이지에서 스키마 없이 빈 테이블 만들기스키마 정의가 있는 빈 테이블 만들기에 필요한 정보를 입력합니다. 테이블 만들기를 클릭하기 전에 암호화 유형을 설정하고 테이블과 함께 사용할 Cloud KMS 키를 지정해야 합니다.

    1. 암호화 유형의 드롭다운 목록을 클릭하고 고객 관리 암호화를 선택합니다.
    2. 고객 관리 암호화 키에 키의 리소스 ID를 입력합니다. 이 키의 형식은 다음과 같습니다.
      projects/[PROJECT_ID]/locations/[LOCATION]/keyRings/[KEYRING]/cryptoKeys/[KEY]
      
      키 리소스 ID를 검색하는 방법은 키 리소스 ID를 참조하세요.
  3. 테이블 만들기를 클릭합니다.

명령줄

bq 명령줄 도구를 --destination_kms_key 플래그와 함께 사용하여 테이블을 만들 수 있습니다. --destination_kms_key 플래그는 테이블과 함께 사용할 키의 리소스 ID를 지정합니다. 이 키의 형식은 다음과 같습니다.

projects/[PROJECT_ID]/locations/[LOCATION]/keyRings/[KEYRING]/cryptoKeys/[KEY]
키 리소스 ID를 검색하는 방법은 [키 리소스 ID](/kms/docs/object-hierarchy#key_resource_id)를 참조하세요. 스키마가 있는 빈 테이블을 만드는 방법:
bq mk --schema name:string,value:integer -t \
--destination_kms_key projects/[PROJECT_ID]/locations/[LOCATION]/keyRings/[KEYRING]/cryptoKeys/[KEY] \
mydataset.newtable

또는 DDL 문을 이용할 수도 있습니다.

bq query --use_legacy_sql=false "
  CREATE TABLE mydataset.newtable (name STRING, value INT64)
  OPTIONS(
    kms_key_name='projects/[PROJECT_ID]/locations/[LOCATION]/keyRings/[KEYRING]/cryptoKeys/[KEY]'
  )
"

쿼리에서 테이블을 만드는 방법:

bq query --destination_table=mydataset.newtable \
--destination_kms_key projects/[PROJECT_ID]/locations/[LOCATION]/keyRings/[KEYRING]/cryptoKeys/[KEY] \
"SELECT name,count FROM mydataset.babynames WHERE gender = 'M' ORDER BY count DESC LIMIT 6"

bq 명령줄 도구에 대한 자세한 내용은 bq 명령줄 도구를 참조하세요.

Go

// To run this sample, you will need to create (or reuse) a context and
// an instance of the bigquery client.  For example:
// import "cloud.google.com/go/bigquery"
// ctx := context.Background()
// client, err := bigquery.NewClient(ctx, "your-project-id")
tableRef := client.Dataset(datasetID).Table(tableID)
meta := &bigquery.TableMetadata{
	EncryptionConfig: &bigquery.EncryptionConfig{
		// TODO: Replace this key with a key you have created in Cloud KMS.
		KMSKeyName: "projects/cloud-samples-tests/locations/us-central1/keyRings/test/cryptoKeys/test",
	},
}
if err := tableRef.Create(ctx, meta); err != nil {
	return err
}

Python

테이블을 만들기 전에 Table.encryption_configuration 속성을 EncryptionConfiguration 객체로 설정하여 고객 관리 암호화 키로 새 테이블을 보호합니다.

# from google.cloud import bigquery
# client = bigquery.Client()
# dataset_id = 'my_dataset'

table_ref = client.dataset(dataset_id).table('my_table')
table = bigquery.Table(table_ref)

# Set the encryption key to use for the table.
# TODO: Replace this key with a key you have created in Cloud KMS.
kms_key_name = 'projects/{}/locations/{}/keyRings/{}/cryptoKeys/{}'.format(
    'cloud-samples-tests', 'us-central1', 'test', 'test')
table.encryption_configuration = bigquery.EncryptionConfiguration(
    kms_key_name=kms_key_name)

table = client.create_table(table)  # API request

assert table.encryption_configuration.kms_key_name == kms_key_name

Cloud KMS 키로 보호하는 테이블 쿼리

Cloud KMS로 보호되는 테이블을 쿼리할 때는 특별한 준비가 필요하지 않습니다. BigQuery는 테이블 콘텐츠 암호화에 사용한 키의 이름을 저장하여 Cloud KMS로 보호되는 테이블을 쿼리할 때 사용합니다.

BigQuery가 테이블 콘텐츠 암호화에 사용한 Cloud KMS 키에 액세스할 수 있는 한, 모든 기존 도구와 BigQuery 콘솔 및 bq 명령줄 인터페이스는 기본 암호화 테이블과 같은 방식으로 실행됩니다.

쿼리 결과를 Cloud KMS 키로 보호

웹 UI

  1. BigQuery 웹 사용자 인터페이스의 쿼리 작성 버튼을 클릭합니다.

  2. 새 쿼리 텍스트 영역에 유효한 BigQuery SQL 쿼리를 입력합니다.

  3. 암호화 유형을 클릭하고 고객 관리 암호화를 선택합니다.

  4. 고객 관리 암호화 키에 키의 리소스 ID를 입력합니다. 이 키의 형식은 다음과 같습니다.

    projects/[PROJECT_ID]/locations/[LOCATION]/keyRings/[KEYRING]/cryptoKeys/[KEY]
    
    키 리소스 ID를 검색하는 방법은 키 리소스 ID를 참조하세요.

  5. 쿼리 실행을 클릭합니다.

명령줄

--destination_kms_key 플래그를 지정하여 Cloud KMS로 대상 테이블이나 쿼리 결과(임시 테이블을 사용하는 경우)를 보호합니다. --destination_kms_key 플래그는 대상 테이블이나 결과 테이블과 함께 사용할 키의 리소스 ID를 지정합니다. 이 키의 형식은 다음과 같습니다.

projects/[PROJECT_ID]/locations/[LOCATION]/keyRings/[KEYRING]/cryptoKeys/[KEY]
키 리소스 ID를 검색하는 방법은 [키 리소스 ID](/kms/docs/object-hierarchy#key_resource_id)를 참조하세요. 필요에 따라 `--destination_table` 플래그를 사용하여 쿼리 결과의 대상을 지정할 수 있습니다. `--destination_table`을 사용하지 않는다면 쿼리 결과는 임시 테이블에 기록됩니다. 테이블을 쿼리하는 방법은 다음과 같습니다.
bq query \
--destination_table=mydataset.newtable \
--destination_kms_key projects/[PROJECT_ID]/locations/[LOCATION]/keyRings/[KEYRING]/cryptoKeys/[KEY] \
"SELECT name,count FROM mydataset.babynames WHERE gender = 'M' ORDER BY count DESC LIMIT 6"

bq 명령줄 도구에 대한 자세한 내용은 bq 명령줄 도구를 참조하세요.

Go

q := client.Query("SELECT 17 as my_col")
q.Location = "US" // Location must match the dataset(s) referenced in query.
q.QueryConfig.Dst = client.Dataset(destDatasetID).Table(destTableID)
q.DestinationEncryptionConfig = &bigquery.EncryptionConfig{
	// TODO: Replace this key with a key you have created in Cloud KMS.
	KMSKeyName: "projects/cloud-samples-tests/locations/us-central1/keyRings/test/cryptoKeys/test",
}
return runAndRead(ctx, client, q)
job, err := q.Run(ctx)
if err != nil {
	return err
}
status, err := job.Wait(ctx)
if err != nil {
	return err
}
if err := status.Err(); err != nil {
	return err
}
it, err := job.Read(ctx)
for {
	var row []bigquery.Value
	err := it.Next(&row)
	if err == iterator.Done {
		break
	}
	if err != nil {
		return err
	}
	fmt.Println(row)
}

Python

QueryJobConfig.destination_encryption_configuration 속성을 EncryptionConfiguration으로 설정하여 고객 관리 암호화 키로 쿼리 대상 테이블을 보호하고 쿼리를 실행합니다.

# from google.cloud import bigquery
# client = bigquery.Client()

job_config = bigquery.QueryJobConfig()

# Set the destination table. Here, dataset_id is a string, such as:
# dataset_id = 'your_dataset_id'
table_ref = client.dataset(dataset_id).table('your_table_id')
job_config.destination = table_ref

# Set the encryption key to use for the destination.
# TODO: Replace this key with a key you have created in KMS.
kms_key_name = 'projects/{}/locations/{}/keyRings/{}/cryptoKeys/{}'.format(
    'cloud-samples-tests', 'us-central1', 'test', 'test')
encryption_config = bigquery.EncryptionConfiguration(
    kms_key_name=kms_key_name)
job_config.destination_encryption_configuration = encryption_config

# Start the query, passing in the extra configuration.
query_job = client.query(
    'SELECT 17 AS my_col;',
    # Location must match that of the dataset(s) referenced in the query
    # and of the destination table.
    location='US',
    job_config=job_config)  # API request - starts the query
query_job.result()

# The destination table is written using the encryption configuration.
table = client.get_table(table_ref)
assert table.encryption_configuration.kms_key_name == kms_key_name

Cloud KMS로 보호되는 테이블 로드

Cloud KMS로 보호되는 테이블에 데이터 파일을 로드하는 방법:

Go

// To run this sample, you will need to create (or reuse) a context and
// an instance of the bigquery client.  For example:
// import "cloud.google.com/go/bigquery"
// ctx := context.Background()
// client, err := bigquery.NewClient(ctx, "your-project-id")
gcsRef := bigquery.NewGCSReference("gs://cloud-samples-data/bigquery/us-states/us-states.json")
gcsRef.SourceFormat = bigquery.JSON
gcsRef.AutoDetect = true
loader := client.Dataset(datasetID).Table(tableID).LoaderFrom(gcsRef)
loader.WriteDisposition = bigquery.WriteEmpty
loader.DestinationEncryptionConfig = &bigquery.EncryptionConfig{
	// TODO: Replace this key with a key you have created in KMS.
	KMSKeyName: "projects/cloud-samples-tests/locations/us-central1/keyRings/test/cryptoKeys/test",
}

job, err := loader.Run(ctx)
if err != nil {
	return err
}
status, err := job.Wait(ctx)
if err != nil {
	return err
}

if status.Err() != nil {
	return fmt.Errorf("Job completed with error: %v", status.Err())
}

Python

LoadJobConfig.destination_encryption_configuration 속성을 EncryptionConfiguration으로 설정하여 고객 관리 암호화 키로 로드 작업 대상 테이블을 보호하고 테이블을 로드합니다.

# from google.cloud import bigquery
# client = bigquery.Client()
# dataset_id = 'my_dataset'

dataset_ref = client.dataset(dataset_id)
job_config = bigquery.LoadJobConfig()
job_config.autodetect = True
job_config.source_format = bigquery.SourceFormat.NEWLINE_DELIMITED_JSON

# Set the encryption key to use for the destination.
# TODO: Replace this key with a key you have created in KMS.
kms_key_name = 'projects/{}/locations/{}/keyRings/{}/cryptoKeys/{}'.format(
    'cloud-samples-tests', 'us-central1', 'test', 'test')
encryption_config = bigquery.EncryptionConfiguration(
    kms_key_name=kms_key_name)
job_config.destination_encryption_configuration = encryption_config
uri = 'gs://cloud-samples-data/bigquery/us-states/us-states.json'

load_job = client.load_table_from_uri(
    uri,
    dataset_ref.table('us_states'),
    location='US',  # Location must match that of the destination dataset.
    job_config=job_config)  # API request

assert load_job.job_type == 'load'

load_job.result()  # Waits for table load to complete.

assert load_job.state == 'DONE'
table = client.get_table(dataset_ref.table('us_states'))
assert table.encryption_configuration.kms_key_name == kms_key_name

Cloud KMS로 보호되는 테이블에 스트리밍하기

추가 매개변수를 지정하지 않고도 CMEK로 보호되는 BigQuery 테이블에 데이터를 스트리밍할 수 있습니다. 이 데이터는 버퍼와 최종 위치 모두에서 Cloud KMS 키로 암호화됩니다. CMEK 테이블로 스트리밍하기 전에 키 사용성 및 접근성에 관한 요구사항을 검토하세요.

스트리밍에 대한 자세한 내용은 BigQuery로 데이터 스트리밍하기를 참조하세요.

테이블을 기본 암호화에서 Cloud KMS 보호로 변경

명령줄

bq cp 명령어를 --destination_kms_key 플래그와 함께 사용하면 기본 암호화로 보호하는 테이블을 새 테이블이나 Cloud KMS로 보호되는 원본 테이블에 복사할 수 있습니다. --destination_kms_key 플래그는 대상 테이블과 함께 사용할 키의 리소스 ID를 지정합니다. 이 키의 형식은 다음과 같습니다.

projects/[PROJECT_ID]/locations/[LOCATION]/keyRings/[KEYRING]/cryptoKeys/[KEY]

키 리소스 ID를 검색하는 방법은 키 리소스 ID를 참조하세요.

기본 암호화를 사용하는 테이블을 Cloud KMS 보호를 사용하는 새 테이블에 복사하는 방법:

bq cp \
--destination_kms_key projects/[PROJECT_ID]/locations/[LOCATION]/keyRings/[KEYRING]/cryptoKeys/[KEY] \
sourceDataset.sourceTableId destinationDataset.destinationTableId

기본 암호화를 사용하는 테이블을 Cloud KMS 보호를 사용하는 같은 테이블에 복사하는 방법:

bq cp -f \
--destination_kms_key projects/[PROJECT_ID]/locations/[LOCATION]/keyRings/[KEYRING]/cryptoKeys/[KEY] \
sourceDataset.sourceTableId sourceDataset.sourceTableId

Cloud KMS 보호를 사용하는 테이블을 기본 암호화로 변경하려면 --destination_kms_key 플래그를 사용하지 않고 bq cp를 실행하여 파일을 같은 파일에 복사합니다.

bq 명령줄 도구에 대한 자세한 내용은 bq 명령줄 도구를 참조하세요.

Go

// To run this sample, you will need to create (or reuse) a context and
// an instance of the bigquery client.  For example:
// import "cloud.google.com/go/bigquery"
// ctx := context.Background()
// client, err := bigquery.NewClient(ctx, "your-project-id")
srcTable := client.DatasetInProject("bigquery-public-data", "samples").Table("shakespeare")
copier := client.Dataset(datasetID).Table(tableID).CopierFrom(srcTable)
copier.DestinationEncryptionConfig = &bigquery.EncryptionConfig{
	// TODO: Replace this key with a key you have created in Cloud KMS.
	KMSKeyName: "projects/cloud-samples-tests/locations/us-central1/keyRings/test/cryptoKeys/test",
}
job, err := copier.Run(ctx)
if err != nil {
	return err
}
status, err := job.Wait(ctx)
if err != nil {
	return err
}
if err := status.Err(); err != nil {
	return err
}

Python

QueryJobConfig.destination_encryption_configuration 속성을 EncryptionConfiguration으로 설정하여 고객 관리 암호화 키로 테이블 복사 대상을 보호하고 테이블을 복사합니다.

# from google.cloud import bigquery
# client = bigquery.Client()

source_dataset = bigquery.DatasetReference(
    'bigquery-public-data', 'samples')
source_table_ref = source_dataset.table('shakespeare')

# dataset_id = 'my_dataset'
dest_dataset_ref = client.dataset(dataset_id)
dest_table_ref = dest_dataset_ref.table('destination_table')

# Set the encryption key to use for the destination.
# TODO: Replace this key with a key you have created in KMS.
kms_key_name = 'projects/{}/locations/{}/keyRings/{}/cryptoKeys/{}'.format(
    'cloud-samples-tests', 'us-central1', 'test', 'test')
encryption_config = bigquery.EncryptionConfiguration(
    kms_key_name=kms_key_name)
job_config = bigquery.CopyJobConfig()
job_config.destination_encryption_configuration = encryption_config

job = client.copy_table(
    source_table_ref,
    dest_table_ref,
    # Location must match that of the source and destination tables.
    location='US',
    job_config=job_config)  # API request
job.result()  # Waits for job to complete.

assert job.state == 'DONE'
dest_table = client.get_table(dest_table_ref)
assert dest_table.encryption_configuration.kms_key_name == kms_key_name

테이블이 Cloud KMS로 보호되는지 확인

  1. BigQuery 웹 사용자 인터페이스에서 데이터세트 왼쪽에 있는 파란색 화살표를 클릭하여 펼치거나 데이터세트 이름을 더블클릭합니다. 그러면 데이터세트에 있는 테이블과 뷰가 표시됩니다.

  2. 테이블 이름을 클릭합니다.

  3. 세부정보를 클릭하면, 테이블 세부정보 페이지에 테이블 설명과 테이블 정보가 표시됩니다.

  4. 테이블이 Cloud KMS로 보호된다면 고객 관리 암호화 키 필드에 키 리소스 ID가 표시됩니다.

    보호된 테이블

BigQuery 테이블의 Cloud KMS 키 변경

CMEK로 보호되는 기존 테이블의 Cloud KMS 키를 변경하려면 ALTER TABLE 쿼리를 실행하거나 API 또는 bq 명령줄 도구를 사용합니다. API 및 명령줄 도구를 사용하여 Cloud KMS 키를 수정하는 방법에는 update 또는 cp의 두 가지가 있습니다. update를 사용하면 KMS로 보호하는 테이블에 사용하는 Cloud KMS 키를 변경할 수 있습니다. cp를 사용하면 CMEK로 보호되는 테이블의 Cloud KMS 키를 변경하고, 테이블의 기본 암호화를 CMEK 보호로 변경하거나 CMEK 보호를 기본 암호화로 변경할 수 있습니다. update의 장점은 cp보다 빠르고 테이블 데코레이터를 사용할 수 있다는 점입니다.

기본 UI

이 키의 형식은 다음과 같습니다.

projects/[PROJECT_ID]/locations/[LOCATION]/keyRings/[KEYRING]/cryptoKeys/[KEY]

키 리소스 ID를 검색하는 방법은 키 리소스 ID를 참조하세요.

  1. BigQuery 웹 UI로 이동합니다.

    BigQuery 웹 UI로 이동

  2. 쿼리 작성을 클릭합니다.

  3. 새 쿼리 텍스트 영역에 DDL 문을 입력합니다.

     #standardSQL
     ALTER TABLE mydataset.mytable
     SET OPTIONS (
       kms_key_name="projects/[PROJECT_ID]/locations/[LOCATION]/keyRings/[KEYRING]/cryptoKeys/[KEY]"
     )
     

명령줄

bq cp 명령어를 --destination_kms_key 플래그와 함께 사용하면 Cloud KMS로 보호되는 테이블의 키를 변경할 수 있습니다. --destination_kms_key 플래그는 테이블과 함께 사용할 키의 리소스 ID를 지정합니다. 이 키의 형식은 다음과 같습니다.

projects/[PROJECT_ID]/locations/[LOCATION]/keyRings/[KEYRING]/cryptoKeys/[KEY]

키 리소스 ID를 검색하는 방법은 키 리소스 ID를 참조하세요.

bq update \
--destination_kms_key projects/[PROJECT_ID]/locations/[LOCATION]/keyRings/[KEYRING]/cryptoKeys/[KEY] \
-t [DATASET_ID].[TABLE_ID]

Go

// To run this sample, you will need to create (or reuse) a context and
// an instance of the bigquery client.  For example:
// import "cloud.google.com/go/bigquery"
// ctx := context.Background()
// client, err := bigquery.NewClient(ctx, "your-project-id")
tableRef := client.Dataset(datasetID).Table(tableID)
meta, err := tableRef.Metadata(ctx)
if err != nil {
	return err
}
update := bigquery.TableMetadataToUpdate{
	EncryptionConfig: &bigquery.EncryptionConfig{
		// TODO: Replace this key with a key you have created in Cloud KMS.
		KMSKeyName: "projects/cloud-samples-tests/locations/us-central1/keyRings/test/cryptoKeys/otherkey",
	},
}
if _, err := tableRef.Update(ctx, update, meta.ETag); err != nil {
	return err
}

Python

Table.encryption_configuration 속성을 새 EncryptionConfiguration 객체로 변경하여 테이블의 고객 관리 암호화 키를 변경하고 테이블을 업데이트합니다.

# from google.cloud import bigquery
# client = bigquery.Client()

assert table.encryption_configuration.kms_key_name == original_kms_key_name

# Set a new encryption key to use for the destination.
# TODO: Replace this key with a key you have created in KMS.
updated_kms_key_name = (
    'projects/cloud-samples-tests/locations/us-central1/'
    'keyRings/test/cryptoKeys/otherkey')
table.encryption_configuration = bigquery.EncryptionConfiguration(
    kms_key_name=updated_kms_key_name)

table = client.update_table(
    table, ['encryption_configuration'])  # API request

assert table.encryption_configuration.kms_key_name == updated_kms_key_name
assert original_kms_key_name != updated_kms_key_name

Cloud KMS 키에 대한 BigQuery의 액세스 권한 제거

Cloud KMS 키에 대한 IAM 권한을 취소하는 방법으로 언제든지 이 키에 대한 BigQuery의 액세스 권한을 제거할 수 있습니다.

BigQuery가 Cloud KMS 키에 액세스하지 못하면 사용자 경험이 크게 저하되고 데이터 손실이 발생할 수 있습니다.

  • CMEK로 보호되는 테이블의 데이터에 더 이상 액세스할 수 없습니다. query, cp, extract, tabledata.list는 모두 실패하게 됩니다.

  • CMEK로 보호되는 테이블에 새 데이터를 추가할 수 없습니다.

  • 액세스 권한이 다시 부여되더라도 이러한 테이블에 대한 쿼리 성능은 며칠간 저하될 수 있습니다.

Cloud KMS 키 순환이 미치는 영향

테이블과 연결된 Cloud KMS 키가 순환될 때 BigQuery는 테이블 암호화 키를 자동으로 순환하지 않습니다. 기존 테이블은 생성될 때 사용한 키 버전을 계속 사용합니다. 새 테이블은 현재 키 버전을 사용합니다.

제한사항

Cloud KMS 키에 대한 BigQuery 액세스 권한

다음과 같은 조건에서 BigQuery는 Cloud KMS 키를 사용하고 액세스할 수 있습니다.

  • 키가 사용 설정되어 있음
  • BigQuery 서비스 계정에 키에 대한 암호화 및 복호화 권한이 있음

다음 섹션에서는 키에 액세스할 수 없을 때 스트리밍 삽입 및 장기간 액세스 불가한 데이터에 미치는 영향을 설명합니다.

스트리밍 삽입에 미치는 영향

Cloud KMS 키는 스트리밍 삽입 요청 후 48시간 동안 최소 24시간 연속으로 사용하고 액세스할 수 있어야 합니다. 키를 사용하고 액세스할 수 없다면 스트리밍된 데이터가 완전히 유지되지 않으며 손실될 수도 있습니다. 스트리밍 삽입에 대한 자세한 내용은 BigQuery에 데이터 스트리밍하기를 참조하세요.

장기간 액세스 불가한 데이터에 미치는 영향

BigQuery는 관리형 저장소를 제공하기 때문에 장기간 액세스 불가한 데이터는 BigQuery의 아키텍처와 호환되지 않습니다. BigQuery 테이블의 Cloud KMS 키를 60일 연속으로 사용하고 액세스할 수 없으면 BigQuery는 테이블과 관련 데이터를 삭제할 수 있습니다. BigQuery는 데이터를 삭제하기 최소 7일 전에 결제 계정과 연결된 이메일 주소로 이메일을 보냅니다.

테이블 데코레이터 사용

load, cp, query 작업의 쓰기 처리 WRITE_TRUNCATE를 통해 Cloud KMS로 보호되는 테이블의 데이터를 바꾸면 스냅샷 데코레이터 시간에 따라 테이블 데코레이터를 통한 테이블 쿼리가 불가능할 수 있습니다.

테이블이 T 시간에 교체되었고 스냅샷 데코레이터 snapshot_time의 시간이 T보다 빠르다고 가정할 때, 다음 표는 snapshot_time의 쿼리 가능 여부를 보여줍니다.

T 이전의 암호화 유형 T 이후의 암호화 유형 snapshot_time
Cloud KMS 암호화 Cloud KMS 암호화 쿼리 불가
기본 암호화 Cloud KMS 암호화 쿼리 가능
Cloud KMS 암호화 기본 암호화 쿼리 불가

범위 데코레이터를 사용할 경우 <time2>에도 비슷한 논리가 적용됩니다.

자주 묻는 질문(FAQ)

Cloud KMS 키에 대한 권한이 필요한 사람은 누구인가요?

고객 관리 암호화 키를 사용하면 반복해서 권한을 지정하지 않아도 됩니다. BigQuery 서비스 계정에 Cloud KMS 키를 사용하여 암호화 및 복호화할 수 있는 권한이 있다면, BigQuery 테이블에 대한 권한이 있는 사용자는 Cloud KMS 키에 직접 액세스할 수 없더라도 데이터에 액세스할 수 있습니다.

어떤 서비스 계정을 사용하나요?

테이블의 GCP 프로젝트와 관련된 BigQuery 서비스 계정이 해당 테이블의 데이터 복호화에 사용됩니다. BigQuery 서비스 계정은 프로젝트마다 고유합니다. Cloud KMS로 보호되는 익명 테이블에 데이터를 기록하는 작업의 경우 프로젝트 서비스 계정을 사용합니다.

예를 들어 CMEK로 보호되는 테이블 3개 table1, table2, table3가 있다고 가정해 보겠습니다. 대상 테이블 {project3.table3}{project1.table1, project2.table2}의 데이터를 쿼리하는 방법은 다음과 같습니다.

  • project1.table1project1 서비스 계정 사용
  • project2.table2project2 서비스 계정 사용
  • project3.table3project3 서비스 계정 사용

BigQuery는 어떤 방식으로 Cloud KMS 키를 사용하나요?

BigQuery는 Cloud KMS 키를 사용하여 Tabledata.listjobs.insert 같은 사용자 쿼리에 대한 응답으로 데이터를 복호화합니다.

또한 BigQuery는 읽기에 최적화된 형식으로 데이터를 변환하는 작업 등 데이터 유지관리 및 저장소 최적화 작업에도 이 키를 사용합니다.

도움이 더 필요하면 어떻게 해야 하나요?

여기에서 답변을 찾을 수 없는 질문이 있으면 cmek-feedback@google.com으로 연락하거나 BigQuery 지원 또는 Cloud KMS 지원을 참조하세요.

오류 해결

다음은 일반적인 오류 및 권장되는 해결 방법입니다.

오류 권장 방법
Cloud KMS CryptoKey 암호화/복호화 역할을 부여하세요. 프로젝트와 관련된 BigQuery 서비스 계정에 Cloud IAM 권한이 부족해 지정된 Cloud KMS로 작동할 수 없습니다. 오류나 본 문서의 안내에 따라 적절한 Cloud IAM 권한을 부여하세요.
기존 테이블 암호화 설정이 요청에서 지정하는 암호화 설정과 일치하지 않습니다. 이 오류는 대상 테이블의 암호화 설정이 사용자 요청의 암호화 설정과 일치하지 않을 때 발생합니다. 해결을 위해 쓰기 방식 TRUNCATE로 테이블을 교체하거나 다른 대상 테이블을 지정하세요.
이 리전은 지원되지 않습니다. Cloud KMS 키의 리전이 대상 테이블의 BigQuery 데이터세트 리전과 일치하지 않습니다. 해결을 위해 데이터세트와 일치하는 리전의 키를 선택하거나 키 리전과 일치하는 데이터세트에 로드하세요.

알려진 문제

  • BigQuery 클라이언트 라이브러리는 고객 관리 암호화 키를 구성하는 명령어를 지원하지 않습니다.
이 페이지가 도움이 되었나요? 평가를 부탁드립니다.

다음에 대한 의견 보내기...

도움이 필요하시나요? 지원 페이지를 방문하세요.