KMSで暗号化されたS3のデータをLambdaで処理する方法を試してみた
はじめに
お疲れ様です、あきとです。
今回は、AWS のサービスの一つである Lambda を使って、暗号化されたデータを処理する方法について紹介します。
S3 にデータを保存するときに暗号化できることはよく知られていますが、実際にその暗号化データを AWS 内でどのように処理できるのか疑問を持ち、調べて実際に Lambda で S3 内でデータを暗号化して保存できるか、保存したデータを復号化できるか試してみました。
事前知識
- AWS の基本的なサービス(S3、Lambda、IAM、KMS)の理解
- 簡単な Python の知識
やってみた
手順1: KMS キーの作成と設定
1-1. KMS キーの作成
カスタマー管理型のキーをデフォルトで作成してください。
後ほど、キーポリシーを編集します。
1-2. KMS操作用 IAM ポリシーの作成
Lambda でKMS権限付与のために IAM ポリシーを以下のように作成します。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "S3Read",
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<BUCKET_NAME>/*"
},
{
"Sid": "S3WriteWithKmsOnly",
"Effect": "Allow",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::<BUCKET_NAME>/*"
},
{
"Sid": "KmsForSseKmsFromS3Only",
"Effect": "Allow",
"Action": [
"kms:Decrypt",
"kms:GenerateDataKey*"
],
"Resource": "arn:aws:kms:ap-northeast-1:<ACCOUNT_ID>:key/<KMS_KEY_ID>",
"Condition": {
"StringEquals": {
"kms:ViaService": "s3.ap-northeast-1.amazonaws.com"
},
"ForAnyValue:StringLike": {
"kms:EncryptionContext:aws:s3:arn": "arn:aws:s3:::<BUCKET_NAME>/*"
}
}
}
]
}
各権限の説明:
- s3:GetObject:S3 からオブジェクトを読み取れるようにする
- s3:PutObject:S3 にオブジェクトを書き込めるようにする
- kms:Decrypt:S3 に保存された暗号化オブジェクトを復号できるようにする
- kms:GenerateDataKey*:S3 に新しいオブジェクトを書き込むときに必要なデータキーを生成する
- Condition(kms:ViaService):S3 経由の特定バケット配下のオブジェクトの操作だけを許可
1-3. Lambda 用 IAM ロールの作成
Lambda で使用する IAM ロールを作成するために、ユースケースを Lambda にします。許可ポリシーに CloudWatch Logs への書き込み用の AWSLambdaBasicExecutionRole と先ほど作成したポリシーを追加し、作成します。
1-4. KMS キーの設定
作成した KMS キーの Default キーポリシーを以下のように変更します。
{
"Version": "2012-10-17",
"Id": "key-consolepolicy-3",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<ACCOUNT_ID>:root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "AllowLambdaRoleUseOfKey",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<ACCOUNT_ID>:role/<LAMBDA_ROLE_NAME>"
},
"Action": [
"kms:Decrypt",
"kms:GenerateDataKey*"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"kms:ViaService": "s3.ap-northeast-1.amazonaws.com"
}
}
}
]
}
キーポリシーの説明:
- Principal:このポリシーを使える IAM ロール(ここでは Lambda 実行ロール)を指定
- Condition(kms:ViaService):S3 経由の操作だけを許可する制限(他のサービスからの利用を防ぐ)
手順2: Lambda 関数の実装とテスト
2-1. 基本的な Lambda の実装
KMS で暗号化された S3 を処理する Lambda を Python 3.13 で作成します:
import json
import boto3
import os
# --- S3 クライアント作成 ---
s3 = boto3.client("s3")
# 環境変数から S3 バケット名と KMS キーARNを取得
BUCKET = os.environ["BUCKET"]
KMS_KEY_ARN = os.environ["KMS_KEY_ARN"]
def lambda_handler(event, context):
# --- 保存するテスト用データ(固定値) ---
payload = {"message": "Hello from Lambda with SSE-KMS"}
# JSON形式に変換し、バイト列にエンコード
body = json.dumps(payload).encode("utf-8")
# --- PutObject: S3に暗号化して保存 ---
s3.put_object(
Bucket=BUCKET, # 対象のバケット
Key="sample.json", # 保存するオブジェクトのキー(ファイル名に相当)
Body=body, # 保存するデータ本体
ContentType="application/json", # コンテンツタイプ(JSONを明示)
ServerSideEncryption="aws:kms", # サーバーサイド暗号化方式(KMS)を明示
SSEKMSKeyId=KMS_KEY_ARN, # 使用するKMSキーARNを指定
BucketKeyEnabled=True # 任意: S3 Bucket Keysを有効化(KMSリクエスト削減)
)
# --- GetObject: 保存した暗号化オブジェクトを取得 ---
response = s3.get_object(
Bucket=BUCKET,
Key="sample.json"
)
# 取得したデータをデコードして JSON として読み込み
content = response['Body'].read().decode('utf-8')
data = json.loads(content)
# --- Lambdaの戻り値 ---
return {
'statusCode': 200,
'body': json.dumps({
'message': 'Successfully processed KMS encrypted S3 object',
'data': data
})
}
2-2. 環境変数の設定
Lambda の環境変数に以下を設定:
BUCKET
: 対象の S3 バケット名KMS_KEY_ARN
: 使用する KMS キーの ARN
2-3. Lambda 関数のテスト
ハンドラを lambda_function.lambda_handler に設定し、
Lambda をテスト実行します。
手順3: S3 コンソールでの確認
3-1. 暗号化状態の確認
作成されたオブジェクトの暗号化設定を確認します。
S3 に対象の KMS で暗号化された sample.json のオブジェクトが、作成されます。
オブジェクトのプロパティから、SSE-KMS で適切に暗号化されていることが確認できます。
3-2. 動作確認結果
実行が成功すると、以下のようなレスポンスが返されます:
{
"statusCode": 200,
"body": "{\"message\": \"Successfully processed KMS encrypted S3 object\", \"data\": {\"message\": \"Hello from Lambda with SSE-KMS\"}}"
}
まとめ
今回は KMS で暗号化された S3 のデータを Lambda で処理する方法を実際に試しました。
IAM ポリシーと KMS キーポリシーを正しく設定することで、S3 に保存する際には自動的に暗号化され、取得時には復号化されることが確認できました(ただし、保存時に SSE-KMS を指定する必要があります)。今回の方法では、暗号化・復号化は KMS と S3 が自動的に処理するため、アプリケーションコードが復号処理を担っているわけではない点には注意が必要です。
本記事がどなたかの参考になれば幸いです。
参考資料
- 対称暗号化 KMS キーを作成する - AWS Key Management Service
- S3 - Boto3 1.40.21 documentation
- AWS KMS (SSE−KMS) によるサーバー側の暗号化の指定 - Amazon Simple Storage Service
アノテーション株式会社について
アノテーション株式会社は、クラスメソッド社のグループ企業として「オペレーション・エクセレンス」を担える企業を目指してチャレンジを続けています。「らしく働く、らしく生きる」のスローガンを掲げ、様々な背景をもつ多様なメンバーが自由度の高い働き方を通してお客様へサービスを提供し続けてきました。現在当社では一緒に会社を盛り上げていただけるメンバーを募集中です。少しでもご興味あれば、アノテーション株式会社WEBサイトをご覧ください。