AWS IAM ForAllValuesとForAnyValueの違い
回答
ForAllValues
とForAnyValue
集合演算子は、いずれも複数値のコンテキストキー(multivalued context key)に対して使用します。
ForAllValues
は、リクエストに含まれる指定のコンテキストキーの値(複数値)のすべての値が条件を満たす場合にtrueを返します。
ForAnyValue
は、リクエストに含まれる指定のコンテキストキーの値(複数値)の少なくとも1つの値が条件を満たす場合にtrueを返します。
複数値のコンテキストキーとは
複数値のコンテキストキーとは、リクエストコンテキストにおいて複数の値を取りうる(リスト・配列型である)コンテキストキーを指します。例えば、aws:TagKeys
やaws:PrincipalOrgPaths
がそれに当たります。複数値のコンテキストキーは、AWS グローバル条件コンテキストキーでは「値タイプ」が「複数値」となっており、サービス認証リファレンスでは「タイプ」がArrayOf...
となっています。
逆に、単一の値しか持たないコンテキストキーは単一値のコンテキストキー(single-valued context key)と呼ばれます。
複数値のコンテキストキーかどうかは、リクエストコンテキストの値の数によって決まるのであって、ポリシー条件の値の数には関係ないことに注意が必要です。つまり、以下のようなポリシー条件を書いたとしても、aws:ResourceTag/tag-key
は単一値のコンテキストキーです(よって、このコンテキストキーにForAllValues
やForAnyValue
を使用する必要はありません)。
"Condition": {
"StringEquals": {
"aws:RequestTag/tag-key": [
"value-1",
"value-2"
]
}
}
ForAllValuesの解説
ForAllValues
は、リクエストに含まれる指定のコンテキストキーの値(複数値)のすべての値が条件を満たす場合にtrueを返します。
例として、以下のリクエストコンテキストを以下のポリシー条件で評価する場合を考えます。
-
リクエストコンテキスト:タグキーが
["CreatedBy", "CreatedAt"]
-
ポリシー条件:
"Condition": { "ForAllValues:StringLike": { "aws:TagKeys": "Created*" } }
この場合、["CreatedBy", "CreatedAt"]
のすべての値が「Created*
に一致する」という条件を満たすので、結果はtrueになります。
ポリシー条件に複数値を指定した場合
ポリシー条件の基本的な評価論理として、ひとつのコンテキストキーに対して複数の値を指定した場合、それらの値はOR
で評価されます[1]。これはForAllValues
を使用した場合でも同様です。すなわち、リクエストコンテキストのすべての値がポリシー条件の少なくとも1つの値に一致するとき、trueと評価されます。言い換えれば、リクエスト側集合がポリシー条件側集合の部分集合であるときtrueになります。
以下のリクエストコンテキストを、以下のポリシー条件で評価する例を考えます。
-
リクエストコンテキスト:タグキーが
["Department", "Role"]
-
ポリシー条件:
"Condition": { "ForAllValues:StringEquals": { "aws:TagKeys": [ "Department", "Role", "Environment" ] } }
この場合、["Department", "Role"]
のすべての値が「["Department", "Role", "Environment"]
の少なくとも1つと等しい」という条件を満たすので、結果はtrueになります。あるいは、["Department", "Role"]
は["Department", "Role", "Environment"]
の部分集合であるためtrueになると説明することもできます。
指定のコンテキストキーがリクエストに存在しない場合
指定のコンテキストキーがリクエストに存在しない場合やその値がない場合、結果はtrueになります。
以下のリクエストコンテキストを、以下のポリシー条件で評価する例を考えます。
-
リクエストコンテキスト:タグなし
-
ポリシー条件:
"Condition": { "ForAllValues:StringEquals": { "aws:TagKeys": [ "Department", "Role", "Environment" ] } }
結果はtrueになります。
ForAnyValueの解説
ForAnyValue
は、リクエストに含まれる指定のコンテキストキーの値(複数値)の少なくとも1つの値が条件を満たす場合にtrueを返します。
ポリシー条件においてひとつのコンテキストキーに対して複数の値を指定した場合、リクエストコンテキストの少なくとも1つの値がポリシー条件の少なくとも1つの値に一致するとき、trueと評価されます。言い換えれば、リクエスト側集合とポリシー条件側集合に共通部分があればtrueになります。
指定のコンテキストキーがリクエストに存在しない場合やその値がない場合、結果はfalseになります。
あとがき
-
ForAllValues
で力尽きてForAnyValue
の説明が短くなってしまいましたが、ForAllValues
の方がよっぽど罠が多いため、これで良いかなと思っています - 符号反転(
Not
)系演算子を考えるとさらに複雑になりそうだったため、説明に含めていません(そもそもしんどくて考えていません)
参考
Discussion