AWS SSOのカスタマー管理ポリシーをざっくり試す

これまでAWS管理ポリシーとインラインポリシーしか使えなかったAWS Single Sign-Ｏｎ（以下AWS SSO）が遂にカスタマー管理ポリシーをサポートした！という[リリース](https://aws.amazon.com/jp/about-aws/whats-new/2022/07/aws-single-sign-on-aws-sso-aws-identity-access-management-iam-customer-managed-policies-cmps/)があったので、取り急ぎ試してみる。

## やりたいこと
AWS SSOでカスタマー管理ポリシーを使って楽したい。

## その前に仕様確認
同僚の話によるとどうも思ってたのと少し違う仕様らしいので、公式ドキュメント（英語の方）を読んでみる。
[Custom permissions](https://docs.aws.amazon.com/singlesignon/latest/userguide/howtocmp.html)
[Use IAM policies in permission sets](https://docs.aws.amazon.com/singlesignon/latest/userguide/howtocmp.html)

> When you add customer managed policies and permissions to a permission set, AWS SSO doesn't create a policy in any AWS accounts. You must instead create those policies in advance in each account where you want to assign your permission set, and match them to the name and path specifications of your permission set. When you assign a permission set to an AWS account in your organization, AWS SSO creates an AWS Identity and Access Management (IAM) role and attaches your IAM policies to that role.

これか。。

要約すると、
- カスタマー管理ポリシー（以下CMP）を使う場合、AWS SSOはポリシー作らないよ
- アクセス許可セットを割り当てる先のメンバーアカウント側で、あらかじめポリシー作っておいてね
- AWS SSOは、割り当ての際に作られるロールにこのポリシーを探してくっつけるよ

ということになる。
てっきり管理アカウント側で、インラインポリシー同様CMPを作成・アタッチ・割り当てできるものだと思っていたので、いささか当てが外れた。
利用側のメンバーアカウントで（メンバー側管理者の責任において）ポリシーを作っておくか、スタックセットで（SSO管理者の責任において）ばら撒いた後で割り当てするか、どちらかということになりそうだ。

## ステップバイステップ
画面遷移が多いので、今回は一部を除いて、スクショなしで流れだけ記載する。

### 最初にメンバーアカウント

1. IAMのコンソールから、適当なポリシーを作成する。
1. ポリシー名は`cmp-test-policy`とする（case sensitiveなので注意）。
![スクリーンショット 2022-07-20 午後5.16.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/fc3e3c2c-88da-9022-1358-91d2fe16fb27.png)


### 続いて管理アカウント

1. AWS SSOのコンソールに移動する。
1. **許可セット**→**許可セットを作成**→**カスタム許可セット**を選択する。
1. 以下の画面から、**カスタマーマネージドポリシー**を選択して**ポリシー名**を入力する。
![スクリーンショット 2022-07-20 午後5.17.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/4569903e-3048-a0a9-5007-d3e2d424bdc1.png)

1. **次へ**で名前や説明、タグ等を入力し、**次へ**→**作成**で完了。

これで作成は完了。

目当てのメンバーアカウントに割り当てる際は、以下の手順となる。

1. **AWSアカウント**から対象アカウントを選択。
1. **ユーザーとグループを割り当て**からユーザーを選択し、**Next**。
1. アクセス許可セットを選択して**送信**。

割り当ての手順は従来と変わらない。

## いくつかテスト

- 事前にメンバーアカウントに`cmp-test-policy`がない場合はどうなる？
    - アクセス許可セットの作成は成功する。
    - 割り当て時に、`404 - Not supported policy` エラーで失敗する。
- 割り当て後、メンバーアカウントで`cmp-test-policy`を削除するとどうなる？
    - 削除できない。ポリシーがアタッチされているロールの変更が、AWS SSOからのみ操作可能というエラーとともに弾かれる。
    - 割り当てを解除すると削除可能になる。
- 割り当て後、`cmp-test-policy`の内容変更は可能か？
    - これは可能。通常のIAMの挙動通り、即時反映される。
    - ちなみに、従来のAWS管理ポリシーやインラインポリシーは、AWS SSOが生成するロールへの変更という扱いになり、編集もアタッチ/デタッチも弾かれる（AWS管理ポリシーはそもそも編集できないが）ことを考えると、この挙動の違いは統制上、留意しておく必要がありそう。
- AWS管理ポリシーやインラインポリシーと併用は可能か？
    - これも可能。試してはいないが、CMPと同時にリリースされたバウンダリーも当然併用可能と考えてよい。

というわけで、概ね、想定した通りの挙動だった。

なお、複数アカウントで同じ名前のポリシーに違う権限を与えたらどうなるか？という点については、前出の公式ドキュメントで釘を刺されているので試していない（確認できた挙動から推して、それぞれ異なる権限を与えられることも、そうすることで運用がカオスになることも容易に想像できる）。

>As a best practice, apply the same permissions to the policy in each account where you assign the permission set.


<details><summary>（2022/7/20追記）複数アカウントで同一名称のポリシーに異なる権限を与える際の利点について</summary>
利用者側への権限管理のデリゲーションを前提とする場合は、同じアクセス許可セット名で異なるポリシーを使えるのはむしろメリットになり得る、という指摘をいただきました。
L1運用者向けのアクセス許可セットに対し本番と開発で権限を変えられるようにするとか、名称と基本的な統制だけAWS管理ポリシーとインラインポリシーで整えてあとは自由裁量を与える、などでしょうか。
末尾にも書きましたが各組織の統制モデルや運用に依存するところが大きいので、要件に合った使い分けを検討いただければと思います。
</details>


## 所感

権限を一箇所で集中管理し、複数アカウントに展開するというAWS SSOの基本的な運用モデルを考えると、CMPは管理アカウントで作成する建て付けにして欲しかった。

CMPがイミュータブルでなく、IAM編集権限さえあれば任意のタイミングで変更できる点も、評価が分かれそうだ。カスタムな権限の管理・運用を利用者側に委任できるため、管理者・利用者の責任分界点の置き方によっては、むしろこちらの挙動を歓迎する向きもあるだろう。一方で、中央での統制が十分に利かない、払い出した時点から修正が入った場合（いわゆるドリフト）の追跡が困難であるなど、いくつか運用上の懸念も考えられる。

それぞれの統制モデルに併せて、インラインポリシーとの適切な使い分けが必要な機能と言えそうだ。