AWS + Azure ADによるSingle Sign-Onと複数AWSアカウント切り替えのしくみ作り

こんにちは、生産性向上チームの五十嵐(@ganta0087)です。

今回はAWSアカウントの管理についてのお話です。

AWSアカウントをみなさんの組織ではどのように管理されているでしょうか?

シングルアカウントで運用していると、人やチームが増えて規模が大きくなってきたときに権限管理が中央集権的になり、管理者への負担が増大してしまいます。また、新規ユーザーの登録だけでなく、退職時の削除漏れにも注意が必要です。利用者側としても管理するパスワードが増えるのは避けたいです。

そこで、生産性向上チームではマルチアカウント構成によるシングルサインオン(以下SSO)とチームに委譲できる権限管理のしくみを作ることでこれらの問題を解決し、社内でAWSを活用しやすくなるようにしました。

サイボウズには社員のアカウント情報を管理しているActive Directory(Azure AD)があります。今回はそのAzure ADをIdentity Provider(以下IdP)として設定し、権限管理まわりのしくみを作った内容を紹介します。

SSOを使ったAWSアカウントの構成の概要

AWSアカウントの整理方法

AWSアカウントは目的ごとに作成しています。

具体的にはAWS Organizationsの組織単位(OU)を使って次のように整理しています。

組織単位によるグルーピングを使ってAWSアカウントをツリー状に構成

  • root
    • admin
      管理用アカウントを配置
    • service
      この下にプロダクトごとのOUを作成し、さらにその下へ環境ごと(Production、Stagingなど)のアカウントを配置
    • professional
      組織横断型チーム用のアカウントを配置
    • business
      その他業務用のアカウントを配置
    • sandbox
      実験用のアカウントを配置

また、AWS Organizationsを使うことで請求の一括化や、APIを使ったアカウントの作成も行っています。 AWS Organizationsの利用方法については、AWSの公式ドキュメントをご参照ください。

aws.amazon.com

AWSアカウントへのログインの流れ

AWSアカウントへのログインの流れは次のようになっています。

認証用AWSアカウントにAzure ADによるシングルサインオンでログインして各アカウントにAssumeRoleを利用して切り替える流れ

まず、認証用AWSアカウントにAzure ADを経由してSSOでログインします。 この認証用アカウントには、Azure AD上のすべてのユーザーがログインできるようにしています。

これはAWS上の権限管理のためにAzure AD側のメンテナンスが不要となるよう、一律ログインさせてしまう方式をとっています。そのため、AWSにSSOでログインした直後の状態では何もできないようにしています。

目的のAWSアカウントにはAssumeRoleを利用して切り替えます。 認証用AWSアカウントに誰がどのアカウントに切り替えてよいかを定義しておき、それに基づいて切り替え可否を制御しています。この定義のマスターデータはkintoneに置き、CircleCI ServerのScheduled Buildsを使って自動同期することで簡単にメンテナンスができるようにしています。

認証用アカウントへのSSOの設定

ここでは手順のおおまかな流れを説明します。詳細な手順はMicrosoftの公式ドキュメントをご参照ください。

docs.microsoft.com

Azure AD側にAWSをアプリケーション登録

  1. Azure ADのエンタープライズアプリケーションにAWSを追加します。
  2. 追加したAWSアプリケーションにSAMLの設定を行います。
  3. フェデレーションメタデータXMLをダウンロードします。

AWS側にSAMLの設定を追加

  1. Azure AD連携用のIAM Userを作成します。(Azure ADからAWS上のIAM Roleを参照するため)
  2. IAMでProvider TypeがSAMLのIdentity Providerを追加し、Azure ADからダウンロードしたフェデレーションメタデータXMLをアップロードします。
  3. SAMLフェデレーション用のIAM Roleを作成します。(SSOの認証を通過したユーザーに割り当てられるロール) 先述したとおり、Azure ADにユーザーがあれば、誰でもAWSへ入れるようにしています。そのため、このロールに設定するポリシーは何もできないものを定義しておきます。内部的にはこのロールへAssumeRoleしており、ロールが参照できるように、iam:ListRolesだけは許可しています。
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AssumeRoleWithSAMLBasePolicy",
            "Effect": "Allow",
            "Action": "iam:ListRoles",
            "Resource": "*"
        }
    ]
}

Azure AD側にIAM Roleのマッピングを設定

  1. Azure AD連携用IAM Userのアクセスキーとシークレット使ってプロビジョニングの設定を行います。
  2. Azure AD上の全ユーザーが所属しているグループにSAMLフェデレーション用IAM Roleを割り当てます。

AWSアカウントの切り替え

先述したとおり、SSOで入った直後は何もできないため、別のAWSアカウントのロールへ切り替えられるようにします。

まず、切り替え先のAWSアカウントに対象となるロールを作成します。ロールの作成時に「別のAWSアカウント」を選択して、「アカウントID」に認証用AWSアカウントのIDを指定します。

そして、どのAWSアカウントのどのロールに切り替えてよいかのポリシーを、認証用AWSアカウントのSAMLフェデレーション用IAM Roleに付与していきます。

