Jumpアカウント環境においてPermissions boundaryを用いてユーザーの作成するIAMロールの権限を制限する方法

2022.08.22

Jump アカウント管理者が利用者の作成する IAM ロールの権限を制限する方法を紹介します。

利用者に対して IAM ユーザーの作成を禁止する次のシナリオを想定し、Permissions boundary を用いて IAM ロール作成時に付与できる権限を制限する方法を試してみます。

  • Jump アカウント管理者が IAM ユーザーを一元的に管理する
  • Jump アカウント管理者は利用者に IAM ユーザーを払い出し、IAM ユーザーの作成権限は与えない
  • Jump アカウント管理者は利用者に対して IAM ロールの作成を許可するが、IAM ユーザーを作成する権限の付与は許可しない


以前に、AWS IAM Identity Center (旧 AWS Single Sign-on) において、Permissions boundary を用いて IAM ロールの権限を制限する方法を書きましたが、今回はその Jump アカウント環境版です。

実現イメージ

実現イメージ図を示します。

Jump アカウント管理者はスイッチロール先の AWS アカウントに利用者に対して、禁止させたいアクションの拒否ポリシーを含む Permissions boundary 用 IAM ポリシーを作成しておき、利用者が Permissions boundary 用 IAM ポリシーをアタッチしていない IAM ロールの作成を禁止することで実現します。

Permissions boundary を用いる場合の権限は次の図の通りとなり、Permissions boundary と Identity-based policy の両方で許可されているアクションの権限が与えられます。

引用元:Permissions boundaries for IAM entities - AWS Identity and Access Management

例えば、AWS アカウント利用者が Identity-based policy として AWS 管理ポリシーAdministratorAccessをアタッチした IAM ロールを作成した場合でも、Permissions boundary で IAM ユーザー作成が禁止されていれば、作成された IAM ロールの権限では IAM ユーザーは作成できません。


設定するポリシー

スイッチロール先アカウントで作成する Permissions boundary 用 IAM ポリシーと Jump アカウントの IAM グループにアタッチする IAM ポリシーについて説明します。

なお、今回設定するポリシーは動作テスト用に作成していますので、本番環境では適切な設定をご検討ください。

Permissions boundary 用 IAM ポリシー

設定しているポリシーの概要は次の通りです。

  • 全てのアクションを許可
  • IAM ユーザーと IAM グループの作成、更新、削除を禁止
  • 指定した Permissions boundary を設定していない IAM ロールの作成禁止
  • 指定した Permissions boundary を IAM ロールから削除することを禁止
  • 指定した Permissions boundary のポリシーの更新、削除を禁止

test-pb-policy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "*",
            "Resource": "*"
        },
        {
            "Effect": "Deny",
            "Action": [
                "iam:CreateUser",
                "iam:CreateLoginProfile",
                "iam:CreateAccessKey",
                "iam:UpdateUser",
                "iam:DeleteUser",
                "iam:CreateGroup",
                "iam:UpdateGroup",
                "iam:DeleteGroup",
                "iam:AddUserToGroup",
                "iam:RemoveUserFromGroup",
                "iam:AttachUserPolicy",
                "iam:DetachUserPolicy",
                "iam:PutUserPolicy",
                "iam:DeleteUserPolicy",
                "iam:AttachGroupPolicy",
                "iam:DetachGroupPolicy",
                "iam:PutGroupPolicy",
                "iam:DeleteGroupPolicy"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Deny",
            "Action": [
                "iam:CreateRole",
                "iam:AttachRolePolicy",
                "iam:DetachRolePolicy",
                "iam:PutRolePolicy",
                "iam:DeleteRolePolicy",
                "iam:PutRolePermissionsBoundary"
            ],
            "Resource": "*",
            "Condition": {
                "StringNotEquals": {
                    "iam:PermissionsBoundary": "arn:aws:iam::444455556666:policy/test-pb-policy"
                }
            }
        },
        {
            "Effect": "Deny",
            "Action": [
                "iam:DeleteRolePermissionsBoundary"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "iam:PermissionsBoundary": "arn:aws:iam::444455556666:policy/test-pb-policy"
                }
            }
        },
        {
            "Effect": "Deny",
            "Action": [
                "iam:CreatePolicyVersion",
                "iam:DeletePolicy",
                "iam:DeletePolicyVersion",
                "iam:SetDefaultPolicyVersion"
            ],
            "Resource": [
                "arn:aws:iam::444455556666:policy/test-pb-policy"
            ]
        }
    ]
}

スイッチロール先アカウントでは上記の IAM ポリシーを許可の境界(Permissions boundary)としてアタッチした IAM ロールを作成します。作成する IAM ロールの信頼ポリシーの例を示します。

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

参考情報ですが、信頼ポリシーで複数の IAM ユーザーを指定したい場合は次のブログが参考になります。

Jump アカウントの IAM グループ用 IAM ポリシー

次に、Jump アカウントの IAM グループにアタッチする2つの IAM ポリシーを紹介します。

1つ目は、スイッチロール先のAWSアカウントにスイッチロールするための権限です。

test-jump-policy

{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Action": "sts:AssumeRole",
        "Resource": "arn:aws:iam::444455556666:role/test-restricted-admin-role"
    }
}

2つ目は、IAM ユーザーが自身のパスワード変更と MFA 認証設定を行うことができる権限です。IAM ユーザーでサインイン後にユーザー自身で MFA 認証の設定を行い、その後にスイッチロールする流れを想定しています。

