普段使いのAWS SSO、マルチアカウント環境でCLIの利用をセキュアで楽にする

プロフィールにも記載しておりますが、投稿内容は個人の見解であり、所属する組織の公式見解ではありません。

[Japan APN Ambassador Advent Calendar 2020](https://qiita.com/advent-calendar/2020/japan-apn-ambassador) の 19 日目のエントリです。

本日は、AWSのマルチアカウント環境での作業を楽にするため、**AWS SSOを「普段使い」する**ための方法をご提案します。

こちら、Advent Calendar登録時になんとなく「AWS SSOについて書こっかなー」ぐらいのノリだったのですが、
初日にAPN Ambassador界の技術書の巨匠、佐々木さん(@dkfj)が書かれた[エントリー](https://blog.takuros.net/entry/2020/12/01/094417)と被っており、
しかも内容もいつもどおりすばらしいということで、完全にはしごを外されたかたちとなっております。
ネタ被りしておりますこと、予めお詫び申し上げます🙇

## AWS SSOとは？

[AWS Single Sign-On](https://aws.amazon.com/jp/single-sign-on/) (以下、AWS SSO)は、2017年12月に米国東部 (バージニア北部) リージョンで一般公開されました。

公式のドキュメントによれば、

>AWS Single Sign-On (SSO) は、複数の AWS アカウントとビジネスアプリケーションへのアクセスの一元的な管理を容易にし、割り当てられたアカウントとアプリケーションのすべてに対する 1 か所からのシングルサインオンアクセスをユーザーに提供できるようにする AWS のサービスです。

引用：[AWS Single Sign-On（クラウドシングルサインオン (SSO) サービス）| AWS](https://aws.amazon.com/jp/single-sign-on/)

とあり、AWSアカウントだけでなく、
SalesforceやServiceNow等のビジネスアプリケーションとのシングルサインオンも実現できるマネージドサービスです。

AWS SSOがビルトインで[サポートするサービス](https://docs.aws.amazon.com/singlesignon/latest/userguide/saasapps.html#saasapps-supported)は日々増え続けており、GithubやSlack、Confluenceといったビルダーに人気のサービスから、Zoomなどもありますね。

AWS SSOは、**2020年9月についに東京リージョンでもGA**となり、
日本のAWSユーザー様にとっても、より利用しやすいものになりました！

[AWS Single Sign-On が東京リージョンで利用できるようになりました | Amazon Web Services ブログ](https://aws.amazon.com/jp/blogs/news/aws-single-sign-on-tokyo/)

そして、2020年9～11月にかけて、現在進行形で頻繁にアップデートが行われている**「熱い」サービス**の1つです。

- 2020年9月10日、[AWS SSOのAPIとCloudFormationサポートがリリース](https://aws.amazon.com/about-aws/whats-new/2020/09/aws-single-sign-on-adds-account-assignment-apis-and-aws-cloudformation-support-to-automate-multi-account-access-management/)

- 2020年9月18日、[AWS SSOのサインインプロセスやサインインドメインの変更を発表](https://aws.amazon.com/jp/blogs/security/get-ready-upcoming-changes-aws-single-sign-on-user-sign-in-process/)

- 2020年11月20日、[AWS SSOのWebAuthnサポートを発表。](https://aws.amazon.com/about-aws/whats-new/2020/11/aws-single-sign-on-adds-web-authentication-webauthn-support-for-user-authentication-with-security-keys-and-built-in-biometric-authenticators/)YubiKeyやTouch IDでもMFAできるようになりました

- 2020年11月24日、[AWS SSOで属性ベースのアクセス制御機能をリリース。](https://aws.amazon.com/about-aws/whats-new/2020/11/aws-single-sign-on-enables-attribute-based-access-control-simplify-permissions/)Active Directory等のユーザーアカウント属性を元に、アクセス制御設定を行うことができるようになりました

- 2020年12月15日、[AWS SSOがMicrosoft Active Directory (AD) synchronizationをサポート](AWS Single Sign-On now supports Microsoft Active Directory (AD) synchronization https://aws.amazon.com/about-aws/whats-new/2020/12/aws-single-sign-on-supports-microsoft-ad-synchronization/)

## AWS SSOを「普段使いする」とは？

さて、このように熱いAWS SSOですが、
いきなり本番投入するというのはさすがに抵抗があるかと思います。

特に、AWS SSO導入の敷居を上げていると思われるのが、AWS SSOを利用するためには、
[**対象のAWSアカウントがAWS Organizationsの管理対象になっている必要がある**](https://docs.aws.amazon.com/singlesignon/latest/userguide/prereqs.html)ことです。

AWS OrganizatonsやAWS SSOに慣れるために、
先ずは開発環境やサンドボックス環境で有効化してみて、実際に使ってみてはいかがでしょうか？

### AWS OrganizationsとAWS SSOを有効化してみる

AWS OrganizationsとAWS SSOの有効化手順ですが・・・
全部書くとものすご～～～く長いエントリになってしまうので、参考にさせていただいたブログ記事をご紹介します。
(手抜きですいません・・)

#### AWS Organizations

AWS Organizationsの有効化手順については、
APN Ambassadorでもある、クラスメソッド社の濱田様が書かれた以下のブログを参考にさせて頂きました。

[AWS Organizationsとは？rootユーザも制御するその強力さを手を動かして体感してみる | Developers.IO]( https://dev.classmethod.jp/articles/organizations-gettingstarted/)

こちらの記事、Organizationsを有効化するチュートリアルというだけでなく、
OrganizationsやSCPの概念についてもわかりやすく解説して下さっており、めちゃくちゃおすすめです！！！

#### AWS SSO

AWS SSOの有効化・設定手順については、
サーバーワークス社の渡辺様が書かれた以下のブログを参考にさせて頂きました。

[AWS Single Sign-On（SSO）でAWSアカウントへシングルサインオン - サーバーワークスエンジニアブログ](https://blog.serverworks.co.jp/tech/2020/03/06/sso/)

こちらの記事、公式ドキュメントのGetting Startedだけではわかりづらい、
AWS SSOへのAWSアカウントの追加や、アクセス権限セットの追加手順についても、
画面ショット付きでわかりやすく説明して下さっています！

#### こうなった

AWS Organizationsについては以下のように設定しました。
OUの下に、「開発用(Development)AWSアカウント」と「サンドボックス用(Sandbox)AWSアカウント」をOrganizationsの管理対象に追加しました。
![organizations_tree_with_caption.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281143/d53bb216-3ca1-d91e-9713-a107e7e5ca58.jpeg)

AWS SSOについては以下のように設定しました。
2つのAWSアカウントに対して、参照権限のみ許可するPermission Sets(ViewOnlyAccess)を設定してあります。
また、SSO用のグループとユーザーを作成し、両方のAWSアカウントに紐づけしてあります。
![aws_sso_accounts_with_caption.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281143/17ffb433-c977-5c9e-9039-d74a53bdd398.jpeg)

ログインプロセス中に、11月にリリースされたばかりのWebAuthnも加えてみます。
AWS SSOのSettingsにて、"Security keys and build-in authenticators"にチェック。
![sso_mfa_settings02.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281143/87327d58-9e40-a3f1-372a-85a8c95f18b6.jpeg)


## 普段使いしてみた

シングルサインオンの使用感を確かめてみましょう。

### AWS SSOを有効化し、マネジメントコンソールを使う
AWS SSOを有効化すると、User Portal URLが発行されます。
URLにアクセスすると、ID⇒パスワードと入力した後、MFAが走ります。
![aws_sso_login_dec_2020_03.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281143/dc85c717-a333-770d-b7b7-184c569ab790.jpeg)
今回はYubiKeyで認証してみます。
YubiKeyを端末のUSBポートに刺し、タッチ。
![aws_sso_login_dec_2020_04.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281143/8fe4f310-c774-52cf-caf2-7336eb33727b.jpeg)
許可。
![aws_sso_login_dec_2020_05.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281143/481a8d11-5820-cfe3-a225-3f7f7cf26871.jpeg)
完了。
YubiKeyが登録できました。以後、サインイン時のMFAは、ID/パスワードに加え、YubiKeyへのタッチのみで済みます。
![aws_sso_login_dec_2020_06.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281143/aa4d340d-f628-ae2d-c702-4495e6c74ef2.jpeg)
ログインプロセスが完了すると、User Portalが表示されます。
"Management console"リンクをクリックすることで、各アカウントの環境にジャンプできます。
今回は2アカウントしかなく、ありがたみが薄いですが、
1組織内で10も20もAWSアカウントがある場合は便利かと思います。
![aws_sso_portal_with_caption.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281143/3885d7d1-3229-602f-eb24-bb67af5ca6b1.jpeg)



### AWS SSOを有効化し、AWS CLIを使う

手元の端末のAWS CLIでSSOする場合、"aws configure sso"します。
※PowerShellで実行しています。**AWS CLIはバージョン2(重要)**をインストールしておいて下さい。

マネジメントコンソールの時と同様、ブラウザが開きログインプロセスが走ります。

```
PS C:\> aws configure sso
SSO start URL [None]: https://[yourdirectory].awsapps.com/start
SSO Region [None]: ap-northeast-1
Attempting to automatically open the SSO authorization page in your default browser.
If the browser does not open or you wish to use a different device to authorize this request, open the following URL:

https://device.sso.ap-northeast-1.amazonaws.com/
```

利用したいアカウントID(開発用AWSアカウント)を選択し、デフォルトリージョンとプロファイル名(ViewOnly-Development)を入力します。

```
There are 2 AWS accounts available to you.
Using the account ID <AWS SSOで登録したアカウントIDを選択>
The only role available to you is: ViewOnlyAccess
Using the role name "ViewOnlyAccess"
CLI default client Region [None]: ap-northeast-1
CLI default output format [None]:
CLI profile name [ViewOnlyAccess-<アカウントID>]: ViewOnly-Development
```

もう1つのアカウントID(サンドボックス用AWSアカウント)も、同様にプロファイル登録しておきます。(ViewOnly-Sandbox)

AWS CLIを実行する際は、プロファイル名を指定します。

```
PS C:\> aws s3 ls --profile=ViewOnly-Development
※開発用AWSアカウントのバケットが表示される
PS C:\> aws s3 ls --profile=ViewOnly-Sandbox
※サンドボックス用AWSアカウントのバケットが表示される
```

さて、この時おもむろに"aws configure list"を実行してみましょう。

```
PS C:\> aws configure list                                                                                                       Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key                <not set>             None    None
secret_key                <not set>             None    None
    region                <not set>             None    None
```

**アクセスキーとシークレットアクセスキーを明示的に設定してない**ですね。
ここが一番うれしいポイントかと思います。

アクセスキーとシークレットアクセスキーって・・**配布した後の管理がすごくめんどくさい**ですよね。
最近はあまり聞かなくなりましたが、数年前、GithubにPushしたコード中にアクセスキーとシークレットアクセスキーがハードコードされており、悪用されて高額請求、みたいな事故が散見されました。

AWS SSOを利用すると、~/.aws/cli/cacheと~/.aws/sso/cacheに一時的な認証情報が保存されます。
**AWS SSOのデフォルトのセッション有効期限は1時間。**つまり、生成されたtemporaryなアクセスキーとシークレットアクセスキーは、1時間でexpireします。

デフォルトプロファイルを設定すれば、クライアント端末上のコード中から
AWS SSOによって生成された一時的な認証情報を利用することもできます。

```
PS C:\> $env:AWS_PROFILE="ViewOnly-Sandbox" 
```

IAMロールを直接割り当てできないクライアント端末であっても、AWS SSOを活用することで、
**AWSアクセス時に長期的に利用できるアクセスキー/シークレットアクセスキーを配布する必要がなくなり**、
且つ、**プロファイルの切り替えによってマルチアカウント環境でもシームレスにCLIによる作業を進めることができる**ようになります。

※AWS SSOは[CloudShell](https://aws.amazon.com/blogs/aws/aws-cloudshell-command-line-access-to-aws-resources/)でも動くよ！！！

## まとめ
AWS SSOの良いところばかり書きましたが、**Permission Setsの権限設定がザルだと全くもってセキュアではなくなります**ので、最小権限付与の原則に基づき、しっかり制限しましょう。
また、せっかくAWS Organizationsを利用しているので、SCPを使ったガードレール設定も併せて検討すべきかと思います。

一番の障壁は、**AWSアカウントの調達スキームによっては、AWS Organizationsが利用できない**、というケースですかね・・。
AWSアカウントをリセラー経由で調達される場合は、AWS Organizationsを利用可能かどうか、事前にご確認いただくとよいかと思います。

こちらからは以上です。