S3 の ListObjects, ListBucket などについてのあれこれ

S3 を色々触っていて気になる事・ちょっとハマった事などがいくつかあったので、それについて書く。

s3:ListObjects という action は存在しない

S3 API には、ListObjects という API がある。あるバケットのあるディレクトリ(正確には prefix だけど)配下のオブジェクト一覧を返すというもの。

ListObjects – Amazon Simple Storage Service

で、この操作を特定の人に許可するバケットポリシーを作成しようとして、s3:ListObjects という action を許可しようとしたら “S3 policy has invalid action” みたいなエラーが出た。

結論からすると、 s3:ListObjects という action は存在しない。ListObjects という操作をを許可するためには s3:ListBucket という action を許可する必要がある。

以下の SO が簡潔にまとまってる。

amazon web services – AWS Bucket Policy Error: Policy has invalid action – Stack Overflow

細かい解説を見たければ、日本語の以下の記事が詳しい。

S3の特定パスのみに対して全ての操作が可能なIAMポリシー | DevelopersIO

S3 の action の一覧などは、以下のページを参照。

Actions, resources, and condition keys for Amazon S3 – Service Authorization Reference

s3:ListBucket と s3:ListAllMyBuckets

前述の通り s3:ListBucket と言うのは、オブジェクト一覧を閲覧する許可するためのものであり、バケット一覧の閲覧を許可したい場合は s3:ListAllMyBuckets という action がある。AWS、S3 をある程度使っている人であれば、この名前にモヤモヤしている人も多いと思う。

以下の SO の回答によれば、S3 は AWS 最古参のサービスだから、その辺の名前付けとかがちゃんと決まってない時代の遺産なのでは、という事だった。

amazon web services – Invalid Action: The action s3:ListObjects does not exist – Stack Overflow

ちなみに、 s3:ListBucket は、”bucket” という単語が単数形なのに注意。ある1つの bucket の中身を一覧表示する、という意味なのが分かると思う。実際には存在しないが s3:ListBuckets という名前であれば、bucket の一覧を表示する意味だけど。

バケットへの操作とオブジェクトへの操作

S3 の action には、主にバケットへの操作とオブジェクトへの操作の2つに大別される。例えば、s3:ListObject はバケットへの操作であり、 s3:GetObject はオブジェクトへの操作である。

良くあるユースケースとして、some_role に対して example-bucket というバケットの dir-a というディレクトリ配下への読み込み権限を付与するという例を考える。この場合、

  • arn:aws:s3:::example-bucket に対して s3:ListBucket を許可
  • arn:aws:s3:::example-bucket/dir-a/* に対して s3:GetObject を許可

という形で権限設定を行う事になる。

CloudFormation の設定を抜粋すると以下のような感じになる。

  ExampleBucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref ExampleBucket
      PolicyDocument:
        Id: ExampleBucketPolicy
        Statement:
          - Sid: SomeRoleReadOnly
            Effect: Allow
            Action:
              - s3:GetObject
              - s3:ListBucket
            Resource:
              - "arn:aws:s3:::example-bucket"
              - "arn:aws:s3:::example-bucket/dir-a/*"
            Principal:
              AWS: "arn:aws:iam::1234567890:role/some_role"

ちょっと面白い(分かりづらい)のは 、action として s3:GetObjects3:ListBucket の2つを指定し、resource に arn:aws:s3:::example-bucketarn:aws:s3:::example-bucket/dir-a/* の2つを指定しているが、バケットに対する action (s3:ListBucket)はバケットに対してのみ適用され、オブジェクトに対する action (s3:GetObject)はオブジェクトに対してのみ適用されるということ。(当たり前といえば当たり前だけど。)

S3 の action として(主に)バケットへの操作とオブジェクトへの操作の2種類があるということを知らないと、上の CloudFormation の設定を見たときに、

「え? dir-a 以外の読み込みも許可されてしまうんじゃない?」

と思うかもしれない。

まとめ

S3 の権限設定は複雑すぎる。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です