test-self-control-policy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowListActions",
            "Effect": "Allow",
            "Action": [
                "iam:ListUsers",
                "iam:ListVirtualMFADevices"
            ],
            "Resource": "*"
        },
        {
            "Sid": "AllowIndividualUserToListOnlyTheirOwnMFA",
            "Effect": "Allow",
            "Action": [
                "iam:ListMFADevices"
            ],
            "Resource": [
                "arn:aws:iam::*:mfa/*",
                "arn:aws:iam::*:user/${aws:username}"
            ]
        },
        {
            "Sid": "AllowIndividualUserToManageTheirOwnMFA",
            "Effect": "Allow",
            "Action": [
                "iam:CreateVirtualMFADevice",
                "iam:DeleteVirtualMFADevice",
                "iam:EnableMFADevice",
                "iam:ResyncMFADevice"
            ],
            "Resource": [
                "arn:aws:iam::*:mfa/${aws:username}",
                "arn:aws:iam::*:user/${aws:username}"
            ]
        },
        {
            "Sid": "AllowIndividualUserToDeactivateOnlyTheirOwnMFAOnlyWhenUsingMFA",
            "Effect": "Allow",
            "Action": [
                "iam:DeactivateMFADevice"
            ],
            "Resource": [
                "arn:aws:iam::*:mfa/${aws:username}",
                "arn:aws:iam::*:user/${aws:username}"
            ],
            "Condition": {
                "Bool": {
                    "aws:MultiFactorAuthPresent": "true"
                }
            }
        },
        {
            "Sid": "AllowGetAccountPasswordPolicy",
            "Effect": "Allow",
            "Action": "iam:GetAccountPasswordPolicy",
            "Resource": "*"
        },
        {
            "Sid": "AllowChangePassword",
            "Effect": "Allow",
            "Action": "iam:ChangePassword",
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        },
        {
            "Sid": "BlockMostAccessUnlessSignedInWithMFA",
            "Effect": "Deny",
            "NotAction": [
                "iam:CreateVirtualMFADevice",
                "iam:EnableMFADevice",
                "iam:ListMFADevices",
                "iam:ListUsers",
                "iam:ListVirtualMFADevices",
                "iam:ResyncMFADevice",
                "iam:GetAccountPasswordPolicy",
                "iam:ChangePassword"
            ],
            "Resource": [
                "arn:aws:iam::*:mfa/${aws:username}",
                "arn:aws:iam::*:user/${aws:username}"
            ],
            "Condition": {
                "BoolIfExists": {
                    "aws:MultiFactorAuthPresent": "false"
                }
            }
        }
    ]
}

2つ目のポリシーは次のドキュメントを参考としました。

IAM: IAM ユーザーに MFA デバイスの自己管理を許可する

IAM ユーザーに自分のパスワードを変更する権限を付与する


設定方法

Permissions boundaryの設定を行い、動作を確認してみます。

以降では、AWS アカウント ID は次の値に置き換えています。

  • Jump アカウント 111122223333
  • スイッチロール先アカウント 444455556666

Jump アカウントの設定

IAM グループと IAM ユーザーを作成します。

  • IAM グループ test-pb-group
    • 所属する IAM ユーザー test-pb-user

スイッチロール先アカウントにおいて IAM ロールの信頼ポリシーを設定する際に、指定した IAM ユーザーが Jump アカウント側に存在しない場合はエラーとなります。そのため、事前に IAM ユーザーを作成しておきます。

IAM グループ test-pb-groupには、前章で記載した次の2つの IAM ポリシーをアタッチします。

  • IAMポリシー test-jump-policy
  • IAMポリシー test-self-control-policy

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

Permissions boundary 用 IAM ポリシーを作成します。

  • IAM ポリシー test-pb-policy

次に、作成した IAM ポリシーtest-pb-policyをアタッチする IAM ロールを作成します。信頼されたエンティティタイプとして「AWS アカウント」を選択して、アカウント ID には Jump アカウントの ID を入力します。また、MFA 認証が必要な設定としています。

IAM ロールの権限はAdministratorAccessとし、許可の境界(Permissions boundary)として上記で作成した IAM ポリシーtest-pb-policyをアタッチします。

名前はtest-restricted-admin-roleとしています。

作成後に、信頼ポリシーを編集します。

設定する信頼ポリシーは前章で紹介した次のポリシーです。

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

以上で設定完了です。ここからは動作確認をしてみます。

はじめに、Jump アカウントで作成した IAM ユーザーでマネジメントコンソールにサインインし、MFA 認証を設定します。

その後、MFA 認証を用いて再度サインインしたあとにスイッチロールを行います。

スイッチロール後の権限を確認していきます。

IAM ユーザーの作成は、AdministratorAccess 権限がアタッチされているにも関わらず、Permissions boundary にて拒否されるメッセージが表示されます。

同様に、IAM グループの作成も Permissions boundary にて拒否されるメッセージが表示されます。

Permissions boundary をアタッチせずに IAM ロールの作成を試してみます。

想定通り、IAM ロールの作成に失敗します。

Permissions boundary としてtest-pb-policyをアタッチした IAM ロールの作成を試してみます。

IAM ロールを作成でき、test-pb-policyが許可の境界としてアタッチされていることを確認できます。

以上で動作確認は終了です。


さいごに

Jump アカウント管理者がユーザーが作成する IAM ロールの権限を制限する方法を紹介しました。基本的な考え方は AWS IAM Identity Center(旧 AWS SSO)で実現する場合と変わらないので、以前と同じような内容のブログとなりました。

実際に活用するときは、事前にスイッチロール先アカウントで Permissions boundary 用の IAM ポリシーを作成しておく必要があるため、CloudFormation 等を利用して作成を自動化することも検討事項になります。

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


参考資料

Permissions boundaries for IAM entities - AWS Identity and Access Management

権限の昇格を防ぎ、アクセス許可の境界で IAM ユーザー範囲を限定する