AWS SSOでABACを触ってみた。


というわけで今回は、最近に発表された新機能であるAWS SSOでのABACを触ってみました。
https://aws.amazon.com/jp/about-aws/whats-new/2020/11/aws-single-sign-on-enables-attribute-based-access-control-simplify-permissions/

# AWS SSOとは

https://docs.aws.amazon.com/ja_jp/singlesignon/latest/userguide/what-is.html

会社で運用するAWSアカウントは、環境を分けたり検証したりするためいくつも用意されていることがあります。
AWSアカウントにアクセスする場合、通常はIAMユーザーを発行して対応するかと思いますが、個人個人にユーザー発行していくのは面倒ですよね。
そこで、組織が所持しているIdPと連携し、そのユーザー情報を使って複数のAWSアカウントに共通でアクセスできるようにするのがこのAWS SSOです。


# ABACとは

https://docs.aws.amazon.com/singlesignon/latest/userguide/abac.html

属性ベースのアクセスコントロールを指します。
今までの権限管理というのは、サービス単位でアクセス許可を行っていました。
しかし、権限管理の複雑化により同じサービスでもこのリソースは触れるようにしたいがこちらは触れないようにしたいという需要が生まれました。
例えば、自分のIAMユーザーは参照できるようにしたいが、他のユーザーは見せたくないなどです。

そこで生まれたのがAttributes-Based Access Controlです。
これにより、リソースに付与されたタグの値などを参照してアクセス権限を設定できるようになりました。


#手順

参考
https://docs.aws.amazon.com/ja_jp/singlesignon/latest/userguide/configure-abac.html

SCIMによって外部プロバイダーIdP（AzureAd）のユーザーをAWS SSOに自動プロビジョニングしているという前提です。
すでにSSOの設定はされていて、新しくアクセス権限にABACを追加したいとします。
今回は、IdPで持っているユーザーの電子メールアドレスを参照し、特定のドメインでなければアクセス拒否します。

##SAMLアサーションに参照したい情報を渡す。

AWS SSOはSAMLという技術を使用しています。
SAMLはアサーションというものに色々な情報を載せ、その内容を確認することでSSOを実現しています。
そのため、AWS側でIdPが持つ情報を使用する場合、アサーションの中に含めてやる必要があります。

以下のように移動してください。
AzureAD→エンタープライズアプリケーション→｛SSO用のアプリ｝→シングルサインオン→ユーザー属性とクレーム→編集→新しいクレームの追加

以下のAccessControl:Emailというのが今回追加したいものになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540428/fa1915fc-b11d-4454-8e39-eeee8809cd3c.png)

名前：AccessControl:｛Email｝
名前空間：https://aws.amazon.com/SAML/Attributes
ソース：属性
ソース属性：{user.mail}

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540428/2ee27798-508a-7f55-53f0-4dae3ccb89e5.png)

名前空間は固定で、名前やソース属性は使用したい値に応じて変えましょう。
これでアサーションにユーザーのメールアドレスが含まれるようになりました。

##AWS SSOにてABACを有効化する

AWS側でABACを有効化するには、設定画面から有効にする必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540428/278a24d0-fd23-e6ab-0a4a-73c22852a378.png)

このとき、アクセスコントロールの属性→詳細を表示からマッピングを行いたくなりますが、アサーションに情報を含めるように設定したためここはなにもいじる必要はありません。

##アクセス権限セットで属性を使用したConditionを設定する。

参考
https://docs.aws.amazon.com/ja_jp/singlesignon/latest/userguide/configure-abac-policies.html

ここまででABACを行う準備ができました。
では、アクセス権限セットに属性を使用したConditionを設定してみましょう。
これだけだと当然条件に一致しようがしまいが何の権限もないので、管理ポリシーでも適当な権限を付与しておきましょう。

```yaml
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "BlockUsersOtherThanWHI",
            "Effect": "Deny",
            "Action": "*",
            "Resource": "*",
            "Condition": {
                "StringNotLike": {
                    "aws:PrincipalTag/Email": "*@xxxxxx.onmicrosoft.com"
                }
            }
        }
    ]
}
```

今回は、アサーションに含めたEmailを参照して、後半が@xxxxxx.onmicrosoft.comに一致しない場合はすべての権限をDenyするようにしてみました。
本来はIdP側でちゃんとユーザーを絞っておく必要がありますが、運用と組織図がかみ合っていないなどで使用したいユーザーグループのなかに権限を与えたくないユーザーがいたりもするかもしれません。
これでもアカウントへのSSOまでは行われてしまいますが、中で何も見れず何もできないのでセーフティネットとしては機能するはずです。
やったー


##トラブルシュート

ここまでの手順で設定はできたと思いますが、うまく動かないなということもあると思います。
そこで、IdP側から情報が来ていないのか、AWS側でアクセス権限セットの記述に失敗しているのかを切り分けるために、アサーションに値が含まれているか確認してみましょう。
アサーションの中身を調べるには、GoogleChromeの拡張機能が便利でした。

SAML-tracer
https://chrome.google.com/webstore/detail/saml-tracer/mpdajninpobndbfcldcmbpnnbhibjmch?hl=jp

使い方は簡単で、SAML-tracerを有効にした状態でSSOポータルからSSOしてみるだけでSAMLアサーションを確認することができます。
いろいろGETとかのリクエストが出てくると思いますが、SAMLはちゃんとSAMLというマークがついているので一目でわかるはずです。
その結果得られたアサーションは以下のようなものになります。
ちゃんとEmailが渡っていることが確認できますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540428/e8b9febd-9e26-886c-9659-783696152392.png)

#おわりに

AWS SSOのABAC機能を使ってみました。
今回はIdPのユーザー属性をそのまま参照して静的な値と比較していましたが、例えばEC2インスタンスのタグを比較対象にしたりということも可能です。
ABACは無限の可能性を秘めていますので、これを使いこなしていくのは最先端のAWS使いにとっては必須要件といえるでしょう。
是非皆さんも触ってみてくださいね。