スイッチロール先の本番・開発アカウントにてIAMロール、ポリシー、パーミッションバウンダリーを作ってみた

AWS IAM の機能の中でも割とマイナーなPermissions Boundary(パーミッションバウンダリー)。今回はこれを活用してみました。
2020.08.30

ちゃだいん(@chazuke4649)です。

今日はスイッチロールを前提とした本番・開発アカウント用のIAMロール・ポリシー・パーミッションバウンダリーを考えてみたのでご紹介します。

どういうこと?

構成図

解説

AWS環境の中に複数の環境を持つ場合、複数のアカウントに分けて運用することで一定のメリットを享受することができます。詳しくはこちらをご覧ください。今回は上図の様に、中央管理用のAWSアカウントにIAMユーザーを一元管理し、実際に構築・開発・運用する環境はAWSアカウントとして分けて作成し、その環境へは中央管理用のAWSアカウントからスイッチロールしてアクセスするというものです。

これによる最大のメリットは、管理すべきユーザーを一元的に集中管理できる様になるため、アカウント数の追加に伴ってユーザー数も増やさなくて済む点かと思われます。

その中でも今回の特徴としては、スイッチロール先のIAMロールの権限を、通常のIAMポリシーと Permissions Boundary(パーミッションバウンダリー)で管理している点です。この構成のメリットは、IAMポリシーではとりあえず広くアクションを許可し、パーミッションバウンダリーでこれだけは禁止したいというアクションを制限する、といった柔軟な権限設定が可能になる点かと思われます。

では実際にやってみます。

前提

  • スイッチロール元である、中央管理用のAWSアカウント111111111111
  • スイッチロール先である、本番・開発環境用のAWSアカウント222222222222

※構成図では本番・開発は分けてますが、以下手順では片方のみ作成するとお考えください。

手順

以下の通り手順で進めます。

  • 1.中央管理用のAWSアカウントにIAMユーザーを作成する
  • 2.本番・開発環境用のAWSアカウントにバウンダリーを作成する
  • 3.本番・開発環境用のAWSアカウントにIAMロールを作成する

1.中央管理用のAWSアカウントにIAMユーザーを作成する

※ 本エントリでは、中央管理用のIAMユーザーの権限はどうあるべきかを掘り下げません。 よって最低限の権限をもったIAMユーザーを作成します。

  • AWSアカウント:111111111111
  • IAMユーザー名:xxx-yamada.taro

IAMポリシーは以下の通りです。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "sts:AssumeRole"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

最低限スイッチロールする権限を有したユーザーを作成しました。本来は中央管理用のAWSアカウント内で最低限の情報を読み取りできたり、自分でパスワードやMFAを設定できる様にする必要があるかと思われます。

2.本番・開発環境用のAWSアカウントにパーミッションバウンダリーを作成する

次に、スイッチロール先である本番・開発環境のAWSアカウントにて作業を行います。

IAMロールを作成する前に、そのIAMロールのアクションを制限するために、パーミッションバウンダリーのポリシーを作成します。カスタマー管理ポリシーとして作成し、今後IAMロールを複数追加した場合でも、バウンダリー用のポリシーとして一元的に使用します。最後の参考URLにも書いてますが、この記事を参考に一部修正しています。ポリシーの概要は以下の通りです。

  • 禁止したいアクション
    • CloudTrailの停止/削除を拒否
  • 権限昇格の防止関連
    • IAM Userの作成を拒否
    • IAM Roleの作成とPolicyのアタッチは指定したRole用Boundary(RolePermissionsBoundary)がアタッチされている場合のみ可能(されていないと拒否)
    • UserPermissionsBoundaryとRolePermissionsBoundaryの編集を拒否
    • アタッチされているPermissions Boundaryのデタッチを拒否

実際のポリシーは以下の通りです。

RolePermissionsBoundary.json

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AdministratorAccess",
            "Effect": "Allow",
            "Action": "*",
            "Resource": "*"
        },
        {
            "Sid": "DenyUserCreationOrChange",
            "Effect": "Deny",
            "Action": [
                "iam:CreateUser",
                "iam:DeleteUser",
                "iam:PutUserPolicy",
                "iam:DeleteUserPolicy",
                "iam:AttachUserPolicy",
                "iam:DetachUserPolicy",
                "iam:PutUserPermissionsBoundary",
                "iam:AddUserToGroup",
                "iam:RemoveUserFromGroup",
                "iam:UpdateUser"
            ],
            "Resource": "*"
        },
        {
            "Sid": "DenyCreateOrChangeRoleWithoutBoundary",
            "Effect": "Deny",
            "Action": [
                "iam:CreateRole",
                "iam:PutRolePolicy",
                "iam:DeleteRolePolicy",
                "iam:AttachRolePolicy",
                "iam:DetachRolePolicy",
                "iam:PutRolePermissionsBoundary"
            ],
            "Resource": "*",
            "Condition": {
                "StringNotEquals": {
                    "iam:PermissionsBoundary": "arn:aws:iam::[AccoundID]:policy/RolePermissionsBoundary"
                }
            }
        }, 
        {
            "Sid": "DenyBoundaryPolicyEdit",
            "Effect": "Deny",
            "Action": [
                "iam:CreatePolicyVersion",
                "iam:DeletePolicy",
                "iam:DeletePolicyVersion",
                "iam:SetDefaultPolicyVersion"
            ],
            "Resource": [
                "arn:aws:iam::[AccoundID]:policy/UserPermissionsBoundary",
                "arn:aws:iam::[AccoundID]:policy/RolePermissionsBoundary"
            ]
        },
        {
            "Sid": "DenyBoundaryDelete",
            "Effect": "Deny",
            "Action": [
                "iam:DeleteUserPermissionsBoundary",
                "iam:DeleteRolePermissionsBoundary"
            ],
            "Resource": "*"
        },
        {
            "Sid": "DenyCloudTrailChange",
            "Effect": "Deny",
            "Action": [
                "cloudtrail:DeleteTrail",
                "cloudtrail:PutEventSelectors",
                "cloudtrail:StopLogging",
                "cloudtrail:UpdateTrail"
            ],
            "Resource": "*"
        }
    ]
}

