【小ネタ】AWS CLIのAssumeRoleとマネジメントコンソール(マルチセッション無効)のスイッチロールでは使用される認証情報が異なる
はじめに
皆様こんにちは、あかいけです。
最近、多段スイッチロールをしていた際に、AWS CLIからはAssumeRoleできるのに、マネジメントコンソールのスイッチロールは失敗することがありました。
もちろん使っているロールは同じのため、同じ認証情報で操作しているはずなのに、なぜ結果が異なるのか最初は全くわかりませんでした…。
しかし調べてみると、AWS CLIとマネジメントコンソールでは使用される認証情報が異なることが原因でした。
今回はその違いについてまとめます。
なお本事象は マネジメントコンソールのマルチセッション無効 の場合に発生するため、マルチセッション有効の場合は発生しない事象しません。
マルチセッションを利用した多段スイッチロールについては、よろしければ以下をご参照ください。
何が起きたか
今回遭遇したのは、以下のようにIAMユーザーから多段でロールをスイッチする構成です。
この構成にてAWS CLIでは問題なくAssumeRoleできる一方、マネジメントコンソールのスイッチロールは失敗しました。
IAMユーザー / IAMロールの権限設定
今回のIAMユーザー / IAMロールの権限設定を整理します。
まず、IAMユーザーAには各ロールを引き受けるためのIAMポリシーを付与しています。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::<ACCOUNT-B-ID>:role/iam-role-b"
}
]
}
IAMロールBの信頼ポリシーは次のとおりです。
IAMユーザーAがIAMロールBを引き受けられるように設定しています。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<ACCOUNT-A-ID>:user/iam-user-a"
},
"Action": "sts:AssumeRole"
}
]
}
さらに、IAMロールBにはIAMロールCを引き受けるためのIAMポリシーを付与しています。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::<ACCOUNT-C-ID>:role/iam-role-c"
}
]
}
IAMロールCの信頼ポリシーは次のとおりです。
IAMロールBがIAMロールCを引き受けられるように設定しています。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<ACCOUNT-B-ID>:role/iam-role-b"
},
"Action": "sts:AssumeRole"
}
]
}
AWS CLIでの操作
AWS CLIでの操作では、まずアカウントAのマネジメントコンソールにIAMユーザーAでログインし、その後のコマンドはCloudShellで実行します。
まず、現在の認証情報がIAMユーザーAであることを確認します。
aws sts get-caller-identity
{
"UserId": "XXXXXXXXXXXXXXXXXXXXX",
"Account": "<ACCOUNT-A-ID>",
"Arn": "arn:aws:iam::<ACCOUNT-A-ID>:user/iam-user-a"
}
次に、IAMユーザーAの認証情報でIAMロールBの一時認証情報を取得します。
aws sts assume-role \
--role-arn arn:aws:iam::<ACCOUNT-B-ID>:role/iam-role-b \
--role-session-name iam-role-b-session
取得した一時認証情報を環境変数にセットし、認証情報がIAMロールBに切り替わったことを確認します。
export AWS_ACCESS_KEY_ID=<取得したAccessKeyId>
export AWS_SECRET_ACCESS_KEY=<取得したSecretAccessKey>
export AWS_SESSION_TOKEN=<取得したSessionToken>
aws sts get-caller-identity
{
"UserId": "XXXXXXXXXXXXXXXXXXXXX:iam-role-b-session",
"Account": "<ACCOUNT-B-ID>",
"Arn": "arn:aws:sts::<ACCOUNT-B-ID>:assumed-role/iam-role-b/iam-role-b-session"
}
続いて、IAMロールBの一時認証情報でIAMロールCの一時認証情報を取得します。
aws sts assume-role \
--role-arn arn:aws:iam::<ACCOUNT-C-ID>:role/iam-role-c \
--role-session-name iam-role-c-session
取得した一時認証情報を環境変数にセットした後、認証情報がIAMロールCに切り替わったことが確認できます。
export AWS_ACCESS_KEY_ID=<取得したAccessKeyId>
export AWS_SECRET_ACCESS_KEY=<取得したSecretAccessKey>
export AWS_SESSION_TOKEN=<取得したSessionToken>
aws sts get-caller-identity
{
"UserId": "XXXXXXXXXXXXXXXXXXXXX:iam-role-c-session",
"Account": "<ACCOUNT-C-ID>",
"Arn": "arn:aws:sts::<ACCOUNT-C-ID>:assumed-role/iam-role-c/iam-role-c-session"
}
マネジメントコンソールでの操作
マネジメントコンソールでの操作では、まずはアカウントAのIAMユーザーAでログインします。
次にIAMロールBにスイッチロールします。これは問題なく成功します。

