AWS IAM でアクション行にない条件キーは使えるのか?ssm:PutParameter と aws:ResourceTag で検証してみた
はじめに
クラウド事業本部コンサルティング部の山﨑です。
AWS の IAM ポリシーを書くとき、サービス認可リファレンスのアクションテーブルを確認することがあると思います。
サービス認可リファレンスでは、各アクションで利用できるリソースタイプや条件キーが確認できます。
条件キーはアクション行の条件キー列に表示されるものだけでなく、アクションに紐づくリソースタイプ側に定義されている場合もあります。
今回気になったのは、以下の点です。
アクション行の条件キーに
aws:ResourceTag/${TagKey}が直接記載されていなくても、アクションに紐づくリソースタイプ側にaws:ResourceTag/${TagKey}が定義されていれば、IAM ポリシーの条件キーとして利用できるのか?
AWS Systems Manager のサービス認可リファレンスを見ると、ssm:PutParameter のアクション行には aws:ResourceTag/${TagKey} が直接表示されていません。
一方で、ssm:PutParameter に紐づく parameter リソースタイプ側には aws:ResourceTag/${TagKey} が定義されています。
今回は、この読み方が実際の IAM ポリシー評価でも期待どおりに機能するのか、AWS Systems Manager Parameter Store の ssm:PutParameter を使って検証しました。
結論
ssm:PutParameter のアクション行に aws:ResourceTag/${TagKey} が直接記載されていなくても、アクションに紐づくリソースタイプ parameter 側の条件キーとして定義されていれば、対象パラメータのリソースタグを条件に評価されました。
具体的には、既存の SSM パラメータに付与された Env=Test タグを条件に、AWS CLI の aws ssm put-parameter --overwrite による更新を明示的に拒否できました。
公式ドキュメントの確認
まず、AWS Systems Manager のサービス認可リファレンスを確認します。
サービス認可リファレンスでは、アクションテーブルの条件キー列だけでなく、アクションに紐づくリソースタイプ側の条件キーも確認する必要があります。
今回確認したいのは、アクション行の条件キー列には表示されていないものの、リソースタイプ側に定義されている条件キーが、実際に IAM ポリシーで評価されるのかという点です。

ssm:PutParameter のアクション行を見ると、リソースタイプには parameter* が記載されています。
一方で、ssm:PutParameter アクション行の条件キーには以下が記載されています。
aws:RequestTag/${TagKey}aws:TagKeysssm:Overwritessm:Policies
ここには、aws:ResourceTag/${TagKey} は直接記載されていません。

