同名のIAMユーザーを再作成した場合はスイッチロール先IAMロールの信頼ポリシー更新が必要

IAM ユーザーを削除した後に同名の IAM ユーザーを作成した場合は、スイッチロール先の IAM ロールの信頼ポリシーにおいて IAM ユーザー名が合致している場合でもスイッチロールができなくなります。信頼ポリシーを更新することでスイッチロールが再度できるようになるため、その方法を確認しました。
2022.06.20

IAM ユーザープリンシパルに関するユーザーガイドで次の記載を見つけ、気になったので試してみました。例えば、Jump アカウント環境において同名の IAM ユーザーを再作成した場合は、スイッチロール先の AWS アカウントにおいて IAM ロールの更新作業を行わなければスイッチロールができません。

ロールの信頼ポリシーの Principal 要素に、特定の IAM ユーザーを指し示す ARN が含まれている場合、その ARN をポリシーに保存するときに、IAM がユーザーの一意のプリンシパル ID に変換されます。これにより、ユーザーを削除して再作成することにより、誰かがそのユーザーの特権をエスカレートするリスクを緩和できます。通常、この ID はコンソールには表示されません。これは、信頼ポリシーが表示されるときに、ユーザーの ARN への逆変換が行われるためです。ただし、ユーザーを削除すると、関係が壊れます。ユーザーを再作成しても、ポリシーが適用されることはありません。これは、新しいユーザーには、信頼ポリシーに保存されている ID と一致しない新しいプリンシパル ID が付与されるためです。この場合、プリンシパル ID はコンソールに表示されます。これは、AWS が有効な ARN に ID をマッピングできなくなるためです。その結果、信頼ポリシーの Principal 要素で参照されているユーザーを削除して再作成する場合は、ロールを編集して、正しくなくなったプリンシパル ID を正しい ARN に置き換える必要があります。ポリシーを保存するときに、IAM が再び、ARN をユーザーの新しいプリンシパル ID に変換します。

引用元:AWS JSON ポリシーの要素: Principal - AWS Identity and Access Management


IAM ロールの信頼ポリシーの設定内容に変更はないはずなので、「ロールを編集」とはどのような操作になるのか確認しました。結論としては次の操作で、同名の IAM ユーザー再作成後のスイッチロールができるようになりました。

  • マネジメントコンソールの場合
    • IAM ロールの「信頼ポリシーを編集」の画面を開き、内容を変更せずに「ポリシーを更新」を行う
  • AWS CLI の場合


試してみた

Jump アカウント環境を想定して次の構成で試してみました。

次のリソースを作成しています。

  • Jump アカウント : 111122223333
    • IAM ユーザー名 : test-user
    • 許可ポリシー : AWS 管理ポリシーAdministratorAccess
  • スイッチロール先アカウント : 444455556666
    • IAM ロール名 : test-readonly-role
    • 許可ポリシー : AWS 管理ポリシーReadOnlyAccess
    • 信頼ポリシー : 下記参照

IAM ロールtest-readonly-roleの信頼ポリシー

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::111122223333:user/test-user"
            },
            "Action": "sts:AssumeRole",
            "Condition": {}
        }
    ]
}

Jump アカウントの IAM ユーザーtest-userからスイッチロール先アカウントにスイッチロールできることを確認します。

この状態で、Jump アカウントの IAM ユーザーtest-userを削除して、同じ名前の IAM ユーザーtest-userを再作成したところ、ユーザーガイドに記載の通りスイッチロールに失敗するようになりました。

削除前の IAM ユーザーと再作成後の IAM ユーザーを比較したところ、UserIdが異なっているためか、冒頭のユーザーガイドの記載の通り別のユーザーとして扱われるようです。

削除前の IAM ユーザー

$ aws iam get-user --user-name test-user
{
    "User": {
        "Path": "/",
        "UserName": "test-user",
        "UserId": "AIDA5VOZMRYTHQXIORSDF",
        "Arn": "arn:aws:iam::111122223333:user/test-user",
        "CreateDate": "2022-06-18T11:31:43+00:00",
        "PasswordLastUsed": "2022-06-18T11:34:09+00:00"
    }
}

再作成後の IAM ユーザー

$ aws iam get-user --user-name test-user
{
    "User": {
        "Path": "/",
        "UserName": "test-user",
        "UserId": "AIDA5VOZMRYTKTZMDNAKZ",
        "Arn": "arn:aws:iam::111122223333:user/test-user",
        "CreateDate": "2022-06-18T11:40:07+00:00",
        "PasswordLastUsed": "2022-06-18T11:41:00+00:00"
    }
}

再びスイッチロールをできるようにするために IAM ロールの更新を行います。


