📓

AWS Lambda/S3:getObjectが403エラー吐いた時のActionとResourceの整理

2022/01/21に公開

動機

Typescript + AWS lambdaでS3クライアント(aws-sdk)を使用して、アップロードされているObjectを取得する、 S3.getObject() というメソッドを実行した時に403を吐き続けたので、改めて必要なIAM周りを整理してみることにしました。

解決策

結果的に以下の2点を整理し直しました。

  1. S3.getObject() を実行するのに許可するべきアクション
  2. S3.getObject() を実行するのに必要なリソース

1. S3.getObject() を実行するのに許可するべきアクション

これは下記のリンクからわかるのですが、 s3:ListBuckets3:getObject が必要です。

https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getObject-property

You need the s3:GetObject permission for this operation. For more information, see Specifying Permissions in a Policy. If the object you request does not exist, the error Amazon S3 returns depends on whether you also have the s3:ListBucket permission.
If you have the s3:ListBucket permission on the bucket, Amazon S3 will return an HTTP status code 404 ("no such key") error.
If you don’t have the s3:ListBucket permission, Amazon S3 will return an HTTP status code 403 ("access denied") error.

2. S3.getObject() を実行するのに必要なリソース

許可するべきアクションから実行するリソースを調べたところ

listBucket には arn:aws:s3:::bucket-name
getObject には arn:aws:s3:::bucket-name/*

がそれぞれ必要だったのでResourceにアタッチすれば S3.getObject() が実行できるはずです。

書き方例

[
  {
    Action: ['s3:GetObject'],
    Resource: {
      'Fn::Join': [
        '',
        [
          {
	    'Fn::GetAtt': ['bucket-name', 'Arn'],
	  },
	  '/*'
        ],
      ],
    },
    Effect: 'Allow',
  },
  {
    Action: ['s3:ListBucket'],
    Resource: {
      'Fn::GetAtt': ['bucket-name', 'Arn']
    },
    Effect: 'Allow',
  }
]

リンク

https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getObject-property
https://www.yamamanx.com/aws-lambda-s3-select/

Discussion