Coping with the problem that IAM users with PowerUserAccess can switch to all IAM roles

With the emergence of AWS Organizations, multi-account operations using multiple AWS accounts are increasing in systems using AWS.

In multi-account operations, centralized user management using IAM roles is important.
In this article, I will introduce some important points to note when performing this centralized management.

#Multi-account best practices on AWS
Multiple patterns are possible when using AWS multi-account operations.

1. Create an IAM user for each account and log in individually.
1. Create a bastion account for IAM management, create an IAM role for each account, and use a switch role.
1. SSO login using AWS SSO.
1. Use a third-party authentication provider such as OneLogin.


1.In the method of using each account, when the member is changed, it is necessary to add and delete users in all AWS accounts, and the management cost increases as the number of target accounts increases.

3.Microsoft Active Directory is required to use AWS SSO.
There is no problem when a company uses it in-house, but it is difficult to apply when outsourcing such as a development company.

4.Use of a third-party provider requires a separate contract.

#Configuration in a practical environment
In AWS best practice, JUMP accounts have only IAM users and no other resources.

In an environment where accounts are unified and CloudTrail settings are performed in a batch like Organizations, it is possible to actually configure the JUMP account in this way, but overall management is particularly important. If you want to make one JUMP account of multiple accounts that have not been made, you may need an IAM user with some operational authority such as setting up CloudTrail and building a platform account in the JUMP server.

#IAM role in the target account
The account that is the target of the switch role does not require any complicated operations.
As with normal IAM users and IAM groups, set the appropriate permissions
Create an IAM role.

Permission management is possible by creating roles such as IAM administrator roles, resource administrators, developers, and testers.

#Trust relationship settings
When creating an IAM role, choose a different AWS account and enter the account ID for the JUMP account.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102020/5115c211-0c92-d7c4-24cc-9ad35c4df570.png)

It can also be changed from the IAM role Trust relationship tab.

```json:Trust_Relationship
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<JUMP account ID>:root"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

#IAM Group and IAM Role

AWS best practice recommends that you do not set policies directly for IAM users, but instead set permissions for IAM groups, and IAM users belong to groups to manage permissions.

By limiting the IAM roles that can be switched in each IAM group
It is possible to divide roles such as IAM administrator, resource administrator, developer, tester.

It is important to design the IAM role created in the target account and the IAM group in the JUMP account as a pair.

## Switch control to a specific role

To actually switch to a specific IAM role, set the following IAM policy for the IAM group:
In fact, we recommend creating a user management policy and attaching this management policy to the IAM group.

```JSON:IAM_policy_that_restricts_the_switch_destination_IAM_role

{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Action": "sts:AssumeRole",
    "Resource": "arn:aws:iam::<target account ID or"*">: role / <created IAM role name>"
  }
}
```

This procedure is also described in the official document.
https://docs.aws.amazon.com/en_us/IAM/latest/UserGuide/tutorial_cross-account-with-roles.html

#PowerUserAccess in JUMP account
As mentioned in the official document, if you attach an AWS managed policy PowerUserAccess policy to an IAM group in a JUMP account, the above switch destination ** IAM policy restricting IAM role ** will not work properly.

If the PowerUserAccess policy is attached, all IAM roles can be accessed.
The AWS official document proposes the following switch role denial rights in this case.


```Json:A_policy_that_denies_switching_to_a_specific_IAM_role
{
   "Version": "2012-10-17",
   "Statement": {
     "Effect": "Deny",
     "Action": "sts: AssumeRole",
     "Resource": "arn: aws: iam :: <target account ID or *>: role / non-purpose IAM role name"
   }
}
```

In this case, it is not impossible if the number of IAM roles is small, but the policy becomes complicated when there are multiple IAM roles.

In addition, if you include denial authority, policies belonging to multiple IAM groups may not work as intended.
For example, if there is a user who is both a resource administrator and an IAM administrator and a user who has only one role,
Even if you belong to two IAM groups, the two permissions are combined and will not work.

## Switch control and PowerUserAccess
Why does switch role not work properly in PowerUserAccess?

To consider the cause, let's look at PowerUserAccess permissions.

```Json:PowerUserAccess_policy
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "NotAction": [
                "iam:*",
                "organizations:*",
                "account:*"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:CreateServiceLinkedRole",
                "iam:DeleteServiceLinkedRole",
                "iam:ListRoles",
                "organizations:DescribeOrganization",
                "account:ListRegions"
            ],
            "Resource": "*"
        }
    ]
}
```

PowerUserAccess is a policy that allows all operations except **IAM**, **Organizations**, and **AWS account itself** by the NotAction element.

As for the control related to the switch role, since the element being used is an IAM role, it is considered to be an IAM element, but in reality it is **STS**.

Since PowerUserAccess is in a state where all STSs are allowed, it can be switched to all IAM roles regardless of **IAM policy that restricts IAM roles to switch to**.

## Proposal for switch control version PowerUserAccess permission
In order for the **IAM policy that restricts the IAM role to switch to work as intended**
You could use a policy that refuses to switch to a specific IAM role.
It is recommended to create and use a custom PowerUserAccess policy that works as intended with an IAM policy that restricts the switch destination IAM role.

Specifically, the policy is as follows.

```Json:PowerUserAccess_policy_corresponding_to_IAM_role_switch_restriction
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "NotAction": [
                "iam:*",
                "organizations:*",
                "account:*",
                "sts:*",
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:CreateServiceLinkedRole",
                "iam:DeleteServiceLinkedRole",
                "iam:ListRoles",
                "organizations:DescribeOrganization",
                "account:ListRegions"
            ],
            "Resource": "*"
        }
    ]
}
```

Add **sts: \*** inside the NotAction element.

This makes it possible to switch only to the IAM role specified in the ** IAM policy that restricts the switch destination IAM role ** as intended.

Consider using it if you want to control accounts with multiple accounts while having PowerUserAccess authority with JUMP account.