OpenSearchでBackend rolesを使ってユーザーとロールを紐づける

# はじめに
皆さんこんにちは。いよいよ年の瀬ですね。
今回は、Amazon OpenSearch Serviceのユーザーとロールの設定についてまとめてみようと思います。
ドキュメントにも記載はありますが、初見だとなかなかわかりにくいので、一度図でまとめてみます。
少しネタバレすると、**Backend Roles**をうまく使うのがコツです。

# 前提
Amazon OpenSearch Serviceバージョン1.2での内容になります。
OpenSearch ServerlessやElasticsearch、OSSのOpenSearchでは挙動が異なる場合があるのでご注意ください。

# OpenSearchのロールって何？
Amazon OpenSearch Serviceでは、[きめ細やかなアクセスコントロール（Fine-grained access control）](https://docs.aws.amazon.com/ja_jp/opensearch-service/latest/developerguide/fgac.html)という機能を用いることで、OpenSearch内でのロールを定義することができます。
このロールは、IAMロールとは異なりますが、イメージは似ています。ロールごとに、読み込みや書き込みなどの許可するアクションなどを定義することができます。

以下が実際のロールのEdit画面です。雰囲気だけつかんでください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/7ee123b2-580f-6ec3-c933-0596edced5cf.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/6f1c0db4-4f98-385d-1223-28dbf62606e7.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/8d2a4bf0-c34c-03c2-ad15-e4e962dd14b0.png)

さて、IAMロールでも、そのロール自体に色々なものを紐づけられますよね。（IAMユーザー、SAML認証使ったIdP、Lambda関数などのリソースなど）
同じく、OpenSearchのロールにも色々なものが紐づけられます。

その紐づけを紹介する前に、また実際のスクリーンショットを見てみましょう。
これは、あるロールに何を紐づけるかを設定する画面です。
**Users**と**Backend roles**という2つの項目があることが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/9f844b98-7d57-c8f3-5690-852e5dac241e.png)

# Backend rolesとは何か？
[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/opensearch-service/latest/developerguide/fgac.html#fgac-access-control:~:text=%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84%E3%80%82-,%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%81%B8%E3%81%AE%E3%83%AD%E3%83%BC%E3%83%AB%E3%81%AE%E3%83%9E%E3%83%83%E3%83%94%E3%83%B3%E3%82%B0,-%E3%83%AD%E3%83%BC%E3%83%AB%E3%81%AE%E3%83%9E%E3%83%83%E3%83%94%E3%83%B3%E3%82%B0)にはこのように記載があります。
>バックエンドロールは、ロールをユーザーにマッピングする別の方法です。同じロールを多数の異なるユーザーにマッピングするのではなく、ロールを 1 つのバックエンドロールにマッピングしてから、すべてのユーザーがそのバックエンドロールを持つようにできます。バックエンドロールは、IAM ロールまたは任意の文字列にすることができます。

Backend rolesを使うと、**ロールに直接紐づけるのではなく、もう一層Backend rolesを挟んで紐づける**ことができるようになります。
また、Backend rolesはInternal usersだけでなく、IAMロールやSAML認証の際のIdPにも利用可能です。

Backend rolesを使ってInternal usersとロールを紐づけるときは、以下のスクショのように両者のBackend roleに同じ文字列を入力します。（例では`back-sample`という名前のBackend roleとしています）
Backend roleはどこかでロールのように作成するのではなく、自由に文字列で記載できます。

**Internal usersの設定**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/f089657b-adab-8bbd-12c8-e0c7a77488bc.png)

**ロールの設定**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/c07dc64d-129f-4168-8777-23ee28f2ae9d.png)


# ロールと何が紐づけられる？
さて、先ほどロールの紐づけ画面には**Users**と**Backend roles**という2つの項目がありました。
それを踏まえて、ロールの紐づけを図にしたものが以下です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/6e10e3d2-8a25-b27d-7b95-9f79bb6fb33c.png)

CognitoユーザーやIAMユーザーは、Usersの項目から紐づけます。
IAMロールやIdPは、Backend rolesの項目から紐づけます。
Internal usersは、Usersの項目から直接ロールに紐づけられますし、Backend rolesを介して紐づけることもできます。

では、Internal usersを利用するとき、どのようにロールと紐づけるのが良いでしょうか？

