Amazon S3のアクセスコントロール入門

こんにちは。廣田です。
Amazon S3といえば、配信用のコンテンツを置いたり、Webページをホスティングさせたり、ログファイルをとりあえず突っ込んだりできるAWSでも最古参のサービスです。Webサービスのデータ置き場として使っている方も多いのではないでしょうか。
今日は、S3上のデータへのアクセスを制御・制限する方法について、基本的なキーワードや設定をご紹介したいと思います。

アクセス権限の種類

S3には「許可(Allow)」「明示的拒否(Explicit Deny)」「デフォルト拒否(Default Deny)」という3つのアクセス権限が存在し、 強い方から 明示的拒否 > 許可 > デフォルト拒否 という優先順位がつけられています。
S3ではあるオブジェクトに対して複数の場所でアクセス権限を設定することができますが、評価の順番は関係なく順位の高いものが適用されます。また、アクセス権限の設定が一つも存在しない場合はデフォルト拒否が適用されます。

「許可」の設定だけが存在 → 許可
「許可」の設定と「明示的拒否」の設定が存在 → 拒否
アクセス権限の設定が一つも存在しない → 拒否

アクセス権限を設定できる場所

現在のS3では、上で述べたアクセス権限を以下の3ヶ所で設定できます。

  • ACL(Access Control List)
  • バケットポリシー
  • IAMポリシー

一つずつ見てみましょう。なお、スクリーンショットでは昨年末から導入された新しいS3コンソールを使用しています。

ACL(Access Control List)

ACLでは、バケットやオブジェクトについて、特定のユーザに対するアクセス権限を設定できます。公式ドキュメントなどでは、アクセス権限が設定されるユーザのことを被付与者(Grantee)といいます。

S3コンソール上では、バケットを開いた後、上部のタブから「アクセス権限」を選び、「アクセスコントロールリスト」をクリックすると設定の確認と変更ができます。「オブジェクトアクセス」と「アクセス許可」の2つがありますが、これはそれぞれ「オブジェクトそのものへのアクセス」と「オブジェクトのアクセス権限の編集権限」を示しています。アクセス権限を知らない人に編集されては困るので、通常はオブジェクトアクセスの設定を変更することになると思います。
ACL_プロパティ
また、バケットのACLについてはバケット作成時に設定することもできます。項目の名前が少し違いますが、内容は上と同じです。
ACL_バケット作成時

注意点:ACLでは読み込みや書き込みを「許可」することしかできないようです。S3コンソール上でチェックを外した場合、明示的拒否ではなく設定そのものが存在しないという扱いになります。このため、バケットポリシーなどにアクセスを許可する設定が存在するとアクセスが可能になります。

バケットポリシー

バケットポリシーでは、ユーザやS3以外のAWSサービスに対するアクセス権限を設定できます。設定されるユーザやサービスのことをプリンシパル(Principal)といい、IAMユーザやIAMロールなどARN(Amazon Resource Name)の付いているリソースを指定できます。ただし、例外的にIAMグループは指定できません。無効なARNを指定するとバケットポリシーの保存時にエラーが出るので、表示されたエラーでググるなりして別の方法を考える必要があります。

S3コンソール上では、「アクセス権限」→「バケットポリシー」を選ぶとバケットポリシーの編集画面が表示されます。ACLとは異なり、単なる許可/拒否だけでなくリクエストの内容に応じた条件付きの許可設定なども可能です。その分設定の書き方が複雑なので、公式ドキュメントのサンプルを活用したり、AWS Policy Generatorを使うのが良いと思います。
バケットポリシー

例えば、S3へのアクセスをCloudFront経由のみに限定したい場合、以下のようにプリンシパルにCloudFrontのARNを指定してS3のファイル取得を許可します。このバケットポリシー以外にアクセス権限の設定が存在しなければ、CloudFront経由以外のアクセスにはデフォルト拒否が適用されてアクセスできなくなります。