マネジメントコンソールで信頼ポリシーを更新

信頼ポリシーの内容に変更はないはずですが、試しに IAM ロールの「信頼ポリシーを編集」を開き、何も変更せずに「ポリシーを更新」してみました。

この操作でよかったようです。スイッチロールができるようになりました。


AWS CLI で信頼ポリシーを更新

IAM ユーザーtest-userを再作成してスイッチロールに失敗することを確認します。

AWS CLI で IAM ロールを確認したところ、マネジメントコンソールのとき同様にPrincipalを変更する必要はなさそうです。

$ aws iam get-role --role-name test-readonly-role
{
    "Role": {
        "Path": "/",
        "RoleName": "test-readonly-role",
        "RoleId": "AROAWLQZGIQF4KOVA2Z3D",
        "Arn": "arn:aws:iam::444455556666:role/test-readonly-role",
        "CreateDate": "2022-06-18T11:32:42+00:00",
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Principal": {
                        "AWS": "arn:aws:iam::111122223333:user/test-user"
                    },
                    "Action": "sts:AssumeRole",
                    "Condition": {}
                }
            ]
        },
        "Description": "",
        "MaxSessionDuration": 3600,
        "RoleLastUsed": {
            "LastUsedDate": "2022-06-18T14:00:53+00:00",
            "Region": "us-east-1"
        }
    }
}

信頼ポリシーの更新コマンドupdate-assume-role-policyで試してみます。

update-assume-role-policy — AWS CLI 1.25.11 Command Reference

update-assume-role-policyの引数には信頼ポリシードキュメントが必須なので、同じ設定内容のドキュメントを用意しました。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::111122223333:user/test-user"
            },
            "Action": "sts:AssumeRole",
            "Condition": {}
        }
    ]
}

信頼ポリシーを更新します。

$ aws iam update-assume-role-policy --role-name test-readonly-role --policy-document file://assume-role-policy.json

改めて IAM ロールを確認してみますが、出力結果に変わりはありません。

$ aws iam get-role --role-name test-readonly-role
{
    "Role": {
        "Path": "/",
        "RoleName": "test-readonly-role",
        "RoleId": "AROAWLQZGIQF4KOVA2Z3D",
        "Arn": "arn:aws:iam::444455556666:role/test-readonly-role",
        "CreateDate": "2022-06-18T11:32:42+00:00",
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Principal": {
                        "AWS": "arn:aws:iam::111122223333:user/test-user"
                    },
                    "Action": "sts:AssumeRole",
                    "Condition": {}
                }
            ]
        },
        "Description": "",
        "MaxSessionDuration": 3600,
        "RoleLastUsed": {
            "LastUsedDate": "2022-06-18T14:00:53+00:00",
            "Region": "us-east-1"
        }
    }
}

上記の作業でスイッチロールができるようになりました。

ユーザーガイド通り、異なるユーザーとして扱われて権限昇格対策となっています。

ロールの信頼ポリシーの Principal 要素に、特定の IAM ユーザーを指し示す ARN が含まれている場合、その ARN をポリシーに保存するときに、IAM がユーザーの一意のプリンシパル ID に変換されます。これにより、ユーザーを削除して再作成することにより、誰かがそのユーザーの特権をエスカレートするリスクを緩和できます。通常、この ID はコンソールには表示されません。これは、信頼ポリシーが表示されるときに、ユーザーの ARN への逆変換が行われるためです。

引用元:AWS JSON ポリシーの要素: Principal - AWS Identity and Access Management

IAM ユーザーの再作成をしたときのスイッチロール先の IAM ロールの更新作業として何をする必要があるか確認できました。もしかしたらもっとよい方法があるかもしれません。


さいごに

IAM ユーザーのPrincipalに関するユーザーガイドを読んでいて気になった、同名の IAM ユーザーを再作成した場合において、スイッチロール先の IAM ロールで更新作業が必要な仕様を試してみました。あまりない状況かもしれませんが、Jump アカウントを運用している際には知っておきたい内容だと思いました。

なお、信頼ポリシーのPrincipalにおいて、IAM ユーザーとしてUserIdを指定する方法もあります。この場合は、IAM ユーザー再作成時に信頼ポリシーの内容を変更する必要がありますが、現在の設定内容が削除前と再作成後のどちらを示しているのか判別しやすいというメリットがあります。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "AIDA5VOZMRYTLPEXAMPLE"
            },
            "Action": "sts:AssumeRole",
            "Condition": {}
        }
    ]
}


参考資料

AWS JSON ポリシーの要素: Principal - AWS Identity and Access Management

Modifying a role (AWS CLI) - AWS Identity and Access Management