S3初心者向け『例 3 :バケット所有者が自分の所有していないオブジェクトに対するアクセス許可をユーザーに付与』をやってみた

2019.09.05

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

概要

大阪オフィスのちゃだいんです。

手を動かして学ぶために、公式ドキュメントのチュートリアルをやってみました。

今回も、Amazon S3です。(いい意味とそうでない意味の両方の意味でハマってます)。前回の続編で、内容は以下のものです。

例 3: バケット所有者が自分の所有していないオブジェクトに対するアクセス許可をユーザーに付与 - Amazon Simple Storage Service

この例のシナリオでは、バケット所有者がオブジェクトへのアクセス許可を付与しますが、バケット内のオブジェクトの一部がバケット所有者によって所有されていません。バケット所有者は、自分が所有していないオブジェクトへのアクセス許可をどうすれば付与できるでしょうか。 この例では、バケット所有者は、自分のアカウントのユーザーにアクセス許可を付与しようとしています。

前提条件

AWS CLIが使用できる環境で行ってます。

また、2つのアカウントはドキュメントと同様に以下のように記載します。

AWSアカウントID アカウントの呼び方 アカウントの管理者ユーザー
1111-1111-1111 アカウント A AccountAadmin
2222-2222-2222 アカウント B AccountBadmin

早速やってみた

1. S3バケットとIAMユーザーを作成する(アカウントA側の作業)

  • いつも通り、マネジメントコンソールからS3バケットを作成します。

  • 今回のバケット名は190904testbucketにしました。

  • 続いて、IAMユーザーをアカウントA側に作成します。

  • 名前をTestUserAとします。このユーザーにIAMポリシーは一切与えてません。

※この辺の流れは以下の前回記事で書いてます

S3初心者向け『例 2 : バケット所有者がクロスアカウントのバケットのアクセス許可を付与』をやってみた

2. S3バケットポリシーを追加する(アカウントA側の作業)

  • 今回のお題は、アカウントBからファイルを保存できて、それをアカウントAのIAMユーザーが触れる状態です。

このポリシーは、アカウント B に s3:PutObject および s3:ListBucket アクセス許可を付与します。このポリシーはまた、アカウントA ユーザー TestUserA に s3:GetObject アクセス許可を付与します。 ※先述ドキュメントより引用してますが、本記事合わせ名称を少し変更しています

  • 以下のポリシーを190904testbucketのバケットポリシーに記入します。
{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Sid": "Statement1",
         "Effect": "Allow",
         "Principal": {
            "AWS": "arn:aws:iam::222222222222:root"
         },
         "Action": [
            "s3:PutObject"
         ],
         "Resource": [
            "arn:aws:s3:::190904testbucket/*"
         ]
      },
      {
         "Sid": "Statement3",
         "Effect": "Allow",
         "Principal": {
            "AWS": "arn:aws:iam::111111111111:user/TestUserA"
         },
         "Action": [
            "s3:GetObject"
         ],
         "Resource": [
            "arn:aws:s3:::190904testbucket/*"
         ]
      }  
   ]
}
  • 見切れてますが、こんな感じで保存しておきます。

3.バケットにファイルをアップロードする(アカウントB側の作業)

  • 先ほどのポリシーでアカウントB はアカウントA の190904testbucketに対するアクセス許可を得たはずです。

  • アカウントBの権限を使用して、実際にHotNepalFood.jpgをバケットにアップロードしてます。

  • 以下のようにaws s3api put-objectコマンドを実行します。

aws s3api put-object --bucket 190904testbucket --key HotNepalFood.jpg --body HotNepalFood.jpg --profile AccountBadmin
{
    "ETag": "\"174f062737b436f644aee3d43f9e577f\""
}
  • 成功したようです。S3コンソールをアカウントAの管理者として見てみましょう。

  • ちゃんと画像ファイルが入ってます。このオブジェクトの所有者は誰になっているでしょうか。

  • 詳細をのぞくと赤枠の部分にアカウントBの名前が入ってました。

4.オブジェクト所有者がバケット所有者に、オブジェクトに対するフルコンロールをオブジェクトACLにて許可する(アカウントB側の作業)

  • 小見出しがとても長いですが、そういうことをやります。

  • その前に、この許可を与える前にアカウントAのTestUserAがオペレーションできるか試します。

  • 以下のコマンドを実行します。

$ aws s3api get-object --bucket 190904testbucket --key HotNepalFood.jpg Outputfile.jpg --profile TestUserA

An error occurred (AccessDenied) when calling the GetObject operation: Access Denied
  • はい、拒否られました。

  • では、ちゃんと小見出しの内容を実現するコマンドを実行してみます。

$ aws s3api put-object-acl --bucket 190904testbucket --key HotNepalFood.jpg --grant-full-control id=************************************************* --profile accountBadmin
  • id=*******...の部分はダミーですが、実際の正規ユーザーIDはS3バケットから取得しています。

  • 先ほどのaws s3api put-object-aclコマンドで許可されたはずなので、失敗したTestUserAによるオペレーション実行を再チャレンジします。
$ aws s3api get-object --bucket 190904testbucket --key HotNepalFood.jpg Outputfile.jpg --profile TestUserA
{
    "AcceptRanges": "bytes",
    "ContentType": "binary/octet-stream",
    "LastModified": "Thu, 05 Sep 2019 03:09:30 GMT",
    "ContentLength": 1809277,
    "ETag": "\"174f062737b436f644aee3d43f9e577f\"",
    "Metadata": {}
}
  • いけましたね!

  • ちなみに、オブジェクトのACLを見てみました。

  • 青枠がアカウントBの正規ユーザーID、赤枠がアカウントAの正規ユーザーID。コマンド実行前をみてなかったのですが、おそらくこの赤枠部分が追加されたはずです。

  • 以上で、今回のお題は完了です。

  • ちなみに、HotNepalFood.jpgとはこんな写真でした。(この赤唐辛子が涙でるレベルのHotさでした)

感想

今回は初めてオブジェクトACLを使用しました。オブジェクトACLを使用する際にはどうやら、正規ユーザーIDが鍵になるようです。

誰かのお役に立てば幸いです。それではまた、大阪オフィスのちゃだいんでした。