【S3】特定のフォルダのみアクセスを許可する

1つのS3バケットに複数のフォルダを作成した場合、特定のフォルダのみアクセス可能な
IAMユーザが必要になるときがあります。この記事では表題の要件を満たすIAMポリシー
と実際の動作について検証した結果を記載します。


S3バケットのフォルダは上記のように作成してみました。今回はfolder1配下の
test1」と「test2」のみアクセスを許可するIAMポリシーを作成してみます。
併せて、特定のIPアドレスからのみ接続できるように制限をかけてみます。

 

IAMポリシーの作成

早速結論ですが、今回の要件を満たすIAMポリシーは下記の通りです。

{
 "Version":"2012-10-17",
 "Statement": [
   {
     "Effect": "Allow",
     "Action": [
         "s3:ListAllMyBuckets"
     ],
     "Condition": {
         "IpAddress": {
             "aws:SourceIp": [
                 "接続元IPアドレス/32"
             ]
         }
     },
     "Resource": [
         "arn:aws:s3:::*"
     ]
   },
   {
     "Effect": "Allow",
     "Action": [
         "s3:ListBucket",
         "GetBucketLocation"
     ],
     "Condition": {
         "IpAddress": {
             "aws:SourceIp": [
                 "接続元IPアドレス/32"
             ]
         },
         "StringEquals": {
             "s3:prefix": [
                 "",
                 "folder1/"
             ]
         }
     },
     "Resource": [
         "arn:aws:s3:::S3バケット名"
     ]
   },
   {
     "Effect": "Allow",
     "Action": [
         "s3:ListBucket",
         "GetBucketLocation"
     ],
     "Condition": {
         "IpAddress": {
             "aws:SourceIp": [
                 "接続元IPアドレス/32"
             ]
         },
         "StringEquals": {
             "s3:prefix": [
                 "",
                 "test1/",
                 "test2/"
             ]
         }
     },
     "Resource": [
         "arn:aws:s3:::S3バケット名/folder1"
     ]
   },
   {
     "Effect": "Allow",
     "Action": [
         "s3:ListBucket",
         "GetBucketLocation"
     ],
     "Condition": {
         "IpAddress": {
             "aws:SourceIp": [
                 "接続元IPアドレス/32"
             ]
         },
         "StringLike": {
             "s3:prefix": [
                 "",
                 "folder1/test1/*",
                 "folder1/test2/*"
             ]
         }
     },
     "Resource": [
         "arn:aws:s3:::S3バケット名"
     ]
   },
   {
     "Effect": "Allow",
     "Action": [
         "s3:*"
     ],
     "Condition": {
         "IpAddress": {
             "aws:SourceIp": [
                 "接続元IPアドレス/32"
             ]
         }
     },
     "Resource": [
         "arn:aws:s3:::S3バケット名/folder1/test1/*",
         "arn:aws:s3:::S3バケット名/folder1/test2/*",
     ]
   }
  ]
}


1つ目のAllowステートメントでは、ユーザ自身のアカウントに存在するS3バケット
一覧表示することを許可しています。

2つ目と3つ目のAllowステートメントでは、フォルダ「folder1」「test1」「test2」を
一覧表示することを許可しています。

4つ目のAllowステートメントでは、フォルダ「test1」「test2」のコンテンツを
一覧表示することを許可しています。

5つ目のAllowステートメントでは、フォルダ「test1」「test2」で全てのS3アクション
(読み取り, 書き込み, 削除など) を実行することを許可しています。

 

動作確認

今回はAWS CLIから接続を確認してみたいと思います。

まずはバケットのフォルダを表示してみたいと思います。

    $ aws s3 ls s3://S3バケット名/
                               PRE folder1
                               PRE folder2

問題なく表示されました。

それではフォルダ「folder1」を表示してみたいと思います。

    $ aws s3 ls s3://S3バケット名/folder1/
                               PRE test1
                               PRE test2
                               PRE test3
    yyyy-mm-dd hh:mm:ss          0                  

こちらも問題なく表示されました。

つづいてフォルダ「folder2」を表示してみたいと思います。

    $ aws s3 ls s3://S3バケット名/folder2/

    An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied

こちらは想定通りアクセスできません。

つづいてフォルダfolder1内のtestフォルダをそれぞれ表示してみたいと思います。

    $ aws s3 ls s3://S3バケット名/folder1/test1/
    yyyy-mm-dd hh:mm:ss          0 
    yyyy-mm-dd hh:mm:ss         54 abc.txt
    $ aws s3 ls s3://S3バケット名/folder1/test2/
    yyyy-mm-dd hh:mm:ss          0                  
    $ aws s3 ls s3://S3バケット名/folder1/test3/

    An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied                

こちらも想定通り「test1」と「test2」にアクセスできており、「test3」にはアクセス
できません。※「test1」には事前にテキストファイル「abc.txt」をアップロードして
いたため当該ファイルが表示されています。

それではフォルダfolder1内のオブジェクト「abc.txt」を削除してみたいと思います。

    $ aws s3 rm s3://S3バケット名/folder1/test1/abc.txt
    delete: s3://S3バケット名/folder1/test1/abc.txt          
    $ aws s3 ls s3://S3バケット名/folder1/test1/
    yyyy-mm-dd hh:mm:ss          0 

削除アクションも問題なく実行できることが確認できました。

それでは最後に別の接続元IPアドレスを許可した場合の接続を確認してみます。
IAMポリシーのIPアドレスの記載を変更後にS3バケットを表示してみます。

    $ aws s3 ls s3://S3バケット名/

    An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied                

こちらも想定通りアクセスが拒否されました。
接続元IPアドレス制限もしっかり機能していることが確認できました。

 

以上で特定のフォルダのみアクセスを許可するIAMポリシーの設定は完了になります。

最後までご覧いただきありがとうございました。