その後IAMロールBからIAMロールCへのスイッチロールを試みると…

失敗してしまいます。
AWS CLIとマネジメントコンソールでのAssumeRoleの呼ばれ方の違い
両者の違いは、ひとことで言うとロールの連鎖をサポートしているかどうかにあります。
AWS CLIの場合
AWS CLIはロールの連鎖をサポートしています。
そのため引き受けているIAMロールBの一時認証情報を使って次のIAMロールCの AssumeRole を呼び出します。
そして、今回IAMロールCの信頼ポリシーで許可していたのはIAMロールBだったので、AWS CLIでは問題なく引き受けられたわけです。
マネジメントコンソールの場合
一方、マネジメントコンソールのスイッチロールはロールの連鎖をサポートしていません。
どのロールにスイッチしているかに関わらず、常に元の認証情報を使って AssumeRole を呼び出します。
つまり、コンソール上でIAMロールBにスイッチした状態でIAMロールCへのスイッチを試みても、実際にはIAMユーザーAの認証情報でIAMロールCの AssumeRole が呼ばれます。
そして今回の設定では、IAMロールCの信頼ポリシーにはIAMユーザーAが含まれていないため、スイッチロールに失敗していたのです。
なおこの仕様はAWSの公式ドキュメントにも明記されています。
AWS マネジメントコンソール でロールを切り替えると、コンソールは常に元の認可情報を使用して切り替えを認可します。これは、IAM ユーザー、SAML フェデレーションロール、またはウェブ ID フェデレーションロールとしてサインインする際に適用されます。
解決方法
マネジメントコンソールからIAMロールCへスイッチするには、IAMユーザーAの認証情報で直接IAMロールCを引き受けられるようにする必要があります。
これはアカウントをまたぐ AssumeRole なので、次の2つを両方設定する必要があります。
- IAMユーザーA側のIAMポリシー: IAMロールCを引き受ける許可を追加する
- IAMロールC側の信頼ポリシー: IAMユーザーAからの引き受けを許可する
まず、IAMユーザーAのIAMポリシーにIAMロールCを引き受ける許可を追加します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": [
"arn:aws:iam::<ACCOUNT-B-ID>:role/iam-role-b",
"arn:aws:iam::<ACCOUNT-C-ID>:role/iam-role-c"
]
}
]
}
そのうえで、IAMロールCの信頼ポリシーにIAMユーザーAを追加します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::<ACCOUNT-B-ID>:role/iam-role-b",
"arn:aws:iam::<ACCOUNT-A-ID>:user/iam-user-a"
]
},
"Action": "sts:AssumeRole"
}
]
}
修正後にマネジメントコンソールからスイッチロールを試みると…
問題なくスイッチロールできるようになりました。

さいごに
以上、AWS CLIではスイッチロールできるのにマネジメントコンソールでは失敗する話でした。
同じロールを使っていても結果が変わるのは、ロールの連鎖をサポートしているかどうかの違いが原因でした。
- AWS CLIはロールの連鎖をサポートしている
- 引き受けているロールの一時認証情報で
sts:AssumeRoleを呼ぶ
- 引き受けているロールの一時認証情報で
- マネジメントコンソールはサポートしていない(マルチセッション無効の場合)
- 引き受けているロールに関係なく、常にスイッチロール元の認証情報で
sts:AssumeRoleを呼ぶ
- 引き受けているロールに関係なく、常にスイッチロール元の認証情報で
同じ事象で困っている方の助けになれば幸いです。