しかし、同じサービス認可リファレンスのリソースタイプテーブルを見ると、parameter リソースタイプには条件キーとして以下が記載されています。
aws:ResourceTag/${TagKey}ssm:resourceTag/tag-key
図にすると、以下のような関係です。
parameter* の * は、そのアクションで必須のリソースタイプであることを表しています。
つまり、ssm:PutParameter のアクション行だけを見ると aws:ResourceTag/${TagKey} は見つかりませんが、アクションに紐づく parameter リソースタイプ側には aws:ResourceTag/${TagKey} が定義されています。
今回の検証では、この parameter リソースタイプ側の条件キーを使って、既存の SSM パラメータに付与された Env=Test タグを条件に ssm:PutParameter を制御できるのか確認します。
検証構成
今回の検証では、以下の 2 つの SSM パラメータを用意しました。
| パラメータ名 | タグ |
|---|---|
/abac-test/blocked |
Env=Test |
/abac-test/allowed |
なし |
検証用 IAM ロールを作成し、そのロールを AssumeRole した状態で aws ssm put-parameter --overwrite を実行し、IAM アクション ssm:PutParameter の評価結果を確認します。
今回の検証では、同じ IAM ロールに対して以下の 2 段階でポリシーを設定しました。
| 段階 | IAM ポリシー | 確認内容 |
|---|---|---|
| 1 | ssm:PutParameter を許可 |
Deny 条件を追加する前に、両方のパラメータを更新できることを確認 |
| 2 | aws:ResourceTag/Env が Test の場合に Deny |
Env=Test タグ付きパラメータだけ更新に失敗することを確認 |
今回の検証で登場する主な要素は以下です。
| 種類 | 今回使うもの | 用途 |
|---|---|---|
| IAM アクション | ssm:PutParameter |
SSM パラメータの作成・更新を許可または拒否する |
| AWS CLI コマンド | aws ssm put-parameter |
SSM パラメータを作成・更新する |
| CLI オプション | --overwrite |
既存パラメータを更新する |
| 条件キー | aws:ResourceTag/Env |
対象パラメータに付与済みの Env タグを評価する |
| 条件値 | Test |
Env=Test の場合に Deny する |
検証対象の SSM パラメータを作成
まず、検証対象となる SSM パラメータを事前に作成しました。
以降の検証では、これらの既存パラメータに対して、検証用 IAM ロールを AssumeRole した状態で aws ssm put-parameter --overwrite を実行します。
Env=Test タグ付きパラメータ
Env=Test タグ付きの検証用パラメータを作成します。
aws ssm put-parameter \
--region ap-northeast-1 \
--name /abac-test/blocked \
--type String \
--value "v1" \
--tags Key=Env,Value=Test
実行結果です。
{
"Version": 1,
"Tier": "Standard"
}
タグなしパラメータ
aws ssm put-parameter \
--region ap-northeast-1 \
--name /abac-test/allowed \
--type String \
--value "v1"
実行結果です。
{
"Version": 1,
"Tier": "Standard"
}
作成後の状態は以下です。
| パラメータ名 | タグ |
|---|---|
/abac-test/blocked |
Env=Test |
/abac-test/allowed |
なし |
検証1: Deny 条件なしで両方のパラメータを更新できることを確認
まず、aws:ResourceTag/Env が Test の場合の Deny 条件を追加する前に、両方のパラメータを更新できることを確認します。
期待結果は以下です。
| 対象パラメータ | タグ | 操作 | 期待結果 |
|---|---|---|---|
/abac-test/blocked |
Env=Test |
aws ssm put-parameter --overwrite |
成功 |
/abac-test/allowed |
なし | aws ssm put-parameter --overwrite |
成功 |
IAM ポリシー
この時点では、検証用 IAM ロールに以下の IAM ポリシーを付与しています。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowPutParameterForAbacTest",
"Effect": "Allow",
"Action": "ssm:PutParameter",
"Resource": "arn:aws:ssm:ap-northeast-1:123456789012:parameter/abac-test/*"
},
{
"Sid": "AllowReadForVerification",
"Effect": "Allow",
"Action": [
"ssm:GetParameter",
"ssm:DescribeParameters",
"ssm:ListTagsForResource"
],
"Resource": "*"
}
]
}
このポリシーでは、/abac-test/* 配下の SSM パラメータに対する ssm:PutParameter を許可しています。
まだ aws:ResourceTag/Env が Test の場合の Deny 条件は追加していません。
実行
この時点では Deny 条件を追加していないため、 Env=Test タグ付きの /abac-test/blocked も更新できる想定です。
aws ssm put-parameter \
--region ap-northeast-1 \
--name /abac-test/blocked \
--type String \
--value "baseline-blocked-v2" \
--overwrite
実行結果です。
{
"Version": 2,
"Tier": "Standard"
}
続いて、タグなしの /abac-test/allowed を更新します。
こちらも Deny 条件を追加していないため、更新できる想定です。
aws ssm put-parameter \
--region ap-northeast-1 \
--name /abac-test/allowed \
--type String \
--value "baseline-allowed-v2" \
--overwrite
実行結果です。
{
"Version": 2,
"Tier": "Standard"
}
Deny 条件を追加する前の結果は以下です。
| 対象パラメータ | タグ | 操作 | 結果 |
|---|---|---|---|
/abac-test/blocked |
Env=Test |
aws ssm put-parameter --overwrite |
成功 |
/abac-test/allowed |
なし | aws ssm put-parameter --overwrite |
成功 |
この時点で、検証用ロールには対象パラメータに対する ssm:PutParameter 権限があることを確認できました。
検証2: Env=Test タグ付きパラメータだけ Deny されることを確認
次に、同じ IAM ロールのポリシーに、aws:ResourceTag/Env が Test に一致する場合の明示的な Deny を追加します。
期待結果は以下です。
| 対象パラメータ | タグ | 操作 | 期待結果 |
|---|---|---|---|
/abac-test/blocked |
Env=Test |
aws ssm put-parameter --overwrite |
失敗 |
/abac-test/allowed |
なし | aws ssm put-parameter --overwrite |
成功 |
IAM ポリシー
ポリシーは以下です。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowPutParameterForAbacTest",
"Effect": "Allow",
"Action": "ssm:PutParameter",
"Resource": "arn:aws:ssm:ap-northeast-1:123456789012:parameter/abac-test/*"
},
{
"Sid": "AllowReadForVerification",
"Effect": "Allow",
"Action": [
"ssm:GetParameter",
"ssm:DescribeParameters",
"ssm:ListTagsForResource"
],
"Resource": "*"
},
{
"Sid": "DenyPutParameterIfEnvTest",
"Effect": "Deny",
"Action": "ssm:PutParameter",
"Resource": "arn:aws:ssm:ap-northeast-1:123456789012:parameter/abac-test/*",
"Condition": {
"StringEquals": {
"aws:ResourceTag/Env": "Test"
}
}
}
]
}
既存の SSM パラメータに Env=Test タグが付いている場合、そのパラメータに対する ssm:PutParameter を明示的に拒否します。
実行
ケース1: Env=Test タグ付きパラメータを更新
Env=Test タグが付いている /abac-test/blocked を更新します。
Deny 条件を追加した後は、 Env=Test タグ付きの /abac-test/blocked への aws ssm put-parameter --overwrite は失敗する想定です。
aws ssm put-parameter \
--region ap-northeast-1 \
--name /abac-test/blocked \
--type String \
--value "blocked-v3" \
--overwrite
結果は失敗しました。
An error occurred (AccessDeniedException) when calling the PutParameter operation:
User: arn:aws:sts::123456789012:assumed-role/ssm-putparameter-abac-test-role/ssm-putparameter-abac-test-session
is not authorized to perform: ssm:PutParameter
on resource: arn:aws:ssm:ap-northeast-1:123456789012:parameter/abac-test/blocked
with an explicit deny in an identity-based policy
explicit deny と表示されています。
/abac-test/blocked には Env=Test タグが付いているため、以下の Deny 条件に一致したと判断できます。
"aws:ResourceTag/Env": "Test"
更新後の値も確認しました。
{
"Parameter": {
"Name": "/abac-test/blocked",
"Type": "String",
"Value": "baseline-blocked-v2",
"Version": 2,
"ARN": "arn:aws:ssm:ap-northeast-1:123456789012:parameter/abac-test/blocked",
"DataType": "text"
}
}
blocked-v3 には更新されておらず、Deny 条件を追加する前に更新した baseline-blocked-v2 のままでした。
ケース2: タグなしパラメータを更新
次に、タグなしの /abac-test/allowed を更新します。
タグなしパラメータでは aws:ResourceTag/Env が Test に一致しないため、明示的な Deny の対象にならず、更新できる想定です。
aws ssm put-parameter \
--region ap-northeast-1 \
--name /abac-test/allowed \
--type String \
--value "allowed-v3" \
--overwrite
結果は成功しました。
{
"Version": 3,
"Tier": "Standard"
}
更新後の値も確認しました。
{
"Parameter": {
"Name": "/abac-test/allowed",
"Type": "String",
"Value": "allowed-v3",
"Version": 3,
"ARN": "arn:aws:ssm:ap-northeast-1:123456789012:parameter/abac-test/allowed",
"DataType": "text"
}
}
タグなしパラメータでは aws:ResourceTag/Env が Test に一致しないため、明示的な Deny の対象にならず、更新できました。
検証結果まとめ
結果を整理します。
| ケース | 対象パラメータ | タグ | 操作 | 結果 |
|---|---|---|---|---|
| Deny 条件追加前 | /abac-test/blocked |
Env=Test |
aws ssm put-parameter --overwrite |
成功 |
| Deny 条件追加前 | /abac-test/allowed |
なし | aws ssm put-parameter --overwrite |
成功 |
| Deny 条件追加後 | /abac-test/blocked |
Env=Test |
aws ssm put-parameter --overwrite |
失敗 |
| Deny 条件追加後 | /abac-test/allowed |
なし | aws ssm put-parameter --overwrite |
成功 |
同じ IAM ロールで同じ aws ssm put-parameter --overwrite を実行しても、対象の SSM パラメータに Env=Test タグが付いているかどうかで結果が変わりました。
まとめ
ssm:PutParameter に対して、aws:ResourceTag/Env が Test の場合に明示的な Deny が効くか検証しました。
結果は以下のとおりです。
- Deny 条件を追加する前は、
/abac-test/blockedと/abac-test/allowedの両方を更新できた aws:ResourceTag/EnvがTestの場合の Deny を追加すると、Env=Testタグ付きの/abac-test/blockedは更新に失敗した- タグなしの
/abac-test/allowedは更新に成功した ssm:PutParameterのアクション行の条件キー列にaws:ResourceTag/${TagKey}が直接表示されていなくても、アクションに紐づくリソースタイプparameter側に定義されているため、対象パラメータのリソースタグを条件に評価された
今回の検証から、サービス認可リファレンスを確認する際は、アクション行だけでなく、アクションに紐づくリソースタイプ側の条件キーも確認することが重要だと分かりました。
参考
- https://docs.aws.amazon.com/service-authorization/latest/reference/list_awssystemsmanager.html
- https://docs.aws.amazon.com/ja_jp/service-authorization/latest/reference/reference_policies_actions-resources-contextkeys.html
- https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_condition-keys.html