# どのようにInternal usersとロールを紐づける？
結論から言うと、
**テナントごとに必要なロールを作成して、それをBackend rolesと紐づけて管理しよう**
となります。Backend rolesを、ユーザーグループのように使っていきます。
（ちなみに、このユーザーグループのような使い方は、OSSの方のOpenSearchの[ドキュメント](https://opensearch.org/docs/latest/security-plugin/access-control/index/#:~:text=except%20delivery_driver_name.-,Backend%20role,-(Optional)%20Arbitrary%20strings)にも記載があります。）
以下の図を用いて詳しく説明します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/4ece5bb0-529b-e368-9ad5-3c478e0e8d50.png)

## テナントとは？
まずは、テナントという概念についてです。
[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/opensearch-service/latest/developerguide/fgac.html#:~:text=%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84%E3%80%82-,OpenSearch%20Dashboards%20%E3%83%9E%E3%83%AB%E3%83%81%E3%83%86%E3%83%8A%E3%83%B3%E3%82%B7%E3%83%BC,-%E3%83%86%E3%83%8A%E3%83%B3%E3%83%88%E3%81%AF%E3%80%81%E3%82%A4%E3%83%B3%E3%83%87%E3%83%83%E3%82%AF%E3%82%B9)には以下のようにあります。
>テナントは、インデックスパターン、可視化、ダッシュボード、その他の Dashboards オブジェクトを保存するための領域です。Dashboards マルチテナンシーを使用すると、他の Dashboards ユーザーと作業を安全に共有できます (プライベートに保持できます)。どのロールがテナントにアクセスできるか、それらのロールに読み取りアクセスがあるか書き込みアクセスがあるかを制御できます。グローバルテナントがデフォルトです。詳細については、「OpenSearch Dashboards マルチテナンシー」を参照してください。

つまり、ダッシュボードなどのオブジェクトを分けて管理するときの単位ということになります。
図中だと、tenantAには棒グラフのダッシュボード、tenantBには円グラフのダッシュボードが分けて配置されていますね。

## テナントとロールの関係性は？
テナントに関係するのは、ダッシュボードのオブジェクトと**ロール**です。
逆に、Backend rolesやInternal usersはテナントに紐づけられません。
そのため、テナントごとにロールを作成して、それをBackend rolesと紐づけます。

その際、図の`Role_all`のように、1つのロールを複数のテナントと紐づけることも可能です。
ただ、これをやりすぎると管理が煩雑になるため、管理者権限用のロールだけにしておくことをお勧めします。

## なぜBackend rolesを介して紐づけるのか？
Backend rolesを介するということは、ユーザーとロールを直接依存関係にさせないということです。
これにより、以下のようなメリットがあります。
- ユーザーグループごとの権限が変わった場合、Backend rolesを変更すればよい。
    - もし直接Internal usersを紐づけていた場合は、**その人数分の権限を変更する**必要があります。
    - 図中にはないですが、Backend rolesから複数のRolesを紐づけることも可能です。
- Internal usersを作成するときに、Rolesのことを考えなくてよい。
    - Internal usersを作成するときは、Backend rolesを指定すればよいので、どのRolesを紐づけるか考える必要がありません。
    - そのため、**ユーザー作成の運用負担が軽減**されます。
- IdPとの統合が容易になる。
    - IdPを利用する場合は、Backend rolesを介する必要があります。
    - その際、既に権限が設定されているBackend roleが存在すれば、Internal usersと**同じように権限管理**ができます。
    - 直接紐づいていた場合、Internal usersとIdPで別々にロールを設定しなければなりません。

# おわりに
タイトルのよりも少し広い概念から記載してしまいましたが、具体的な操作の方法というよりは概念的なお話ができて良かったかなと思います。
ただ、最近話題のOpensearch Serverlessでは、ダッシュボードのサインイン方法が[「Sign in with your access key and secret key.」](https://docs.aws.amazon.com/ja_jp/opensearch-service/latest/developerguide/serverless-overview.html#serverless-comparison:~:text=Sign%20in%20with%20your%20access%20key%20and%20secret%20key.)とのことなので、Internal usersは使わなくなっていくのかもしれません。

一方で、従来のOpenSearchのクラスタ構築ではこのロールとユーザーの紐づけはかなり使うところだと思うので、今後もこの認証認可周りのところは試していきたいと思います。
特に、Cognito連携やIdP連携は実際に触ってみたいですね。
それでは！