3.本番・開発環境用のAWSアカウントにIAMロールを作成する

最後に、IAMロールの作成です。今回はIAMロールの作成のみCloudFormationで行います。

Parametersには、それぞれ以下を入力します。

  • TrustedAWSAccountId:111111111111
  • IAMUserName:xxx-yamada.taro

実際のCloudFormationテンプレートは以下の通りです。

xxx-yamada.taro-IamRole.yaml

AWSTemplateFormatVersion: 2010-09-09
Description: Template for Creating IAM Role to Switch from Central AWS Account
Parameters:
  TrustedAWSAccountId:
    AllowedPattern: '^[0-9]*$'
    Type: String
    Default: ''
    Description: Trusted AWS Account ID
  IAMUserName:
    AllowedPattern: '^xxx-[a-z.]*$'
    Type: String
    Default: xxx-xxx.xxx
    Description: IAM Role Name
Resources:
  IAMRoleForFullAccessUser:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              AWS: !Join 
                - ''
                - - 'arn:aws:iam::'
                  - !Ref TrustedAWSAccountId
                  - ':user/'
                  - !Ref IAMUserName
            Action:
              - 'sts:AssumeRole'
      ManagedPolicyArns:
        - 'arn:aws:iam::aws:policy/AdministratorAccess'
      Path: /
      RoleName: !Ref IAMUserName
      PermissionsBoundary: !Sub arn:aws:iam::${AWS::AccountId}:policy/RolePermissionsBoundary
Outputs:
  IAMRoleArn:
    Value: !GetAtt 
      - IAMRoleForFullAccessUser
      - Arn
  LinkForSwitchRole:
    Value: !Join 
      - ''
      - - 'https://signin.aws.amazon.com/switchrole?roleName='
        - !Ref IAMUserName
        - '&account='
        - !Ref 'AWS::AccountId'

テストしてみる

少しテストしてみます。テストの手順は以下の通りです。

  • 1.中央管理用のAWSアカウントのIAMユーザーとしてログインする
  • 2.本番・開発環境用のAWSアカウントのIAMロールにスイッチする
  • 3.IAMロールの権限で許可されているアクションを行う
  • 4.IAMロールの権限で禁止されているアクションを行う

1.中央管理用のAWSアカウントのIAMユーザーとしてログインする

IAMユーザー作成時に発行された、ユーザー名とパスワードを使用してログインします。

2.本番・開発環境用のAWSアカウントのIAMロールにスイッチする

IAMロール作成時に以下のようなスイッチロール用のURLが発行されます。

中央管理アカウントでIAMユーザーにログイン後、上記URLをクリックすると、表示名などをどうするか聞かれますが、適宜xxx-yamada.taroなどと入力し進めば、無事スイッチロールができます。

3.許可されているアクションを行う

スイッチロール後の権限で、許可されているアクションを行ってみます。例えば、EC2インスタンスを起動してみたいと思います。実際にやってみると、以下の通りEC2インスタンスを起動することができました。

4.禁止されているアクションを行う

問題はこっちの方ですね。パーミッションバウンダリーで禁止されているアクションを行ってみたいと思います。

1つ目に、IAMユーザーの作成を行ってみました。すると、以下の通り、作成に失敗しました。

2つ目に、CloudTrailの証跡を削除を試みました。すると、以下の通り、削除に失敗しました。

無事、パーミッションバウンダリーによってアクションが制限されていることが確認できました。
検証は以上です。ぜひ一度皆さんも試してみていただけると幸いです。

参考URL

Switching to a Role (Console) - AWS Identity and Access Management

複数AWSアカウントのユーザ管理を、ログイン用AWS環境に集約してみた | Developers.IO

[新機能]IAMの委譲権限を制限可能なPermissions Boundaryが登場したので試してみた | Developers.IO

Permissions Boundaryによる利用者へのIAM権限移譲と権限昇格の防止 - Qiita

そのBoundary Policy適用しても大丈夫ですか? IAM Policy SimulatorでBoundary Policyのシミュレーションが可能になりました | Developers.IO

IAMのスイッチロールを理解したい | Developers.IO