Snowflake Tri-Secret Secure で複合マスターキーを構成しよう
Snowflake では、複数の暗号化キーによるデータ暗号化が自動的に行われるようになっており、デフォルトの状態でも安全性高くデータ基盤を運用できるようになっています。しかし、組織や業界のセキュリティ要件によっては、顧客自身も暗号化キーを管理できる状態になっていることを求められる場合があります。
Snowflake の Tri-Secret Secure を利用すると、顧客管理キーを Snowflake 上のデータの暗号化に組み込むことができます。本記事では、Tri-Secret Secure の機能概要と構成手順についてご紹介できればと思います。
Snowflake におけるデータ暗号化
具体的な手順に入る前に、Snowflake におけるデータ暗号化について少し言及しておきます。
詳細については以下の公式ドキュメントをご確認ください。
階層キーモデル
Snowflake では、暗号化キー管理において下図のような 4 層(ルートキー/アカウントマスターキー/テーブルマスターキー/ファイルキー)からなる 階層キーモデル を採用しています。
階層キーモデル
各キー階層は、暗号化のスコープに対応しています。この図の場合、例えば Table File 3 は、(Root Key, AMK1, TMK1, FK3) の 4 つのキー全てによって暗号化・復号化されます。
最上位のルートキーは、各クラウドプラットフォームの HSM (Hardware Security Module) サービスによって厳重に管理されます。AWS の場合、AWS CloudHSM が使用されます。
Tri-Secret Secure とは
前述の階層キーモデルや、(説明は割愛しますが)内部的なキーローテーションによって、Snowflake におけるデータ暗号化はデフォルトでも極めて安全性の高い運用がなされています。
しかし、PCI-DSS v4.0 や HIPAA、HITRUST SCF などのセキュリティ基準では、「顧客管理キーによる二重暗号化を実装し、顧客自身も鍵管理の主権を持つこと」を求めるものがあります。例えば、PCI DSS v4.0 (日本語版) には以下のような記述があります。
3.7.6 手動による平文の暗号化鍵の管理操作が担当者によって行われる場合、鍵管理ポリシおよび手順には、知識分割およびデュアルコントロールを使用してこれらの操作を管理することが含まれている。
(目的) 鍵の知識分割とデュアルコントロールは、1 人が鍵全体へのアクセスを行い、データへの不正なアクセス権を取得する可能性を排除するために行われるものです。
Business Critical Edition 以上の Snowflake アカウントでは、Snowflake 側で暗号化しているアカウントマスターキー (AMK-S) の他に、クラウドプラットフォームの鍵管理サービス (AWS の場合、AWS KMS)で作成した顧客管理キー (CMK) を用いて、アカウントマスターキーの一部 (AMK-C) を暗号化します。アカウントマスターキーが必要な場合は、AMK-S と AMK-C をそれぞれの暗号化システムで復号化し、複合マスターキー (Composed-AMK) を作成して使用します。[1] [2]
Snowflake ではこれを Tri-Secret Secure と呼びます。
Tri-Secret Secure の複合マスターキー
Snowflake から CMK へのアクセスは、KMS キーポリシーによって許可します。キーポリシーで Snowflake からのアクセス許可を取り消した場合、Snowflake でさえデータを復号できない状態を実現することができます。
以降で具体的な構成手順についてみていきます。
実施手順
公式ドキュメント に沿って、以下の流れで進めていきます。
【1】KMS 顧客管理キー (CMK) の作成
まず、複合マスターキーを構成する KMS 顧客管理キー (CMK) を作成します。
Snowflake 側から CMK を利用できるよう、後述のステップでキーポリシーを修正します。
resource "aws_kms_key" "default" {
description = "CMK for Snowflake Tri-Secret Secure"
key_usage = "ENCRYPT_DECRYPT"
customer_master_key_spec = "SYMMETRIC_DEFAULT"
is_enabled = true
enable_key_rotation = true
multi_region = false
}
resource "aws_kms_alias" "default" {
name = "alias/${var.alias}"
target_key_id = aws_kms_key.default.key_id
}
resource "aws_kms_key_policy" "default" {
key_id = aws_kms_key.default.key_id
policy = data.aws_iam_policy_document.key_policy.json
}
data "aws_iam_policy_document" "key_policy" {
statement {
sid = "Enable ReservedSSO role permissions"
actions = ["kms:*"]
resources = ["*"]
principals {
type = "AWS"
identifiers = var.admin_principal_arns
}
}
}
【2】CMK の登録・確認
Snowflake 上で作成した CMK の自己登録を行います。
accountadmin ロールで、キー ARN を引数に SYSTEM$REGISTER_CMK_INFO を実行します。
USE ROLE accountadmin;
SELECT SYSTEM$REGISTER_CMK_INFO(
'arn:aws:kms:ap-northeast-1:000011112222:key/xxxxxxxx');
-- Registration completed
SYSTEM$GET_CMK_INFO を実行することで、CMK のステータスを確認できます。
この時点ではステータス pre-registered
となっており、登録はされていますが、まだ Tri-Secret Secure を利用できる状態にはなっていません。
SELECT SYSTEM$GET_CMK_INFO();
-- CMK with ARN: arn:aws:kms:ap-northeast-1:000011112222:key/xxxxxxxx is pre-registered for Tri-Secret Secure
【3】Snowflake ユーザーへの KMS 権限の付与
現時点で Snowflake ユーザーから CMK に対する操作が許可されていないため、SYSTEM$VERIFY_CMK_INFO を実行するとエラーになります。
SELECT SYSTEM$VERIFY_CMK_INFO();
-- Verification failed due to an exception with message: Access is denied to the customer managed key (CMK) for this account. This could be because: 1) the CMK access permissions granted to Snowflake have been revoked OR 2) the CMK is disabled OR 3) the CMK is scheduled for deletion OR 4) the CMK specified is wrong. CMK ARN used: arn:aws:kms:ap-northeast-1:000011112222:key/xxxxxxxx
Snowflake ユーザーが CMK に対する必要なアクションを実行できるよう、KMS キーポリシーを修正していきます。SYSTEM$GET_CMK_CONFIG を実行すると、必要なポリシーを確認できます。
SELECT SYSTEM$GET_CMK_CONFIG();
{
"Sid": "Allow use of the key by Snowflake",
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::999988887777:user/xyz000000"},
"Action": ["kms:Decrypt", "kms:GenerateDataKeyWithoutPlaintext"],
"Resource": "arn:aws:kms:ap-northeast-1:000011112222:key/xxxxxxxx"
}
出力内容の通りに、CMK のキーポリシーの内容を修正します。
data "aws_iam_policy_document" "key_policy" {
statement {
sid = "Enable ReservedSSO role permissions"
actions = ["kms:*"]
resources = ["*"]
principals {
type = "AWS"
identifiers = var.admin_principal_arns
}
}
+ statement {
+ sid = "Allow use of the key by Snowflake"
+ actions = ["kms:Decrypt", "kms:GenerateDataKeyWithoutPlaintext"]
+ resources = [aws_kms_key.default.arn]
+ principals {
+ type = "AWS"
+ identifiers = ["arn:aws:iam::999988887777:user/xyz000000"]
+ }
+ }
}
もう一度 SYSTEM$VERIFY_CMK_INFO を実行すると、今度は検証に成功します。
SELECT SYSTEM$VERIFY_CMK_INFO();
-- Verification successful
【4】登録 CMK の有効化依頼
自己登録した CMK を Tri-Secret Secure で利用できるようにするには、Snowflake サポートに有効化のリクエストをする必要があります。この際、Tri-Secret Secure を利用したい Business Critical Edition のアカウントを伝えます。
執筆時点では、Snowpark Container Service (SPCS) のイメージリポジトリについては Tri-Secret Secure を利用できず、その制約について確認するための以下の SQL の実行を求められました。
USE ROLE accountadmin;
ALTER ACCOUNT
SET ENABLE_TRI_SECRET_AND_REKEY_OPT_OUT_FOR_IMAGE_REPOSITORY=True;
SQL 実行後、自己登録した CMK を有効化して頂き、CMK のステータスが Activated になっていることを確認できました。(ケース起票から数時間程度でクローズまで行きました。爆速対応頂いたご担当者の方、誠にありがとうございます!)
SELECT SYSTEM$GET_CMK_INFO();
-- CMK with ARN: arn:aws:kms:ap-northeast-1:000011112222:key/xxxxxxxx is activated for Tri-Secret Secure
動作確認
通常の動作
Tri-Secret Secure が有効な状態でも複合マスターキーの生成は透過的に行われ、ユーザーは特に意識することなくデータ操作することができます。
USE DATABASE test_db;
USE SCHEMA test_db.test_schema;
CREATE TABLE IF NOT EXISTS tss_demo (col1 NUMBER, col2 VARCHAR);
INSERT INTO tss_demo VALUES (1, 'alice'),(2, 'bob'), (3, 'charlie');
SELECT * FROM tss_demo;
KMS 権限の剥奪
さて、前述の通り Snowflake から CMK へのアクセス権限を剥奪すればデータ復号出来ない状態になるはずなので、その挙動についても確認してみたいと思います。
KMS キーポリシーの、先ほど追加したポリシーステートメントを削除してみます。
data "aws_iam_policy_document" "key_policy" {
statement {
sid = "Enable ReservedSSO role permissions"
actions = ["kms:*"]
resources = ["*"]
principals {
type = "AWS"
identifiers = var.admin_principal_arns
}
}
- statement {
- sid = "Allow use of the key by Snowflake"
- actions = ["kms:Decrypt", "kms:GenerateDataKeyWithoutPlaintext"]
- resources = [aws_kms_key.default.arn]
- principals {
- type = "AWS"
- identifiers = ["arn:aws:iam::999988887777:user/xyz000000"]
- }
- }
}
Apply 後、もう一度 SELECT 文を実行してみましたが、なぜか正常にデータ参照できてしまいました。調べてみた所、どうやら CMK から構成された複合マスターキーは最大 10 分間 Snowflake のメモリ上にキャッシュされ、10 分が過ぎるとこれをフラッシュして再構成するようです。
Tri-Secret Secure FAQ for Snowflake on AWS
Once Snowflake builds the composed AMK after connecting to your KMS, it will be cached in-memory of Snowflake for a maximum of 10 minutes. After the 10 minutes elapse, Snowflake will flush the comp-AMK from the cache and need to rebuild it to continue serving data access.
ということで 10 分間間隔を空けて SELECT 文を再実行したところ、無事 Access is denied のエラーを確認できました。
キーローテーション
Tri-Secret Secure では、CMK をキーローテーションしても引き続きデータ操作できるため、自動キーローテーションを有効化しておいても問題ありません。キーローテーションは、KeyID を変更せずにキーマテリアルを変更する操作を指します。(KeyID を変更する場合は、再度自己登録・有効化の手順を踏む必要があります)
キーポリシーを元に戻した状態で動作確認してみたいと思います。自動ローテーションのタイミングまで待っていられないので、オンデマンドでキーローテーションを実行してみます。(この操作は KMS キーあたり 10 回まで実施可能です)
% aws kms rotate-key-on-demand --key-id xxxxxxxx
{
"KeyId": "arn:aws:kms:ap-northeast-1:000011112222:key/xxxxxxxx"
}
AWS マネジメントコンソール上で、キーローテーションが実行されたことを確認できます。
10 分以上経過しても、無事データ参照できることを確認できました。
さいごに
Snowflake における Tri-Secret Secure の概要・構成手順についてご紹介しました。
ユーザー側で特に何もしなくても安全に運用できるような基盤を Snowflake 側で提供してくれているので、普段あまり細かい仕様・挙動まで意識していませんでしたが、本記事を執筆する中で「なぜ Snowflake のデータ暗号化が安全なのか」について改めて理解を深められた気がします。内部のキーローテーションやリキーイングなどは今回扱えなかったので、気になる方は是非公式ドキュメントや Snowflake の論文 [3] を読んでみてください。
また、本記事執筆に際して Snowflake の Yanase 様 (@masayay) にレビューのご協力を賜りました。この場をお借りして感謝を申し上げたいと思います。
最後まで読んで頂き、ありがとうございました。
-
Data Encryption with Customer-Managed Keys - Snowflake Blog ↩︎
-
SNOWFLAKE TECHNICAL TOOLS FOR PROTECTING SENSITIVE CUSTOMER DATA p.22 ↩︎
-
The Snowflake Elastic Data Warehouse - ACM Digital Library ↩︎

Snowlfake データクラウドのユーザ会 SnowVillage のメンバーで運営しています。 Publication参加方法はこちらをご参照ください。 zenn.dev/dataheroes/articles/db5da0959b4bdd
Discussion