【Redshift】デフォルトの暗号化がSSE-KMSであるS3バケットにUnloadする際はパラメータの指定を考慮する必要があることに注意しよう
データ事業本部のueharaです。
今回は、Redshiftでデフォルトの暗号化がSSE-KMSであるS3バケットにUnloadする際はパラメータの指定を考慮する必要があることに注意しようという話をしたいと思います。
はじめに
特にデフォルトの暗号化設定としてAWSのマネージドキー( alias/aws/s3 )を利用したSSE-KMSでのバケットの暗号化をしている場合、オブジェクトをPutする側のIAMロールにS3にアクセスする権限さえあればKMSのキーに関するポリシーを記載する必要も無いので、Putの際あまり暗号化を意識していない方も多いと思います。
ただ、デフォルトの暗号化設定としてSSE-KMSを設定しているバケットに対しRedshiftからUnloadする際、特定のパラメータを明示的に指定しない場合は SSE-S3 で暗号化が実施されてしまいます。
事象確認
まず、AWSのマネージドキー( alias/aws/s3 )によるSSE-KMSでの暗号化を設定したS3バケットを用意します。

試しに、このバケットに対しAWS CLIを利用してファイルをアップロードします。
$ aws s3 cp test.txt s3://uehara-kms-test/test.txt アップロードされたファイルを確認すると、KMSで暗号化されていました。
こちらは特に直感に違わない挙動かなと思います。

次にRedshiftから当該バケットに対して特に暗号化のパラメータを指定せずに適当なデータをUnloadしてみます。
UNLOAD(' SELECT 1 AS "test" ') TO 's3://uehara-kms-test/test_from_redshift' IAM_ROLE '<IAMロールのARN>' FORMAT AS CSV DELIMITER ',' HEADER PARALLEL OFF EXTENSION 'csv'; Unload自体は問題なく実行完了しました。

Unloadされたファイルを確認すると、こちらは冒頭で述べたように SSE-S3 で暗号化されてしまっています。

私の直感的にはこちらもSSE-KMSで暗号化されるイメージだったのですが、どうやら違うようです。
原因
これはRedshiftのUnloadにおける仕様です。
公式ドキュメントにも以下のような記載があります。
ENCRYPTED パラメータを指定しない場合、UNLOAD は AWS 管理の暗号化キーによる Amazon S3 のサーバー側暗号化 (SSE-S3) 機能を使用して、暗号化されたファイルを自動的に作成します。
したがって、特に ENCRYPTED パラメータを指定しない場合はS3のデフォルトの暗号化設定で SSE-KMS を指定していたとしても SSE-S3 で暗号化された状態で出力されます。
対応
今度は ENCRYPTED を指定してUnloadしてみます( KMS_KEY_ID を明示的に指定することもできますが、 S3バケットのプロパティ上にあるデフォルトのAWS KMS暗号化キーを利用する AUTO を設定)。
UNLOAD(' SELECT 1 AS "test" ') TO 's3://uehara-kms-test/test_from_redshift2' IAM_ROLE '<IAMロールのARN>' FORMAT AS CSV DELIMITER ',' HEADER ENCRYPTED AUTO PARALLEL OFF EXTENSION 'csv'; Unloadされたファイルを確認すると、今度は無事SSE-KMSで暗号化されていました。

パラメータの指定漏れにより、SSE-S3で暗号化された状態でファイルが出力されてしまうことを防ぎたい場合は、以下のようにバケットポリシーで x-amz-server-side-encryption-aws-kms-key-idヘッダーがリクエストに含まれていない場合はs3:PutObjectを拒否する、という設定をすることで対策可能です。
{ "Version": "2012-10-17", "Id": "PutObjectPolicy", "Statement": [ { "Sid": "DenyObjectsThatAreNotSSEKMS", "Effect": "Deny", "Principal": "*", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::uehara-kms-test/*", "Condition": { "Null": { "s3:x-amz-server-side-encryption-aws-kms-key-id": "true" } } } ] } 上記バケットポリシーを設定した状態で ENCRYPTED パラメータを指定せずにUnloadしようとすると失敗します。

最後に
今回は、Redshiftでデフォルトの暗号化がSSE-KMSであるS3バケットにUnloadする際はパラメータの指定を考慮する必要があることに注意しようという話をしてみました。
参考になりましたら幸いです。






