[アップデート]S3の条件付き書き込みをバケットポリシーで強制できるようになりました
こんにちは、リテールアプリ共創部の塚本です。
2024年11月25日に、S3のバケットポリシーにて条件付き書き込みを強制する機能が追加されました。
今回の記事では、バケットポリシーを設定し、実際に条件付き書き込みを強制できるかを確認します。
条件付き書き込みは簡単に説明すると、S3へのリクエスト時に特定のヘッダーを付与することで、上書き防止や競合防止を実現できる機能です。
条件付き書き込みの詳しい仕様については、以下のブログをご参照ください。
試してみた
if-none-match
と if-match
どちらのヘッダーも強制する設定が可能です。
今回は上書き防止用の if-none-match
ヘッダーをバケットポリシーで強制してみます。
User Guideに詳しい記載があるので、こちらを参考にして試してみます。
バケットポリシーの設定
S3バケットを作成し、以下のバケットポリシーを設定します。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowConditionalPut",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<ACCOUNT_ID>:user/<IAM_USER>"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::<BUCKET_NAME>/*",
"Condition": {
"Null": {
"s3:if-none-match": "false"
}
}
}
]
}
以下、個別の設定を見ていきます。
"Principal": {
"AWS": "arn:aws:iam::<ACCOUNT_ID>:user/<IAM_USER>"
},
こちらで設定するIAMユーザーは、後ほどAWS CLIを実行する際のユーザーです。
事前に、S3に関する権限を何も付与していないユーザーを用意しました。
"Condition": {
"Null": {
"s3:if-none-match": "false"
}
}
こちらの箇所ではNull演算子を利用し、「if-none-match
ヘッダーが存在し、その値がnullではないこと」を条件としています。
if-none-match
ヘッダなしで put-objectを実行する => オブジェクトが作成されない
同名オブジェクトがなし・$ aws s3api put-object --bucket "<BUCKET_NAME>" --key "test-object" --body test-file.txt
An error occurred (AccessDenied) when calling the PutObject operation: User: arn:aws:iam::<ACCOUNT_ID>:user/<USER_NAME> is not authorized to perform: s3:PutObject on resource: "arn:aws:s3:::<BUCKET_NAME>/test-object" because no identity-based policy allows the s3:PutObject action
バケットポリシーの設定通り、if-none-match
がない場合はバケットポリシーにて権限が設定されていないため、PutObjectに失敗します。
if-none-match
ヘッダありで put-objectを実行する => オブジェクトが作成される
同名オブジェクトなし・$ aws s3api put-object --bucket "<BUCKET_NAME>" --key "test-object" --body test-file.txt --if-none-match "*"
{
"ETag": "\"hogehoge\"",
"ServerSideEncryption": "AES256"
}
バケットポリシーの設定通り、if-none-match
がある場合はバケットポリシーにて権限が設定されているため、PutObjectに成功します。
if-none-match
ヘッダありで put-objectを実行する => 上書きされない
同名オブジェクトあり・$ aws s3api put-object --bucket "<BUCKET_NAME>" --key "test-object" --body test-file.txt --if-none-match "*"
An error occurred (PreconditionFailed) when calling the PutObject operation: At least one of the pre-conditions you specified did not hold
念の為、同名オブジェクトがある場合も試してみました。
通常の動作通り、同名オブジェクトが存在するので上書きすることができません。
おわりに
今回、Amazon S3のアップデートである「条件付き書き込みのバケットポリシーによる強制」を実際に試してみました。主な内容は以下の通りです:
- バケットポリシーを使用して、if-none-match ヘッダーの使用を強制する設定を行いました。
- AWS CLIを使用して、ヘッダーありとなしの両方のケースでPutObjectを実行し、動作を確認しました。
- 期待通り、if-none-match ヘッダーがない場合はアクセスが拒否され、ヘッダーがある場合はオブジェクトの作成に成功しました。
この機能により、S3バケットレベルで条件付き書き込みを強制できるようになり、データの整合性を保護するための新たな選択肢が増えました。特に、複数のクライアントやアプリケーションが同じバケットにアクセスするような環境で有用だと感じました。
この新機能は、特定のシナリオで非常に有効に機能しそうです。今後、実際のプロジェクトでの適用を検討し、その効果を実践的に検証していきたいと思います。