S3の暗号化タイプがデータ移動なしで変更可能に — UpdateObjectEncryption APIの全貌

AWSAmazon S3KMS暗号化コンプライアンスセキュリティ

S3に保存済みのオブジェクトの暗号化タイプを、データのコピーや移動なしで変更できるようになりました。新しい UpdateObjectEncryption APIの話です。

これまでSSE-S3からSSE-KMSへの移行には、オブジェクトのコピーが必要でした。つまり CopyObject で同じ場所に上書きコピーするという、正直あまりエレガントとは言えない方法です。オブジェクトが数十億個あるバケットでこれをやると、時間もコストも相当かかりますし、何よりコピー中にメタデータが変わるリスクがありました。

今回の UpdateObjectEncryption APIについて、公式ドキュメントには以下のように記載されています(AWS ドキュメント)。

The UpdateObjectEncryption API operation uses envelope encryption to re-encrypt the data key used to encrypt and decrypt your object with your newly specified server-side encryption type. Amazon S3 performs this encryption type update without any data movement.

エンベロープ暗号化の仕組みを活かして、データキーの再暗号化だけを行い、データ本体は一切動かないとのことです。さらにパフォーマンスについても言及があります。

The UpdateObjectEncryption operation is typically completed in milliseconds regardless of the size of the object or the storage class, including S3 Glacier Flexible Retrieval or S3 Glacier Deep Archive.

オブジェクトサイズやストレージクラスに関係なく、S3 GlacierやDeep Archiveのオブジェクトであっても、通常はミリ秒単位で完了するとのことです。

なぜこのアップデートが重要か

多くの組織がコンプライアンス要件への対応で暗号化の見直しを迫られています。AWS自身もこのアナウンスの英語版で以下のように述べています(AWS What’s New)。

Customers across many industries face increasingly stringent audit and compliance requirements on data security and privacy. A common requirement for these compliance frameworks is more rigorous encryption standards for data-at-rest, where organizations must encrypt data using a key management service.

(多くの業界の顧客が、データセキュリティとプライバシーに関する監査・コンプライアンス要件の厳格化に直面している。これらのフレームワークでの一般的な要件は、保管時のデータに対してより厳格な暗号化標準を適用し、鍵管理サービスを使用してデータを暗号化することである。)

具体的に見ると、PCI DSS 4.0のRequirement 3.5/3.6では暗号鍵の管理について以下のように定めています(Thoropass)。

Requirement 3.5: Protect cryptographic keys used for encryption of cardholder data against disclosure and misuse.

Requirement 3.6: Fully document and implement all key-management processes and procedures for cryptographic keys.

カード会員データの暗号化に使用する鍵を開示や不正使用から保護し、鍵管理のプロセスを完全に文書化・実装することが求められています。

一方、SOC2については少しニュアンスが異なります(Konfirmity)。

The SOC 2 framework is purposefully flexible. It does not prescribe specific tools, but it does expect service organisations to implement controls that protect sensitive data.

SOC2は意図的に柔軟な設計になっており、特定のツールを指定するわけではありません。顧客管理キーの使用自体は義務化されていませんが、鍵管理プロセスの文書化と適切な管理体制は求められます。

いずれにしても、SSE-S3(S3管理キー)からSSE-KMS(顧客がコントロール可能なKMSキー)への移行ニーズが多くの組織に存在するのは確かだと思います。

2023年1月以降、S3は全てのオブジェクトをデフォルトでSSE-S3で暗号化するようになりました。つまり、現時点で多くのバケットに大量のSSE-S3オブジェクトが存在しているはずです。これをSSE-KMSに移行したい場合、これまでは以下の方法しかありませんでした。

  • CopyObject でオブジェクトを同じ場所に暗号化タイプを変えてコピー
  • S3 Batch Operationsの S3PutObjectCopy で大量のオブジェクトをコピー

どちらもデータの物理的なコピーが発生するため、大量のオブジェクトがある環境では現実的ではない場面がありました。特にS3 Glacier Flexible RetrievalやDeep Archiveに保存されたオブジェクトは、まず復元してからコピーする必要があり、さらに面倒です。

UpdateObjectEncryption はこの問題を根本的に解決します。

技術的な仕組み