{
  "Version": "2008-10-17",
  "Id": "PolicyForCloudFrontPrivateContent",
  "Statement": [
    {
      "Sid": "1",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity <CloudFront Distribution ID>"
      },
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::<バケット名>/*"
    }
  ]
}

注意点:特定のプリンシパルに対するアクセス権限の例外を設定する方法としてNotPrincipalという指定がありますが、これは使い方に注意が必要です。
まず、”Effect”:”Allow”を指定して全てのプリンシパルにアクセスを許可しつつ、NotPirincipalで例外的に拒否するプリンシパルを指定するのはNGとされています。

“Effect”: “Allow” と同じポリシーステートメント内で NotPrincipal を使用すると、指定のプリンシパルを除き、匿名の(承認されていない)ユーザーを含めた
すべてのプリンシパルに、このポリシーステートメントで指定されているアクセス許可が付与されます。NotPrincipal は、”Effect”: “Allow” と同じ
ポリシーステートメント内で使用しないことを強くお勧めします。
IAM ポリシーエレメントの参照 – 非プリンシパル

反対に、”Effect”: “Deny”を設定して全てのプリンシパルを拒否しつつ、NotPrincipalで例外的に許可するプリンシパルを指定する、ホワイトリスト的な設定は可能です。ただし、この場合は許可したいプリンシパルの親が遡って全て許可されている必要があります。例えば、12345678というAWSアカウントのBobというユーザをホワイトリストに入れたい場合、ユーザBobに加えてアカウント12345678もNotPrincipalに含める必要があります。
詳しい説明と例はIAM ポリシーエレメントの参照 – 非プリンシパル の「”Effect”: “Deny” と同じポリシーステートメント内で NotPrincipal を指定する」に記載があります。

IAMポリシー

IAMユーザやIAMロールに対してS3のアクセス権限を設定する別の方法として、IAMポリシーがあります。設定できる内容は(確認した範囲では)バケットポリシーと同じなので、ここでは省略します。

IAMポリシーはS3ではなくIAM上の設定なので、設定画面もIAMのページにあります。また、ElasticTranscoderなどサービスによっては必要なポリシーを自動的に生成して(インラインポリシーとして)IAMロールにアタッチしている場合もあるので、ポリシーのページに設定が見つからない場合はIAMロールの詳細も確認すると良いと思います。
IAMポリシー

設定の例

アクセス権限の設定を組み合わせて、S3に置いてある動画ファイルへの直接アクセスを禁止することを考えてみましょう。
アクセス制限概要

図で示したように、動画ファイルへのアクセス経路としては以下の4つが考えられます。

  1. インターネット上の匿名ユーザがS3のURLで直接アクセス
  2. 別途提供する認証付きURLを使用してCloudFront経由でアクセス
  3. 管理者(admin)グループのメンバーが管理コンソールからアクセス
  4. 動画エンコードのためにElasticTranscoderからアクセス

このうち、

  • ②CloudFront経由のアクセスにはOrigin Access Identity
  • ③管理コンソールではadminのIAMグループ
  • ④ElasticTranscoderではPipelineに設定したIAMロール(のインラインポリシー)

の情報が付与されます。従って、①直接アクセスのみを禁止するためには以下の設定が必要です。

  • バケットとオブジェクトのACLで、adminグループに対して読み書きを許可
  • バケットポリシーで、Origin Access Identity付きのリクエストに対して読み込みを許可
  • IAMの(インライン)ポリシーで、Pipeline Roleに対して読み書きを許可

表として整理すると以下のようになります。

アクセス元 アクセス権限の設定 アクセスの可否
バケットACL オブジェクトACL バケットポリシー IAMポリシー
①直接アクセス 不可(デフォルト拒否)
②CloudFront経由 Read Read
③管理コンソール Read/Write Read/Write Read/Write
④ElasticTranscoder Read/Write Read/Write

おわりに

入門といいながら、思ったよりボリュームのある記事になってしまいました。アクセス権限という一つの対象に対して複数の設定手段があるので最初は混乱しますが、権限に優先順位があり、設定する対象によって設定場所が違うところがポイントでしょうか。また、上の例のように想定されるアクセス経路と対応する設定内容を書き出してみるのも状況が整理できて良いと思います。

最後までお付き合いありがとうございました!

SNSでもご購読できます。