[AWS][Stripe] AWS Single Sign-On での Stripe への SAML 認証によるログイン設定

AWS Single Sign-On を使った [Stripe](https://stripe.com/jp) ダッシュボードへの SAML によるシングルサインオン設定をやっていきましょう。
なお、公式ドキュメントにあるように、現在 Stripe の「ダッシュボードでのシングルサインオンは招待者限定のベータ」です。
利用するには Strip 社に申請して利用できるようにしてもらう必要があります。
参考: [シングルサインオン](https://stripe.com/docs/dashboard/sso)

# Stripe でのドメインの検証

Stripe ダッシュボードへの SAML ログインを設定する前に、ログインできるユーザのメールアドレスのドメインを認証しておく必要があります。
（認証されたドメインのメールアドレスをもつユーザ以外は SAML ログインできない）
作業手順としては、指定された認証用のコードをドメインのDNSサーバに TXT レコードで登録するだけです。

* [SAML Identity Provider を使用したシングルサインオン - ドメインの所有権を証明する](https://stripe.com/docs/dashboard/sso/other#proving-domain-verification)
* [ドメイン確認](https://stripe.com/docs/dashboard/sso/domain_verification)

# AWS SSO へのアプリケーション登録

Applications から New Application　として `Add a Custom SAML 2.0 application` を選択します。
![スクリーンショット 2021-12-01 16.49.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25964/1168d2bd-ddbe-2289-e271-5ab840a2077a.png)

* [Custom SAML 2.0 applications](https://docs.aws.amazon.com/singlesignon/latest/userguide/samlapps.html)

## Configuration (設定)

「Configuration (設定)」タブでは以下の箇所を設定します。

### AWS SSO metadata (AWS SSO メタデータ)

「AWS SSO metadata (AWS SSO メタデータ)」から以下の値をコピーしておきます。

* AWS SSO issuer URL (AWS SSO 発行者 URL)
* AWS SSO sign-in URL (AWS SSO サインイン URL)
* AWS SSO certificate (AWS SSO 証明書) - 証明書はダウンロードする

![スクリーンショット 2021-12-09 12.40.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25964/9ff3234c-66df-44a6-ff0f-c197dee0787f.png)

### Application metadata (アプリケーションメタデータ)

「Application metadata (アプリケーションメタデータ)」には以下を入力します。

Name|Value
----|----
Application ACS URL (アプリケーション ACS URL) | `https://dashboard.stripe.com/login/saml/consume`
Application SAML audience (アプリケーション SAML 対象者) | `https://dashboard.stripe.com/saml/metadata`

![スクリーンショット 2021-12-09 12.44.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25964/c8a59c48-d79d-a4be-b46c-837583c59f7c.png)


他の箇所は特に変更する必要はないです。
`Display name` と `Description` だけ、お好みで変更してください。

## Attribute Mappings (属性マッピング)

「Attribute Mappings (属性マッピング)」タブでは、以下のように設定します。

User attribute in the application|Maps to this string value or user attribute in AWS SSO|Format
----|----|----
Subject|`${user:email}`|emailAddress
Stripe-Role-{stripe id} (※)|`admin` or `developer` or ,,,|unspecified
※ `{stripe id}` は `acct_` で始まる Stripe ID です。Stripe ダッシュボードの [Account Details](https://dashboard.stripe.com/settings/account) で確認できます。

IdP (AWS SSO) から Stripe に対して `Stripe-Role-{stripe id}` と言う属性を送る必要があります。
SAML ログインするユーザが Stripe ダッシュボードにどのような役割でアクセスできるかを設定するためのものです。
以下の値のいずれかを設定します。

DASHBOARD ROLE|ATTRIBUTE STATEMENT ROLE ID
---|---
Administrator (管理者)|admin
Developer　(開発者)|developer
Analyst (アナリスト)|analyst
Support Specialist (サポートスペシャリスト)|support_specialist
View Only(閲覧のみ)|view_only
* [SAML Identity Provider を使用したシングルサインオン - SAML Identity Provider を設定する](https://stripe.com/docs/dashboard/sso/other#configuring-your-identity-provider)

一方、AWS SSO でマッピングできる属性は、以下の通りです。

Supported attributes in AWS SSO|対応する項目
---|---
${user:AD_GUID}|User ID
${user:email}|Primary email
${user:familyName}|Last name
${user:givenName}|First name
${user:middleName}|Middle Name (※)
${user:name}|Display name
${user:preferredUsername}|Display name
${user:subject}|Username
※ Middle Name は、AWS SSOコンソールからは入力できません

* [Attribute mappings - Supported AWS SSO attributes](https://docs.aws.amazon.com/singlesignon/latest/userguide/attributemappingsconcept.html#supportedssoattributes)

これだけしかマッピングできないので、Stripe の Role として設定できる値がないんです...
苦肉の策として First Name (`${user:givenName}`) に Stripe の Role を設定して、それを Attribute Mapping で渡すようにしました。
![スクリーンショット 2021-12-09 13.20.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25964/3f5087a6-e77c-7e61-222b-3868954222c6.png)

最終的にこうしました。

User attribute in the application|Maps to this string value or user attribute in AWS SSO|Format
----|----|----
Subject|`${user:email}`|emailAddress
Stripe-Role-{stripe id}|`${user:givenName}`|unspecified

![スクリーンショット 2021-12-09 12.49.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25964/dc1093d1-4477-e67d-8fc6-6b37be3f2c12.png)

ここまでで、AWS SSO へのアプリケーション登録完了です。
続いて、Stripe に IdP メタデータの登録を行います。

# Stripe に IdP 設定を登録する

Stripe ダッシュボードの [Settings > User authentication](https://dashboard.stripe.com/settings/user_authentication) で、AWS SSO に登録したアプリケーションの値を、それぞれ以下の箇所にコピーします。

Name|Value
---|---
Issuer ID | AWS SSO issuer URL (AWS SSO 発行者 URL)
Identity provider URL | AWS SSO sign-in URL (AWS SSO サインイン URL)
Identity provider certificate | AWS SSO certificate (AWS SSO 証明書)
Enforcement mode | Optional (任意) を選択

* [SAML Identity Provider を使用したシングルサインオン - Stripe を設定する](https://stripe.com/docs/dashboard/sso/other#configure-stripe)

![スクリーンショット 2021-12-09 12.44.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25964/32a90e03-63ae-47ff-b9b4-890882cb6c38.png)

これで、一通りの設定ができました。
![スクリーンショット 2021-12-09 13.51.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25964/252dabed-0218-e36a-650a-a6bbb044737a.png)

# Stripe への要望

現在、ベータ期間中ということなので、以下のいずれかの機能をつけてもらえると属性マッピングが貧弱な IdP からの接続が簡単になるので対応してもらえると嬉しいなと思われます。
ご検討お願いいたします。

IdP から送られた文字列を、Stripe の role (admin, developer, ...)に変換
--------------------------------------
SAML IdP から role として任意の文字列を送ると、Stripe 側でそれを Stripe の role にあわせて変換してくれると嬉しいです。
IdP から Role として UUID とかの任意の文字列を送る → Stripe 側でユーザが登録した変換テーブルを参照して、Stripe の role (admin, developer, ...) に変換されるとありがたい。

AWS SSO から `${user:groups}` でグループIDをマッピングできるっぽいので、これができればなんとかなります。

* [How to Integrate AWS SSO with AWS Managed Elasticsearch Kibana Instance](https://faun.pub/how-to-integrate-aws-sso-with-aws-managed-elasticsearch-kibana-instance-a290c32114f8)
* [AWS SSO を利用して Amazon Elasticsearch Service へログインしてみた](https://dev.classmethod.jp/articles/aws-sso-amazon-elasticsearch-service-login/)
* [Supported user and group attributes](https://docs.aws.amazon.com/singlesignon/latest/userguide/supported-attributes.html)


Stripe で管理している role を尊重する設定の追加
--------------------------------------
上記ができない場合は次善策として Stripe で管理している role を尊重する文字列の追加してもらえると嬉しいです。
IdP から role として `default` などが送られてきたら、Stripe に登録されているユーザの role を尊重する。
新規ユーザ登録の場合はデフォルト権限を与える。デフォルト権限は管理者が変更できるようになっているとありがたいけれど、一番下の権限( `view_only` )決め打ちでも構わないです。

SAML 対象をユーザ単位(もしくはドメイン単位）で設定できるようになると嬉しい
--------------------------------------
プロジェクト全体で SAML を強制するか、通常のログインも許可するかの設定ができるようになっているけれど、これをユーザ単位(もしくはメールアドレスのドメイン単位）で設定できるようになると嬉しいです。
弊社の Stripe ダッシュボードを使うユーザのメールアドレスは弊社管理のドメインだけではなくて、別のドメインのメールアドレスを使用している人達( 協力会社とかフリーランスの人）もいます。