QuickSightで行レベルアクセス制御を行う手順

以下の投稿の続きです。

https://qiita.com/moritalous/items/f8290f710233efad80b7

---

マルチテナント型のアプリケーションの場合に、一つのテーブルに登録されているデータを、企業や組織ごとにアクセス制御したいことってありますよね。

QuickSightでこのようなアクセス制御を行う方法として、行レベルのセキュリティ機能があります。[参考ドキュメント](https://docs.aws.amazon.com/ja_jp/quicksight/latest/user/row-level-security.html)

QuickSightには[匿名埋め込み機能](https://docs.aws.amazon.com/ja_jp/quicksight/latest/user/embedded-analytics-dashboards-for-everyone.html)というものがあり、QuickSightにユーザー登録をしなくても、ダッシュボードを表示するための一時URLを発行することができます。

匿名埋め込み機能と行レベルのセキュリティ機能を組み合わせることで、自前アプリケーションにQuickSightのダッシュボードを適切な権限制御を行いながら埋め込むことが可能になります。


[前回の投稿（QuickSightでVPC内のAuroraに接続する環境をCDKで構築する手順）](https://qiita.com/moritalous/items/f8290f710233efad80b7)で作成したQuickSightとAuroraの構成を使って、行レベルのセキュリティを試してみました。

:::note
匿名埋め込み機能を使用するには、QuickSightのサブスクリプションを`リーダーあたりの料金`から`セッションキャパシティの料金`に変更する必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/4cef63e1-0981-27ec-7b2c-3a193e9cb16e.png)

:::

## データセットに行レベルアクセス制御を追加する

### 1. データセット一覧画面を表示
![Screen Shot 2023-03-25 at 14.38.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/3ec1053f-750a-492d-aba7-711312c2e54d.png)

### 2. データセットを選択し、`行レベルのセキュリティ`の`設定`をクリック
![Screen Shot 2023-03-25 at 14.38.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/aa152f9d-787d-9c38-5f74-5ea3ad5c1422.png)

### 3. `タグベースのルール`を設定

`ユーザーベースのルール`と、`タグベースのルール`がありますので、`タグベースのルール`を選択します。
![Screen Shot 2023-03-25 at 14.38.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/19a88aba-3c0c-d83e-9589-77b5570cd771.png)

`列`は実際のテーブルの列名で`タグ`はAPIで呼び出す際のタグ名です。
`すべて一致`は、タグの値がこの値の場合に`select *`相当の動作となります。（タグの値を*や''にしてもこの動作にはなりません。）
![Screen Shot 2023-03-25 at 14.38.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/a69cda6b-a2c8-3cda-5c7e-21769d10b022.png)

### 5. ルールを有効化
![Screen Shot 2023-03-25 at 14.39.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/8223370a-dbe3-9e28-9c61-9487b01cc98f.png)

右側のチェックボックスがオンになります。
![Screen Shot 2023-03-25 at 14.39.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/c7977f07-e0be-903c-3f8b-c5754e13e3ae.png)


## 埋め込みURLを発行する 

AWS CLIで匿名アクセス用のURLを発行します。

group1のデータだけが閲覧できるよう`--session-tags`を設定しています。

```shell
aws quicksight generate-embed-url-for-anonymous-user \
  --aws-account-id 754291963749 \
  --namespace default \
  --authorized-resource-arns arn:aws:quicksight:ap-northeast-1:754291963749:dashboard/bb9902f8-d8eb-4182-a6cb-11a35af05956 \
  --experience-configuration '{"Dashboard":{"InitialDashboardId":"bb9902f8-d8eb-4182-a6cb-11a35af05956"}}' \
  --session-tags '{"Key":"group_tag", "Value": "group1"}'
```

レスポンス

```shell
{
    "Status": 200,
    "EmbedUrl": "https://ap-northeast-1.quicksight.aws.amazon.com/embed/a080a360de4f476e8c2be48dd35d0a3f/dashboards/bb9902f8-d8eb-4182-a6cb-11a35af05956?code=AYABeDAfj8Fb0N5iC6JKhyBSZ3gAAAABAAdhd3Mta21zAFBhcm46YXdzOmttczphcC1ub3J0aGVhc3QtMTozNjcwOTQ1NjE4OTQ6a2V5LzkyZDU3MjEzLTc0MjItNGNhOC1iYWZiLTg2MDFjNGZkODgyNwC4AQIBAHgeDGL3XAnX5chwrubXLtqmn-xwPT7Th-AyeZ72nfHdvwGr5O_l6Ygj8thbDymMa0DJAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMmdMA3nNlMVJpvO-eAgEQgDvEtqszA2zLpFveyPxRdBBL_HYma-HJsC0zliKS_JyKIgvS8vSpRGAR6jMm61j-gMxDuFpQPDa3XFC2iQIAAAAADAAAEAAAAAAAAAAAAAAAAABhccQB36YnmgqNelMh0sh2_____wAAAAEAAAAAAAAAAAAAAAEAAACbRj35gF6A5SiKA_Qu3Guj1h6ncVUI5mzBN6YGrUqO3a6EjlnTmi2cIGEogmcv-fgMFIyX6Jq-oHUytRIU03eA9BYo5apu75RyiX2MuyoZJ9DPilgXn_9NBCxkPDgHamKSWtag6w3zxgqSGcH7ZKt_FIHozSBuK3Fm15DSzLQIEWn7Oonm1gC7MyGUgWzsyaIUIObAioZiNP0jMLoiS0n5bFbS2iE8nZrpHBmK&identityprovider=quicksight&isauthcode=true",
    "RequestId": "0702dbdb-0145-443e-8891-3a157218f379",
    "AnonymousUserArn": "arn:aws:quicksight:ap-northeast-1:754291963749:anonymousUser/default/a2450b6ddc564e1ea1303177c6c72d8a"
}
```

発行されたURLにブラウザでアクセスします。想定通り、group1の値だけが表示されます。
![Screen Shot 2023-03-25 at 14.52.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/e8f46291-f373-284d-8288-7e23bc04f4e3.png)

`--session-tags '{"Key":"group_tag", "Value": "All"}'`の場合は、すべてのデータにアクセスができます。
![Screen Shot 2023-03-25 at 22.24.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/1c01e482-8ef9-da05-0acf-337f7c1f2652.png)

* 試しにValueを`*`にしてみましたが、この場合はどの行にもアクセスできていません。（アクセスできていないのかデータが無いのかは、判別が付きません）

![Screen Shot 2023-03-25 at 22.25.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/83a08160-36e5-9de5-c6a3-160d1248aa2f.png)

## QuickSight作成者がデータセットにアクセスできるように設定

ここまでの手順で`タグベースのルール`を有効化すると、QuickSightに管理者や作成者として登録しているユーザーもアクセス制御の対象となり、ダッシュボードを表示してもこの様になってしまいます。

![Screen Shot 2023-03-25 at 14.39.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/fa111e42-d238-b4d8-4e10-bf6096dd1913.png)

これではダッシュボードを作成できないので困ってしまいますが、`ユーザーベースのルール`を組み合わせることで、ダッシュボード作成者に表示させるデータの権限制御が可能です。[参考ドキュメント](https://docs.aws.amazon.com/ja_jp/quicksight/latest/user/restrict-access-to-a-data-set-using-row-level-security.html)

### 1. アクセス許可データセットを作成

誰がアクセスしていいかの情報はデータセットとして用意します。（CSV形式やデータベースを使うかは問いません）今回は、Aurora内のテーブルとして用意しました。

列名は`UserName`、`GroupName`と、`制御したいカラム名`です。

```sql
CREATE TABLE user_master (
    UserName VARCHAR,
    GroupName VARCHAR,
    group_name VARCHAR
);
```

データとしては以下を登録します。

| username | groupname | group_name |
|----------|-----------|------------|
| NULL     | Admin     | NULL       |
| NULL     | Group2    | group2     |
| Group1   | NULL      | group1     |


:::note
`ユーザーベースのルール`は、`タグベースのルール`と異なり、`ユーザーまたはグループにルールを追加し、他のすべての列を値なし (NULL) のままにすると、すべてのデータへのアクセスが付与されます。`という仕様があるため、Adminグループに所属するユーザーはすべてのデータにアクセスが可能となります。
:::

### 2. QuickSightのグループを作成

ユーザーごとに制御もできますが、一般的にはグループを使用することになると思います。

QuickSight管理画面からグループの管理を行います。
![Screen Shot 2023-03-26 at 17.03.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/7b9fb21c-53eb-1797-6a97-5f73ad46d7ad.png)

Adminグループにユーザーを追加します。
![Screen Shot 2023-03-26 at 17.03.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/5b3b327a-71dc-74cc-8439-6867800f8101.png)

### 3. `user_master`テーブルを、データセットとして登録

通常の手順でデータセットを登録します。

![Screen Shot 2023-03-26 at 17.12.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/cb7b2d63-91a8-1494-7ca9-552077da442d.png)

### 4. `行レベルのセキュリティ`の`設定`を追加

対象のデータセットの`行レベルのセキュリティ`の`設定`をクリックします。

![Screen Shot 2023-03-25 at 14.38.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/aa152f9d-787d-9c38-5f74-5ea3ad5c1422.png)

`ユーザーベースのルール`をの中から、`user_master`データセットを選択します。

![Screen Shot 2023-03-26 at 17.13.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/62913163-849d-6cdc-4aca-ba239dbdc601.png)

### 5. ルールを有効化

![Screen Shot 2023-03-26 at 17.14.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/eb451e03-501e-7350-7b23-518681a6683f.png)


### 動作確認

* グループの所属していない場合
![Screen Shot 2023-03-26 at 17.22.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/402592d5-84e2-f1db-be9f-79c4ef3d00d3.png)

* `Admin`グループの所属している場合（全データが閲覧可能）
![Screen Shot 2023-03-26 at 17.14.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/aed8791f-f842-1211-d862-6bde3da09bf3.png)

* `Group2`グループに所属している場合（group2のデータだけ閲覧可能）
![Screen Shot 2023-03-26 at 17.16.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/955714f4-6133-ab0b-4848-1bde314723ba.png)

想定通りの動作ですね。