SSOとスイッチロールでAWSのアカウント管理を楽にした話 (2/2)

# 0.はじめに
## 概要
* 本記事は前半 (AWS側) と後半 (IDaaS側) の2部構成です。
    * こちらは後半 (IDaaS側) です。前半 (AWS側) は[こちら](https://qiita.com/ot_kaneda/items/ec8cefa7e518ea1fcaa1)。
* この記事では、社内でIDaaSからAWSへのシングルサインオン (以下、SSO) および案件で利用する各AWSアカウントへのスイッチロールを連携させた際の背景や手順などを紹介します。
* 多数のWebサービスとAWSアカウントを抱え、ユーザー管理に頭を悩ませているシステム管理者の方に読んでいただければと思っています。

# 1. 大まかな流れ
- 2部構成で、本記事ではIDaaS側で実施する内容を記載しています。
    - 弊社ではCloudGateを利用していますが、おそらくは他のIDaaSでも実施内容は概ね同じかと思います。
## AWS側
1. 踏み台となるAWSアカウントの用意
1. IAM Identity Centerの設定
1. スイッチロール作成
    - → [前の記事へ](https://qiita.com/ot_kaneda/items/ec8cefa7e518ea1fcaa1)
## IDaaS側 (この記事ではCloudGate UNO)
1. サービスプロバイダーの追加
1. 既存ユーザーのプロビジョニング

# 3. IDaaS側
- この記事ではCloudGate UNOについてご説明しますが、細かい設定箇所などはIDaaSによるかと思います。他のIDaaSをご利用の方は適宜読み替えて進めてください。
## 3-1. サービスプロバイダーの追加
1. CloudGateのAdmin Siteで「設定」メニューの「サービスプロバイダー」から「サービスプロバイダー追加」をクリック
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2349419/f16baa18-ee11-d47a-9c44-cd6eb3d87380.png)

1. サービス名「aws」で検索
1. 「Custom Service AWS Single Sign-On SAML2.0」の「+追加」をクリック
    - 表示名は任意のものを入力
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2349419/81f2a53c-c0f5-10f0-5377-09d7e3e46b29.png)
1. 「シングルサインオン」タブで下記を入力して「保存」をクリック
    1. 「Issuer / Provider name / Entity ID」：AWSの「アイデンティティソースの登録」でメモしたIAM Identity Center Assertion Consumer Service (ACS) の URL
    1. 「Assertion consumer service URL」：AWSの「アイデンティティソースの登録」でメモした「IAM Identity Center Assertion Consumer Service (ACS) の URL」
    1. 「Name IDの形式」：`urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress`を選択
    1. 「シングルサインオフの設定 - サインオフ方法」：「なし」を選択
    1. 上記以外は [CloudGate HelpCenter - Amazon Web Services SSO連携設定](https://cg-support.isr.co.jp/hc/ja/articles/6360344486169-Amazon-Web-Services-SSO%E9%80%A3%E6%90%BA%E8%A8%AD%E5%AE%9A) を参照しながら設定してください。
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2349419/4af38944-6b0c-6d74-0bb4-25515b051a00.png)
1. 「プロビジョニング設定」タブで下記を入力して「保存」をクリック
    1. ベースURI：AWSの自動プロビジョニング有効化の際にメモした「SCIMエンドポイント」
    1. OAuth ベアラートークン：AWSの自動プロビジョニング有効化の際にメモした「アクセストークン」
    1. アカウントプロビジョニング：Off → On
    1. 「対象とマッピング」の「アカウントプロビジョニング」について、以下を必要に応じて追加
        1. 姓 → familyName
        1. 名 → givenName
        1. 表示名 → displayName
        - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2349419/5f5a5c68-b04a-e583-d0f6-24f4822368a3.png)


## 3-2. 既存ユーザーのプロビジョニング
1. CloudGateのAdmin Siteで「設定」メニューの「サービスプロバイダー」から3-1. で追加したサービスプロバイダの下に表示される「プロビジョニング [同期する]」ボタンをクリックする
1. 「レポート」メニューの「認証ログ」から「プロビジョニング履歴」タブをクリックする
1. 既存のすべてのユーザーについて、3-1. で追加したサービスプロバイダの名称の「イベント：ユーザー作成」が「成功」で完了していることを確認する

## 3-3. 新たにIDaaSに追加したユーザーのプロビジョニング
1. CloudGateのAdmin Siteで「アカウント管理」メニューの「ユーザー」から「＋作成」をクリックする
1. 「サービス」にて、3-1. で追加したサービスプロバイダにチェックを入れる
1. 「作成」ボタンをクリックする
1. 「レポート」メニューの「認証ログ」から「プロビジョニング履歴」タブをクリックする
1. 追加したユーザーについて、3-1. で追加したサービスプロバイダの名称の「イベント：ユーザー作成」が「成功」で完了していることを確認する

## 3-4. アカウント間のスイッチロールについて
1. 弊社では、作成するすべてのアカウントについて下記のIAMロール作成用CFnテンプレートを適用する運用としました。
    1. システム管理者用ロール
    1. インフラ構築用ロール
    1. 開発者用ロール
1. 細かい内容は割愛しますが、これらのテンプレートはパラメータにて、誰がどのロールに属するかをメールアドレスにて指定することができます。
1. ご参考までに、システム管理者用ロールのCFnテンプレートを公開します。 ※. 公開にあたり、一部値を書き換えています。

```yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Switch role for SystemAdministratorRole'


Parameters:
  CompanyAccountID:
    Type: String
    Default: '01234567890'
  CompanyRoleName:
    Type: String
    Default: 'company_role_name'
  RoleName:
    Type: String
    Default: 'SystemAdministratorRole'
  InitialUserNames:
    Type: CommaDelimitedList

Conditions:
  AddConction: !Not [ !Equals [ "" , !Join [",", !Ref InitialUserNames ] ] ]

Resources:
# Administrator Role
  AdministratorRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Ref RoleName
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Principal:
            AWS: !Sub "arn:aws:iam::${CompanyAccountID}:role/aws-reserved/sso.amazonaws.com/${AWS::Region}/${CompanyRoleName}"
          Action:
            - sts:AssumeRole
            - sts:SetSourceIdentity
          Condition:
            StringEquals:
              aws:PrincipalTag/userName: !If
              - AddConction
              - !Ref InitialUserNames
              - "foo@example.com"
      Path: "/"
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AdministratorAccess

```

# 4. まとめ
- いかがでしょうか。弊社ではこの仕組みでAWSアカウントへのアクセス方法を一元化するまで、個々の社員にAWSアカウント別のIAMユーザー管理を一任していました。社内には20を超えるAWSアカウントが存在していて、社員は複数のAWSアカウントに所属していたので、IAMユーザー数だけで考えても膨大な数が存在していたことになります。
- この仕組みを導入したことにより、以下のメリットが得られました。
    - IDaaS内で社員数分のIDを管理するだけで良くなった
        - 仮に退職者のスイッチロール許可の更新を忘れたとしてもその前段のSSOがそもそもできないので、セキュリティリスクも低減
    - 社員の増減に応じてAWSのIAMユーザーを個別のアカウントに用意する手間も減った
- CloudGate UNOではGoogle Workspace、AWS以外にもMicrosoft 365やSlackなど当社で利用中の他サービスにも連携しているため、他サービスでも利用を広げていき社内のID管理を一元化していけたらいいのかなと思います。