条件にリソースタグを使用したIAMポリシーについて
概要
普段IAMはちょっとした修正でしか触ることがないので初歩的な内容になりますが、
以下のIAMのドキュメントを読んでいて「なんでステートメントが2つ必要なのだろう?」と思ったので調べた内容のメモです。
※このようなポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:StartInstances",
"ec2:StopInstances"
],
"Resource": "arn:aws:ec2:*:*:instance/*",
"Condition": {
"StringEquals": {"aws:ResourceTag/Owner": "${aws:username}"}
}
},
{
"Effect": "Allow",
"Action": "ec2:DescribeInstances",
"Resource": "*"
}
]
}
結論
先に結論を書くと「DescribeInstancesなど一部のアクションはリソースレベルの許可をサポートしていないから」です。
条件に指定しているaws:ResourceTagはAWSリソースにアタッチされたタグのことを指します。
許可するActionをec2:*としていますが、EC2のすべてのアクションが個々のリソースを指定して実行できるわけではありません。
リソースを指定して実行できないアクションがリクエストされた場合このポリシーは許可されません。
どのアクションがリソースレベルでの許可をサポートしているかは以下のページから確認できます。
Amazon EC2 のアクション、リソース、および条件キー
動作確認
IAMの管理者ユーザーでNameタグとTeamというタグを持つEC2インスタンスを作成します。
| Nameタグ | Teamタグ |
|---|---|
| TeamAInstance | A |
| TeamBInstance | B |

同じくIAMの管理者ユーザーでTeamというタグを持つIAMユーザーを作成します。
| Name | Team |
|---|---|
| test | A |

作成したIAMユーザーには、自身に設定されたTeamタグと同じ値を持つEC2インスタンスへのアクションをすべて許可するポリシーをアタッチします。
失敗するポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Action": [
"ec2:*"
],
"Resource": [
"*"
],
"Condition": {
"StringEquals": {
"aws:ResourceTag/team": "${aws:PrincipalTag/Team}"
}
}
}
]
}
上記のポリシーではDescribeInstancesは許可されません。
先述の通り、リソースレベルの許可をサポートしていないアクションは許可されないためです。
このポリシーをアタッチされたユーザーがEC2コンソールからインスタンスの一覧を確認しようとしても何も表示されません。

成功するポリシー
上記の「失敗するポリシー」では「リソースレベルの許可をサポートしていない」アクションに対しての許可が足りません。
これらのアクションを許可するには、リソースに関する条件のないステートメントを別途追加する必要があります。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Action": [
"ec2:*"
],
"Resource": [
"*"
],
"Condition": {
"StringEquals": {
"aws:ResourceTag/team": "${aws:PrincipalTag/Team}"
}
}
},
{
"Sid": "Statement2",
"Effect": "Allow",
"Action": [
"ec2:Describe*"
],
"Resource": [
"*"
]
}
]
}
このポリシーではDescribeから始まるアクションも許可され、EC2コンソールからインスタンスの一覧を確認することができます。

Statement1の動作確認
「自身に設定されたTeamタグと同じ値を持つEC2インスタンスへのアクションをすべて許可」が機能していることも確認しておきます。
まずは自身のTeamタグと同じ値を持つTeamAInstanceを終了させてみます。

これは問題なく成功しました。
では次に自身のTeamタグと異なる値を持つTeamBInstanceを終了させてみます。

こちらは終了させようとすると失敗し、想定通りの挙動となっていることがわかりました。
さいごに
リソースを指定して実行できないアクションがリクエストされた場合、このポリシーは許可されません。
冒頭の「結論」に記載した上記の一文、許可されていないのは確かなのですがこの場合
-
Condition.StringEqualsがFalseを返すのか - そのリクエスト自体が無効と判断されるのか
についての記載をドキュメントから見つけ出すことができませんでした。
すっきりしませんが見つけることができたら追記しようと思います。
Discussion