

S3のKMSキーを別のキーに変更する、UpdateObjectEncryptionでコピー不要になった
この記事は、構成と文章の整理にAIを使っています。
あくまで読みやすくするための補助で、内容そのものをAIにすべて任せて書いているわけではありませんが、ところどころ相談しながら整えています。
S3にSSE-KMSで保存済みのオブジェクトを、別のKMSキーに切り替える必要があって調べた。結論から言うと、今は2つのやり方がある。
前提: 既存オブジェクトの暗号化キーは後から自動で変わらない
バケットのデフォルト暗号化設定を変更しても、既にアップロード済みのオブジェクトには影響しない。これは以前から変わっていない。新しいキーで暗号化し直したいなら、既存オブジェクト1つ1つに対して明示的な操作が必要になる。
方法1: aws s3 cp で自分自身に上書きコピーする(従来方式)
同じパスに対して cp を実行し、暗号化オプションだけ新しいキーを指定するとS3側で再暗号化される。
aws s3 cp s3://example-bucket/example-prefix/ s3://example-bucket/example-prefix/ \ --recursive \ --sse aws:kms \ --sse-kms-key-id arn:aws:kms:ap-northeast-1:111122223333:key/xxxxxxxxポイント:
--recursiveはプレフィックス(フォルダ)配下をまとめて処理するためのオプション。単一オブジェクトだけ対象にするなら不要。- 実体としては「新しいオブジェクトとしてコピーし直す」動作なので、S3のリクエスト課金(コピー分)が発生する。バージョニング有効なバケットだと新しいバージョンが積み増しされる。
- オブジェクト数が多いと単純に時間がかかる。数百万〜数十億単位なら S3 Batch Operations でジョブ化するのが現実的(S3 Inventoryからマニフェストを作って渡す)。
これは今でも使える方法だけど、「コピー」である以上データが動く。Glacierに入ってるオブジェクトだと復元(リストア)が絡んでくるし、Intelligent-Tieringだとティア移動が発生することもある。
方法2: UpdateObjectEncryption API(2026年2月〜)
2026年2月5日に UpdateObjectEncryption operationが追加された。データを動かさずに暗号化タイプ・KMSキーだけをその場で更新できる。
aws s3api update-object-encryption \ --bucket example-bucket \ --key example-object.png \ --object-encryption '{"SSEKMS": { "KMSKeyArn": "arn:aws:kms:ap-northeast-1:111122223333:key/yyyyyyyy", "BucketKeyEnabled": true }}'cp 方式との違い:
- データはコピーされない。Glacier Flexible Retrieval / Deep Archiveのオブジェクトでもリストア不要、Intelligent-Tieringのティアも動かない。
- storage class、作成日時、ETag、チェックサムなどのメタデータプロパティはそのまま保持される。
- 完了はミリ秒単位。オブジェクトサイズやストレージクラスに関係なく速い。
- 課金はPUT/COPY/POST/LIST相当(リクエスト単価)で、常にS3 Standardクラスのリクエストとして課金される。
用途としては公式に「カスタマー管理KMSキーのローテーション対応」が明記されているので、まさに今回みたいなキー変更のためのAPIという位置づけ。SSE-S3 → SSE-KMSへの変更や、S3 Bucket Keyの後付け適用にも使える。
制限
- 未暗号化オブジェクト、DSSE-KMS、SSE-Cで暗号化されたオブジェクトは対象外。
- 新しい暗号化タイプとしてSSE-S3は指定できない(SSE-KMSへの変更専用)。
- Object Lockのcompliance modeが付いているオブジェクトには使えない。governance modeなら一旦ロックを外せば可能。
- KMSキーはフルARN指定が必須。エイリアスやキーIDだけでは受け付けない。
- デフォルトではバケット所有アカウントが持つKMSキーのみ対象。Organizations配下の他アカウントのキーを使いたい場合はAWSサポートへの申請が必要。
必要な権限
{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": [ "s3:UpdateObjectEncryption", "kms:Encrypt", "kms:Decrypt", "kms:GenerateDataKey", "kms:ReEncrypt*" ], "Resource": [ "arn:aws:s3:::example-bucket", "arn:aws:s3:::example-bucket/*", "arn:aws:kms:ap-northeast-1:111122223333:key/yyyyyyyy" ] }]}大量オブジェクトを一括で処理する場合
単発の update-object-encryption を1オブジェクトずつ叩くのは現実的じゃないので、大量にあるなら S3 Batch Operations 経由で UpdateObjectEncryption operationを実行する。S3 Inventoryのメタデータ(プレフィックス、storage class、作成日、暗号化タイプ、KMSキーARN、Bucket Key有無)を条件にオブジェクトリストを生成できるので、「特定の古いKMSキーで暗号化されてるオブジェクトだけ」みたいな絞り込みもできる。
まとめると
- 2026年2月以前の環境や、SDK/CLIのバージョンが古くて
update-object-encryptionが使えない場合は、aws s3 cpの再コピー方式一択。 - 今から新規で組むなら
UpdateObjectEncryptionの方が速い・安い・メタデータも壊れない。既存のキーローテーション運用スクリプトがcpベースなら、移行を検討する価値はある。 - どちらの方式でも、対象オブジェクトが多い場合はS3 Batch Operationsに寄せた方が進捗管理や完了レポートの面で楽。