IAM の Condition によるアクセス制御を試してみる
2020-07-05AWS 認定ソリューションアーキテクト - プロフェッショナルの勉強をしている中で、 IAM の Condition によるアクセス制御の話が出てきたので、 S3 へのアクセスで実際に試してみようと思います。
目次
IAM ポリシーの作成
アクセス制御用の IAM ポリシーを作成します。今回は次のような制御を考えます。
- S3 に対する
ListObjects
またはListObjectsV2
API で取得できるオブジェクトの最大数を 2 とする
ListObjects
または ListObjectsV2
API を実行するためには s3:ListBucket
のアクセス許可が必要なので、このアクションに対して Condition エレメントで条件を指定します。
Condition エレメント
IAM ポリシーの Condition
エレメントでは、予め用意されている StringEquals
や NumericGreaterThan
といった条件演算子によって,
リクエストに含まれるコンテキストの値と条件の一致をチェックします。
条件演算子は次のような種類に分けられています。
- 文字列
- 数値
- 日付
- Bool
- バイナリ
- IP アドレス
- ARN
- IfExists
- 条件キーの有無
今回の条件は 「S3 に対する ListObjects または ListObjectsV2 API で取得できるオブジェクトのキー数の最大数を 2 とする」 なので、文字列条件演算子の NumericLessThanEquals
を使用して次のように記述します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:Get*"
],
"Resource": "arn:aws:s3:::iam-condition-test-bucket"
},
{
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::iam-condition-test-bucket",
"Condition": {
"NumericLessThanEquals": {
"s3:max-keys": "2"
}
}
}
]
}
この JSON の内容で IAM ポリシーを作成します。
s3:max-keys
の条件演算子を指定すると、 ListObjects
または ListObjectsV2
で max-keys
オプションを指定する必要があります。指定しない場合はそもそも条件に一致しないことになります。
If the key that you specify in a policy condition is not present in the request context, the values do not match.
その他、 Condition の詳細については下記の公式ドキュメントも合わせて。
ちなみに、 arn:aws:s3:::iam-condition-test-bucket
は今回の確認用に先に作成しておいた S3 バケットで、バケット内にはオブジェクトが 4 つ格納されています。
$ aws s3api create-bucket \
--bucket iam-condition-test-bucket \
--create-bucket-configuration LocationConstraint=ap-northeast-1
{
"Location": "http://iam-condition-test-bucket.s3.amazonaws.com/"
}
$ aws s3api list-objects-v2 \
--bucket iam-condition-test-bucket \
--query "Contents[].[Key]" \
--output text
sample_0.json
sample_1.json
sample_2.json
sample_3.json
ListObjectsV2 リクエストを実行
今回は AWS CLI で ListObjectsV2
リクエストを実行してみます。
AmazonS3ReadOnlyAccess ポリシーをアタッチした IAM ユーザで実行
まずは S3 への Read Only 権限 (AmazonS3ReadOnlyAccess) を持つ IAM ユーザで ListObjectsV2
を実行してみます。
$ aws s3api list-objects-v2 \
--bucket iam-condition-test-bucket
{
"Contents": [
{
"Key": "sample_0.json",
"LastModified": "2020-07-05T09:43:05+00:00",
"ETag": "\"ff2238a281fccd41c7698ef7a1e2236d\"",
"Size": 21,
"StorageClass": "STANDARD"
},
{
"Key": "sample_1.json",
"LastModified": "2020-07-05T09:42:12+00:00",
"ETag": "\"ff2238a281fccd41c7698ef7a1e2236d\"",
"Size": 21,
"StorageClass": "STANDARD"
},
{
"Key": "sample_2.json",
"LastModified": "2020-07-05T09:42:17+00:00",
"ETag": "\"ff2238a281fccd41c7698ef7a1e2236d\"",
"Size": 21,
"StorageClass": "STANDARD"
},
{
"Key": "sample_3.json",
"LastModified": "2020-07-05T09:42:51+00:00",
"ETag": "\"ff2238a281fccd41c7698ef7a1e2236d\"",
"Size": 21,
"StorageClass": "STANDARD"
}
]
}
バケット内のオブジェクトがすべて取得できました。
Condition 付きの IAM ポリシーをアタッチした IAM ユーザで実行
では、先ほど作成した IAM ポリシーを適当な IAM ユーザにアタッチして ListObjectsV2
を実行してみます。
$ aws s3api list-objects-v2 \
--bucket iam-condition-test-bucket
An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied
AccessDenied
エラーとなり、オブジェクトの一覧が取得できませんでした。
なので、条件に合うように --max-keys
オプションを指定して実行してみます。
$ aws s3api list-objects-v2 \
--bucket iam-condition-test-bucket \
--max-keys 2
{
"IsTruncated": true,
"Contents": [
{
"Key": "sample_0.json",
"LastModified": "2020-07-05T09:43:05+00:00",
"ETag": "\"ff2238a281fccd41c7698ef7a1e2236d\"",
"Size": 21,
"StorageClass": "STANDARD"
},
{
"Key": "sample_1.json",
"LastModified": "2020-07-05T09:42:12+00:00",
"ETag": "\"ff2238a281fccd41c7698ef7a1e2236d\"",
"Size": 21,
"StorageClass": "STANDARD"
}
],
"Name": "iam-condition-test-bucket",
"Prefix": "",
"MaxKeys": 2,
"EncodingType": "url",
"KeyCount": 2,
"NextContinuationToken": "17DiagPib4DkESmD7teHiRKAUOX3+2+PwEfdQ/orj+JJiIY9+KzSt0FY73/EOModsutwA/GSThwc="
}
取得できました。残りのオブジェクトを取得するためには、レスポンスの NextContinuationToken
を使って次のようにリクエストします。
$ aws s3api list-objects-v2 \
--bucket iam-condition-test-bucket \
--max-keys 2 \
--continuation-token 17DiagPib4DkESmD7teHiRKAUOX3+2+PwEfdQ/orj+JJiIY9+KzSt0FY73/EOModsutwA/GSThwc=
{
"IsTruncated": false,
"Contents": [
{
"Key": "sample_2.json",
"LastModified": "2020-07-05T09:42:17+00:00",
"ETag": "\"ff2238a281fccd41c7698ef7a1e2236d\"",
"Size": 21,
"StorageClass": "STANDARD"
},
{
"Key": "sample_3.json",
"LastModified": "2020-07-05T09:42:51+00:00",
"ETag": "\"ff2238a281fccd41c7698ef7a1e2236d\"",
"Size": 21,
"StorageClass": "STANDARD"
}
],
"Name": "iam-condition-test-bucket",
"Prefix": "",
"MaxKeys": 2,
"EncodingType": "url",
"KeyCount": 2,
"ContinuationToken": "17DiagPib4DkESmD7teHiRKAUOX3+2+PwEfdQ/orj+JJiIY9+KzSt0FY73/EOModsutwA/GSThwc="
}
今回の条件は "s3:max-keys": "2"
なので、次のリクエストでは AccessDenied
になります。
$ aws s3api list-objects-v2 \
--bucket iam-condition-test-bucket \
--max-keys 3
An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied
まとめ
IAM の Condition エレメントを使用して S3 への ListObjects
または ListObjectsV2
API のリクエストを制御してみました。
Condition を使用したアクセス制御としては、 EC2 インスタンスに特定のタグがなければ起動できないようにする例がありました。
また、今回は個人の AWS アカウント内での制御でしたが、 AWS Organizations の SCP (サービスコントロールポリシー) を使うことで組織内の AWS アカウントに対しても統一されたアクセス制御をすることができます。
このあたりは SAP の試験でもよく出てくる部分みたいなので、しっかり理解していきたいところです。
comments powered by Disqus