S3のサーバーサイド暗号化は「エンベロープ暗号化」という仕組みを使っています。オブジェクトのデータ本体はデータキーで暗号化され、そのデータキーをさらにマスターキー(SSE-S3ならS3管理キー、SSE-KMSならKMSキー)で暗号化して一緒に保存します。

UpdateObjectEncryption がやることは、このデータキーの暗号化を「掛け替える」だけです。データ本体には一切触れません。そしてメタデータについても公式ドキュメントに明記されています。

The UpdateObjectEncryption operation preserves all object metadata properties, including the storage class, creation date, last modified date, ETag, and checksum properties.

ストレージクラス、作成日、最終更新日、ETag、チェックサムプロパティが全て保持されます。実際に自分の環境で検証した結果でも、LastModifiedETag が変わっていないことを確認できています(後述)。

S3 Intelligent-Tieringのオブジェクトでも、アクセス階層の移動は発生しません。S3 Glacier系のオブジェクトの復元も不要です。ここは見落としがちですが、コピーベースの移行では大きな問題になっていたポイントなので、かなりありがたい改善です。

対応する暗号化タイプ

全ての暗号化タイプの組み合わせに対応しているわけではない点は注意が必要です。

変更元(ソース)として対応:

  • SSE-S3(S3マネージドキー)
  • SSE-KMS(KMSキー)

変更先(ターゲット)として対応:

  • SSE-KMS(KMSキー)
  • SSE-KMSでS3 Bucket Keyを有効化

非対応:

  • 未暗号化のオブジェクト → 対象外
  • DSSE-KMS(二重レイヤー暗号化) → 対象外
  • SSE-C(お客様提供キー) → 対象外
  • SSE-S3をターゲットに指定 → 不可

ここは注意が必要です。SSE-KMSからSSE-S3に「戻す」ことはできません。つまり一方通行です。KMSキーの変更やBucket Keyの有効化は可能ですが、KMS管理をやめてS3マネージドに戻すという操作はこのAPIではサポートされていません。セキュリティの観点からは「暗号化の強度を下げる方向の変更は許可しない」という設計思想だと思います。

自分の環境で試してみた

実際にap-northeast-1リージョンで試してみました。

  • AWS CLI: 2.34.3(update-object-encryption2.33.9 以降で対応。CHANGELOG 2.33.9
  • リージョン: ap-northeast-1(東京)

まず、テスト用のオブジェクトをアップロードします。デフォルト暗号化のSSE-S3が適用されます。

$ echo "test" | aws s3 cp - s3://my-bucket/test-encryption-change.txt

head-object で暗号化状態を確認します。

$ aws s3api head-object --bucket my-bucket --key test-encryption-change.txt
{
    "AcceptRanges": "bytes",
    "LastModified": "2026-03-06T08:14:58+00:00",
    "ContentLength": 78,
    "ETag": "\"a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6\"",
    "ContentType": "binary/octet-stream",
    "ServerSideEncryption": "AES256",
    "Metadata": {}
}

ServerSideEncryptionAES256 です。これはSSE-S3を意味します。ではこれを SSE-KMS に変更してみます。

$ aws s3api update-object-encryption \
  --bucket my-bucket \
  --key test-encryption-change.txt \
  --object-encryption '{
    "SSEKMS": {
      "KMSKeyArn": "arn:aws:kms:ap-northeast-1:123456789012:key/01234567-89ab-cdef-0123-456789abcdef",
      "BucketKeyEnabled": true
    }
  }'

レスポンスなしで正常終了しました。再度 head-object で確認します。

{
    "AcceptRanges": "bytes",
    "LastModified": "2026-03-06T08:14:58+00:00",
    "ContentLength": 78,
    "ETag": "\"a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6\"",
    "ContentType": "binary/octet-stream",
    "ServerSideEncryption": "aws:kms",
    "Metadata": {},
    "SSEKMSKeyId": "arn:aws:kms:ap-northeast-1:123456789012:key/01234567-89ab-cdef-0123-456789abcdef",
    "BucketKeyEnabled": true
}

ServerSideEncryptionaws:kms に変わり、SSEKMSKeyIdBucketKeyEnabled が追加されています。注目すべきは LastModifiedETag が全く変わっていない点です。ドキュメント通り、メタデータが完全に保持されていることを確認できました。