Azure AD上のuser-auser-bに対し、AWSアカウントIDが333333333333SampleRoleロールに切り替えることを許可するには、次のように記述します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "sts:AssumeRole"
            ],
            "Resource": "arn:aws:iam::333333333333:role/SampleRole",
            "Condition": {
                "StringLike": {
                    "aws:userid": [
                        "*:user-a@*",
                        "*:user-b@*"
                    ]
                }
            }
        },
        ...
    ]
}

このポリシーを手動で編集していくのは大変なので、自動化します。

サイボウズではkintoneアプリで切り替え先のAWSアカウント+ロールとユーザーのマッピングを管理して、ポリシー反映のツールを定期実行することによって実現しています。

kintoneアプリ上でAWSアカウントとロール、ユーザーのマッピングを管理しているスクリーンショット

kintoneのレコードに自動生成したロール切り替えのURLへのリンクやARNも表示しており、利便性も高めています。

切り替え先のAWSアカウントが増えてくると、マネジメントコンソール上では5つまでしか履歴が保持されないため不便です。そういうときはAWS Extend Switch RolesというChrome拡張が便利です。後述する~/.aws/configと同じ書式で切り替え設定を書くことができます。Chrome Syncにも対応しており、Chromeに設定したGoogleアカウントへ設定が保存されるのも便利です。

CLIの場合

マネジメントコンソールはWebブラウザで完結するため問題ありません。しかし、CLIからAWS CLIやAWS SDKを使って実装されたツールを利用したい場合は、Azure ADからAWSにSSOするためのしくみが必要となります。

AWSのナレッジセンターにその手順が掲載されています。

aws.amazon.com

流れとしては次のようになります。

  1. WebブラウザでAzure ADからAWSにSSOする際のSAMLレスポンスを、Webブラウザの開発者ツールで取り出します。
  2. AWSのSTSのAPIにAssumeRoleWithSAMLがあるので、これにSAMLレスポンスを渡すことで、認証情報を得ます。
  3. 取得した認証情報を~/.aws/credentialsに保存しておきます。

これを毎回手動で行うことは現実的ではないので、自動化するツールをOSSで実装しました。

github.com

assamではchromedpというChrome DevTools ProtocolでGoogle Chromeを操作するライブラリを利用し、Google Chromeの立ち上げからSAMLレスポンスの取得までを行っています。

assamの使い方

インストール

macOSの場合はHomebrewでインストールできます。

$ brew install cybozu/assam/assam

Linux/Windowsの場合は、最新のReleaseページから対応するアーカイブをダウンロードし、展開して得られるassamコマンドをパスの通ったディレクトリに配置してください。

設定

次に、初期設定を行います。

$ assam --configure
  • Azure Tenant ID
    • Microsoft Azureポータルから確認できます。Azure Active Directoryからプロパティにある「ディレクトリID」がAzure Tenant IDです。
  • App ID URI
    • AWSのSAMLエンドポイントを指定します。Azure AD側に設定したものと同じものを設定します。通常はhttps://signin.aws.amazon.com/samlです。
  • Default Session Duration Hours
    • セッションの有効期限を設定します。1〜12時間の任意の時間を指定してください。
  • Chrome User Data Dir
    • Google Chromeのユーザーデータディレクトリの配置場所を指定します。デフォルトでは~/.config/assam/chrome-user-dataに保存されます。

設定された内容は~/.aws/configdefaultプロファイルのセクションに保存されます。任意のプロファイルに保存する場合は--profile(-p)オプションが使用できます。

ログイン

assamコマンドを実行すると、Google Chromeが起動してAzure ADへのログインを求められます。このログイン操作によって、AWSにシングルサインオンを行い、CLIからAWSにアクセスするための認証情報をローカルに取得します。

$ assam

Azure ADにログインするとGoogle Chromeが終了してプロンプトが戻ります。

assamはデフォルトで.aws/credentialsdefaultプロファイルに認証情報を上書きするのでご注意ください。defaultプロファイルを使いたくない場合は、--profileオプションをご利用ください。

AWSアカウントとロールの切り替え

AWS CLIとSDKでは、切り替え先のロールを~/.aws/configに設定しておくと、AWS_PROFILE環境変数などによるプロファイル名の指定のみで簡単に切り替えることができます。

AWSアカウントIDが333333333333SampleRoleに切り替える設定の場合は、次のようになります。

[profile sample-role]
region = ap-northeast-1
role_arn = arn:aws:iam::333333333333:role/SampleRole
source_profile = default

~/.aws/configで設定したプロファイル名をAWS_PROFILEに指定します。

$ export AWS_PROFILE=sample-role

このように設定することで、SSOで認証情報を得たdefaultのプロファイルでsts:AssumeRoleオペレーションをバックグラウンドで実行します。そして、目的のロールの一時的な認証情報を得て、指定されたAWSへのオペレーションを実行できます。

assamの--profileオプションを使ってプロファイル名をdefaultから変更している場合は、source_profileに変更したプロファイル名を指定してください。

また、AWS SDKを使用したツールでは、AWS_SDK_LOAD_CONFIGtrueまたは1を設定しておくことで、このしくみを利用するようになります。

$ export AWS_SDK_LOAD_CONFIG=true

direnvを利用すると、ディレクトリを移動しただけでプロファイルが切り替えられて便利です。

おわりに

Azure ADをお使いの場合はぜひassamをご活用ください。

他のIdPでもSAMLの設定が可能なので、同様の構成を作る際のご参考になれば幸いです。