Jump アカウント構成において IAM ユーザーのタグを利用した ABAC により EC2 インスタンスの起動・停止許可を与える

2024.02.26

Jump アカウント環境において、IAM ユーザーのタグ情報を利用してスイッチロールできる IAM ロールを制限する構成を試してみました。

イメージ図は下記となります。IAM ユーザーのタグと IAM ロールのタグが一致する場合にスイッチロールできるように ABAC で制御します。今回の構成では、スイッチロール先の IAM ロールにおいて、さらに EC2 インスタンスに同じタグが付与されている場合に操作できるようにしてみました。後述する構築例ではタグとして Project 名を付与する想定で試しています。

なお、下図のように IAM ユーザーのタグは利用せずに、スイッチロール先アカウントだけで ABAC により EC2 の操作を制限する構成もあります。この構成のメリットとしては、IAM ユーザーを必ずしも一つの属性に紐づける必要がないことです(青色タグのロールにも橙色のタグのロールにもスイッチロールできます)。

後者の構成は下記ブログで試しています。本ブログでは前者の構成を試します。

IAM ユーザーのタグを条件にスイッチロール先で EC2 を操作

Jump アカウントの設定、スイッチロール先アカウントの設定の順番で記載します。

設定を検討するに当たり、次の AWS チュートリアルのページを参考になりました。

IAM チュートリアル: タグに基づいて AWS リソースにアクセスするためのアクセス許可を定義する - AWS Identity and Access Management


Jump アカウントの設定

次の設定で IAM ユーザーを作成します。ブログ冒頭の図でいうと青色のタグがProject : AAAとなります。

項目
IAM ユーザー名 test-user
タグ (Key : Value) Project : AAA

設定後の画面です。ARN の情報はスイッチロール先の IAM ロールで信頼ポリシーで利用します。

作成した IAM ユーザーもしくは IAM ユーザーが所属するグループに次のポリシーをアタッチします。Conditon 部分が ABAC の条件になっており、IAM ユーザーとスイッチロール先 IAM ロールの両方のProjectタグの値が一致する場合にスイッチロールできます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "iam:ResourceTag/Project": "${aws:PrincipalTag/Project}"
                }
            }
        }
    ]
}

今回は ABAC の動作確認がメインなので割愛しますが、MFA の設定許可やパスワードの変更許可もアタッチすることが多いです。


スイッチロール先アカウントの設定

下表の設定で 2 つの IAM ロールを作成します。アタッチするカスタマー管理ポリシーは同じポリシーを利用しています。ブログ冒頭の図でいうと青色のタグがProject : AAA、橙色のタグがProject : BBBになります。

項目 IAM ロール 1 の値 IAM ロール 2 の値
IAM ロール名 project-aaa-role project-bbb-role
許可 - カスタマー管理ポリシー project-abac-policy project-abac-policy
信頼ポリシー 下記参照 下記参照
タグ (Key : Value) Project : AAA Project : BBB


カスタマー管理ポリシーは次の通りです。

project-abac-policy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstances"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:StartInstances",
                "ec2:StopInstances",
                "ec2:RebootInstances"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "ec2:ResourceTag/Project": "${aws:PrincipalTag/Project}"
                }
            }
        }
    ]
}

信頼ポリシーは次の通りです。Principal には Jump アカウントのアカウント ID を指定します。

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


操作対象となる EC2 インスタンスは次の設定で作成します。

項目 EC2 インスタンス 1 の値 EC2 インスタンス 2 の値
EC2 インスタンス名 project-aaa-instance project-bbb-instance
タグ (Key : Value) Project : AAA Project : BBB

動作確認

Jump アカウントで作成した IAM ユーザーでマネジメントコンソールにサインインした状態で、同じ値の Project タグを持つ IAM ロールproject-aaa-roleと異なる値の Project タグを持つproject-bbb-roleにそれぞれスイッチロールを試してみます。

始めに、IAM ユーザーと同じ値を持つ Project タグを付与した IAM ロールproject-aaa-roleへスイッチロールしてみます。

意図した通り、スイッチロール先アカウントのマネジメントコンソールに遷移でき、同じ値の Project タグを持つ EC2 インスタンスの停止ができました。

一方で、スイッチロールはできても、異なる値の Project タグを持つ EC2 インスタンスの停止には失敗することを確認できました。こちらも想定通りです。

次に、IAM ユーザーとは異なる値を持つ Project タグを付与した IAM ロールproject-bbb-roleへスイッチロールしてみたところ、スイッチロールに失敗しました。IAM ユーザーと IAM ロールのタグによる制御ができています。

以上で、動作確認は終わりです。

さいごに

Jump アカウント環境において、IAM ユーザーのタグ情報を利用してスイッチロールする IAM ロールを許可する構成を試してみました。例えば、IAM ユーザーにチーム名を示すタグを付け、チーム毎に利用するロールを分ける場合などに利用できると思いました。一方で、今回のブログのようにプロジェクトに関連付けたタグで制御しようとすると、IAM ユーザーが複数のプロジェクトのリソースを操作したい場合に、値を複数持てないことから設計が複雑化する場合もあると思いました。その場合は下図のように IAM ユーザーのタグ情報を利用しない方法も候補になるため、使い所の見極めが必要となりそうです。

[参考] Jump アカウント構成で ABAC を使って EC2 インスタンスの起動・停止許可を与える

以上、このブログがどなたかのご参考になれば幸いです。