SSE-S3への戻しを試す

ドキュメントにはSSE-S3をターゲットにできないと書いてありますが、実際に試してみました。

$ aws s3api update-object-encryption \
  --bucket my-bucket \
  --key test-encryption-change.txt \
  --object-encryption '{"SSES3": {}}'
An error occurred (ParamValidation): Parameter validation failed:
Unknown parameter in ObjectEncryption: "SSES3", must be one of: SSEKMS

パラメータレベルでそもそも SSEKMS しか受け付けません。CLIのバリデーションで弾かれるので、APIリクエスト自体が送信されません。

エイリアス名で試す

KMSKeyArn にはフルARNが必要と書いてありますが、エイリアスを指定するとどうなるか試してみました。

$ aws s3api update-object-encryption \
  --bucket my-bucket \
  --key test-encryption-change.txt \
  --object-encryption '{"SSEKMS": {"KMSKeyArn": "alias/aws/s3", "BucketKeyEnabled": true}}'
An error occurred (ParamValidation): Parameter validation failed:
Invalid length for parameter ObjectEncryption.SSEKMS.KMSKeyArn, value: 12, valid min length: 20

こちらもCLI側のバリデーションで弾かれます。フルARN(arn:aws:kms:...)以外は受け付けないので、既存のスクリプトで alias/my-key のようなエイリアスを使っている場合は書き換えが必要です。

SSE-KMS → SSE-KMS(別キー)への変更

SSE-S3からの移行だけでなく、既にSSE-KMSで暗号化されたオブジェクトのKMSキーを別のキーに変更することもできます。コンプライアンス要件で「年1回キーをローテーションしろ」と求められるケースでは、これが使えます。

まず、KMSキーAで暗号化したオブジェクトを用意します。

$ aws s3api head-object --bucket my-bucket --key test-kms-to-kms.txt
{
    "ServerSideEncryption": "aws:kms",
    "SSEKMSKeyId": "arn:aws:kms:ap-northeast-1:123456789012:key/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
}

別のKMSキーBに変更します。

$ aws s3api update-object-encryption \
  --bucket my-bucket \
  --key test-kms-to-kms.txt \
  --object-encryption '{
    "SSEKMS": {
      "KMSKeyArn": "arn:aws:kms:ap-northeast-1:123456789012:key/fedcba98-7654-3210-fedc-ba9876543210",
      "BucketKeyEnabled": true
    }
  }'
{
    "ServerSideEncryption": "aws:kms",
    "SSEKMSKeyId": "arn:aws:kms:ap-northeast-1:123456789012:key/fedcba98-7654-3210-fedc-ba9876543210",
    "BucketKeyEnabled": true
}

SSEKMSKeyId が変わり、LastModifiedETag はそのまま保持されていました。これまでKMSキーのローテーションにも CopyObject が必要だったので、この改善は大きいと思います。

S3 Batch Operations での大規模移行

単体オブジェクトの変更はCLIで十分ですが、バケット全体のSSE-S3オブジェクトをSSE-KMSに一括移行したい場合はS3 Batch Operationsを使います。公式ドキュメントには以下のように記載されています(AWS ドキュメント)。

A single UpdateObjectEncryption operation job can support a manifest with up to 20 billion objects.

1ジョブで最大200億オブジェクトのマニフェストをサポートするとのことです。

MatchAnyObjectEncryption フィルタを使うと、マニフェスト生成時に暗号化タイプでフィルタリングできます。SSE-S3のオブジェクトだけを対象にしたリストを自動生成してくれるので、事前にインベントリを用意する手間が省けます。

必要なIAM権限

