S3の特定パスのみに対して全ての操作が可能なIAMポリシー
西澤です。今回は、S3バケットの特定パスに対するアクセス権限制御について、お客様から質問いただき、正確に理解できていなかったところを調査したので、整理してみます。
このポリシーで実行可能なアクションについて正確に回答できますか?
いきなりですが、クイズです。下記のようなポリシーにより権限付与されたユーザのアクセス範囲を正確に説明することはできますか?
{ "Version": "2012-10-17", "Statement": [ { "Action": "s3:*", "Effect": "Allow", "Resource": "arn:aws:s3:::access-control-on-specific-path/dir_a/*" } ] }
今回調べてみる前まで、試さないとよくわからない、というのが正直なところでした。ポリシー設定用のjsonを読んだことがある方なら想像がつくとは思いますが、S3上の特定パスのみへのアクセス権限を制御したい、というのが今回やりたいことです。
オブジェクトの一覧取得ができない
このアクセス権限を有したIAMユーザを使って、特定パス(dir_a/*
)へのGet/Put/Deleteができること、特定パス(dir_a/*
)以外へのGet/Put/Deleteができないことは、すぐに確認できました。
$ aws s3 cp ./test.txt s3://$BUCKET/dir_a/ upload: ./test.txt to s3://access-control-on-specific-path/dir_a/test.txt $ aws s3 cp ./test.txt s3://$BUCKET/dir_b/ upload failed: ./test.txt to s3://access-control-on-specific-path/dir_b/test.txt An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
ただし、一覧取得ができませんでした。これは一体どういうことでしょうか?
$ aws s3 ls s3://$BUCKET/dir_a/ An error occurred (AccessDenied) when calling the ListObjects operation: Access Denied $ aws s3 ls s3://$BUCKET/dir_b/ An error occurred (AccessDenied) when calling the ListObjects operation: Access Denied
ListObjectsなんていうS3のアクションは存在しない
このエラーメッセージを見ると、ListObjectsというアクセス権限を付与すれば良さそうなのですが、公式ドキュメントを見ても、そもそもそのようなS3のアクションは存在していません。
S3のアクションの種類
S3のアクションには、下記の種類があります。
S3のアクションの種類 | 制御対象 | 説明 |
---|---|---|
オブジェクトオペレーション | オブジェクト | オブジェクトの操作 |
バケットオペレーション | バケット | バケットそのものの操作 |
バケットサブリソースオペレーション | バケット | バケットのサブリソース(プロパティ等)の操作 |
このうち、後ろの2種類は、バケットに対するアクションです。つまり、前述のポリシーでは、s3:*
という全アクション指定をしているものの、arn:aws:s3:::access-control-on-specific-path/dir_a/*
という形式でバケットではなくオブジェクトでリソース指定をしている為に、実質的には後ろの2種類のバケット操作系の権限は付与されていないということになります。
ListObjectsするにはs3:ListBucketが必要
今回エラーとなって実行できていないListObjectsをする為には、s3:ListBucket
権限が必要なことがわかりました。s3:ListBucket
はバケットオペレーションとなる為、バケットをリソースとして権限を付与する必要があります。
- オブジェクトオペレーション
- s3:GetObject
- s3:GetObjectVersion
- s3:PutObject
- s3:GetObjectAcl
- s3:GetObjectVersionAcl
- s3:PutObjectAcl
- s3:PutObjectVersionAcl
- s3:DeleteObject
- s3:DeleteObjectVersion
- s3:ListMultipartUploadParts
- s3:AbortMultipartUpload
- s3:GetObjectTorrent
- s3:GetObjectVersionTorrent
- s3:RestoreObject
- s3:PutObjectTagging
- s3:PutObjectVersionTagging
- s3:GetObjectTagging
- s3:GetObjectVersionTagging
- s3:DeleteObjectTagging
- s3:DeleteObjectVersionTagging
- バケットオペレーション
- s3:CreateBucket
- s3:DeleteBucket
- s3:ListBucket
- s3:ListBucketVersions
- s3:ListAllMyBuckets
- s3:ListBucketMultipartUploads
- バケットサブリソースオペレーション
- s3:GetAccelerateConfiguration
- s3:PutAccelerateConfiguration
- s3:GetBucketAcl
- s3:PutBucketAcl
- s3:GetBucketCORS
- s3:PutBucketCORS
- s3:GetBucketVersioning
- s3:PutBucketVersioning
- s3:GetBucketRequestPayment
- s3:PutBucketRequestPayment
- s3:GetBucketLocation
- s3:GetBucketPolicy
- s3:DeleteBucketPolicy
- s3:PutBucketPolicy
- s3:GetBucketNotification
- s3:PutBucketNotification
- s3:GetBucketLogging
- s3:PutBucketLogging
- s3:GetBucketTagging
- s3:PutBucketTagging
- s3:GetBucketWebsite
- s3:PutBucketWebsite
- s3:DeleteBucketWebsite
- s3:GetLifecycleConfiguration
- s3:PutLifecycleConfiguration
- s3:PutReplicationConfiguration
- s3:GetReplicationConfiguration
- s3:DeleteReplicationConfiguration
- ポリシーでのアクセス許可の指定 - Amazon Simple Storage Service
特定パスのみListObjectsも可能なポリシー
ということで、ListObjectsも含め、特定パス配下に全ての操作を許す為のポリシーは下記となりました。ポイントは、バケットオペレーションであるs3:List*
を、バケットのみ(パス情報は付けない)をリソースとして設定し、Condition
からs3:prefix
を利用して特定パスのみに絞るところです。
{ "Version": "2012-10-17", "Statement": [ { "Action": "s3:*", "Effect": "Allow", "Resource": "arn:aws:s3:::access-control-on-specific-path/dir_a/*" }, { "Action": "s3:List*", "Effect": "Allow", "Resource": "arn:aws:s3:::access-control-on-specific-path", "Condition": { "StringLike": { "s3:prefix": "dir_a/*" } } } ] }
s3:List*
のところは、s3:ListBucket
でも良さそうですが、バージョン管理が有効となっているバケットでは、s3:ListBucketVersions
が必要となる場合もある為、まとめて権限付与する設定としました。
$ aws s3 ls s3://$BUCKET/dir_a/ PRE data/ PRE data2/ PRE data3/ 2017-02-24 20:37:45 15 index.html 2017-02-27 08:59:32 15 index2.html 2017-02-27 09:43:43 231 index3.html 2017-03-09 15:09:22 5 test.txt $ aws s3 ls s3://$BUCKET/dir_b/ An error occurred (AccessDenied) when calling the ListObjects operation: Access Denied
これで上手く制御できそうですね。
まとめ
今回の記事について理解が難しかった方は、個人的に殿堂入りにすべきだと思っている都元さんの記事をぜひお読みいただき、そもそもS3のパスって何なのかっていうところを、まずは理解しておくと良いと思います。
というか、ヘビーにAWSを利用されているユーザに取っては慣れっこになってしまっているのかもしれませんが、ちょっとS3バケットへのアクセス権限制御は難しすぎるという印象が拭えません。将来的にはもっと直感的な権限設定ができるようになると嬉しいですよね。
どこかの誰かのお役に立てば嬉しいです。