このAPIを使うためのIAMポリシーは以下のようになります。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:UpdateObjectEncryption",
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::my-bucket/*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "kms:Encrypt",
        "kms:Decrypt",
        "kms:GenerateDataKey",
        "kms:ReEncrypt*"
      ],
      "Resource": "arn:aws:kms:ap-northeast-1:123456789012:key/*"
    }
  ]
}

s3:UpdateObjectEncryption という新しいアクションが追加されています。既存のIAMポリシーにはこのアクションが含まれていないはずなので、明示的に許可する必要があります。逆に言えば、このアクションを許可しなければ既存の暗号化設定を変更される心配はありません。最小権限の原則に基づいて、必要なロールにのみ付与することを強くお勧めします。

S3 Batch Operations用のIAMロールには、さらに以下の権限が必要です。

  • s3:GetObject / s3:GetObjectVersion(ソースオブジェクトの読み取り)
  • s3:PutInventoryConfiguration(マニフェスト自動生成用)
  • マニフェストバケットと完了レポートバケットへの s3:PutObject / s3:GetObject

Terraform での暗号化管理

Terraformを使っている環境では、バケットレベルのデフォルト暗号化設定は aws_s3_bucket_server_side_encryption_configuration リソースで管理できます。

resource "aws_kms_key" "s3_encryption" {
  description             = "KMS key for S3 encryption"
  deletion_window_in_days = 7
  enable_key_rotation     = true
}

resource "aws_s3_bucket_server_side_encryption_configuration" "example" {
  bucket = aws_s3_bucket.example.id

  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm     = "aws:kms"
      kms_master_key_id = aws_kms_key.s3_encryption.arn
    }
    bucket_key_enabled = true
  }
}

ただし、これはあくまで「新規オブジェクトのデフォルト暗号化」の設定です。既存オブジェクトの暗号化タイプは変更されません。既存オブジェクトの暗号化を変更するには、今回の UpdateObjectEncryption APIをCLIやSDK、S3 Batch Operations経由で使う必要があります。

ここは見落としがちですが、Terraformでデフォルト暗号化を変更しただけで安心してはいけません。コンプライアンス監査で「全てのオブジェクトがSSE-KMSか」と聞かれた場合、既存オブジェクトが移行済みかどうかは別途確認が必要です。

注意すべき制約

いくつか運用上気をつけるべきポイントがあります。

Object Lock との関係: Compliance-modeのリテンションが設定されたオブジェクトには使えません。Governance-modeやLegal Holdの場合も、先にそれを解除する必要があります。コンプライアンス要件でObject Lockを使っている環境では、この制約は事前に確認しておくべきです。

レプリケーションとの関係: UpdateObjectEncryption はレプリケーションイベントを発生させません。つまりCRR(クロスリージョンレプリケーション)やSRR(同一リージョンレプリケーション)を設定していても、レプリカ側の暗号化は自動更新されません。ソースとレプリカの両方で個別に実行する必要があります。

クロスアカウントKMSキー: デフォルトではバケットオーナーのAWSアカウントが所有するKMSキーのみ使用可能です。AWS Organizations配下の他のメンバーアカウントのキーを使いたい場合は、AWSサポートへのリクエストが必要になります。

バージョニング: バージョニングが有効なバケットでは、VersionId を指定しないと現在のバージョンのみが対象になります。過去バージョンの暗号化も変更したい場合は、バージョンIDを個別に指定する必要があります。

料金

UpdateObjectEncryption のリクエストは、PUT/COPY/POST/LISTリクエストとして課金されます。オブジェクトの実際のストレージクラスに関係なく、S3 Standardのリクエスト料金が適用されます(2026年1月29日 AWS ドキュメント)。

データ転送料金は発生しません(データが移動しないため)。ただしKMS APIの呼び出し料金は別途発生します。S3 Bucket Keyを有効にすると、KMSへのリクエスト数を大幅に削減できるので、大量のオブジェクトを移行する場合はBucket Keyの有効化を合わせて検討すると良いと思います。

まとめ

UpdateObjectEncryption はコンプライアンス対応で暗号化移行に苦労してきた人にとって待望のAPIだと思います。データのコピーが不要で、メタデータも保持され、S3 Batch Operationsで200億オブジェクトまで一括処理できます。

ただし、SSE-S3への「戻し」ができない点、Object Lockとの制約、レプリカへの非伝播といった制約は押さえておく必要があります。また s3:UpdateObjectEncryption という新しいIAMアクションが追加されているので、既存のポリシーを見直して、不必要に権限が広がっていないか確認することをお勧めします。

全てのAWSリージョンで利用可能です。詳細は公式ドキュメントを確認してください(2026年1月29日 AWS ドキュメント)。