BigQueryの承認済みビュー機能を利用した権限制御について

## はじめに

初めまして。 京セラコミュニケーションシステム 小島([@kccs_daichi_kojima](https://qiita.com/kccs_daichi-kojima)）です。  
BigQueryを利用してデータ分析を行う際、ユーザやネットワークによって、クエリを実行できるテーブル（ビュー）やデータセットを分ける必要がでてくることがあります。  
本記事では、BigQueryの承認済みビュー機能を用いた権限制御について解説します。

:::note info
本記事は 2022 年 12 月ごろに作成しております。
Google Cloud の機能を利用した場合は、利用料が発生します。
:::
## この記事の対象者

- BigQueryの権限制御方法を知りたい方。　
- BigQueryでビューやデータセット単位で権限制御を行いたい方。


## 承認済みビューとは？
承認済みビュー機能を利用することで、特定のデータセットから任意のビューに対してクエリ実行の許可をすることが可能です。  
### 利用するメリット
データセットの権限を持っていないユーザも承認されたビューを介すことで対象データセット対してクエリを実行することが可能になります。

![承認済みビュー説明](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984267/d4e0acf6-fc9c-d08c-8657-96f12c4d9410.png)

今回はビュー単位の承認を行いますが、クエリを実行できる列（フィールド）の制御もできるようですので、詳細が気になる方は[公式ページ](https://cloud.google.com/bigquery/docs/authorized-views?hl=ja)を参照ください！

## 利用例
ココからはBigQueryの承認済ビュー機能について実際に設定を行って解説します。  
データセットを2つ作成し、ユーザ権限と承認済みビュー有無での挙動の違いを見ていきましょう。
### BigQuery データセット・テーブル・ビュー作成

テスト用のデータセットを2つ作成します。  
![データセット作成](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984267/db6352c4-ebda-22d3-ec96-5881783fb3c6.png)

test_01データセットにはテーブルを、  
test_02データセットにはtest_01データセットに作成されたテーブルを参照するビューを作成します。  
test_01データセットに作成するテーブルは[コチラ](https://www.mhlw.go.jp/stf/covid-19/open-data.html)のオープンデータ、「新規陽性者数の推移（日別）」のCSVをインポートします。

![テーブル作成](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984267/77de3f42-fd39-781a-2acf-1a66989d43cd.png)
作成されたテーブルは都道府県ごとの感染者数が日付単位で保管されてます。
![テーブルプレビュー（抜粋）](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984267/1bd34ea4-2533-cbc9-d27d-a9f92409d007.png)

test_02データセットに作成するビューはDateとTokyoの列を指定したクエリで作成しておきます。

![ビュー作成](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984267/3881aece-277e-f601-a6ac-ebccdad6e14b.png)
```sql:view_sql
SELECT date,Tokyo FROM 
`{プロジェクトID}.test_01.test_01_table` 
LIMIT 1000
```
### ビューとテーブルにクエリを実行してみる。
権限が異なるIAMを2つ用意し、挙動を確認していきます。

| パターン | IAM権限 | クエリ実行先 |
| :-: | :-: | :-: |
| ① | BigQuery管理者(プロジェクト) | テーブル（test_01_table） |
| ② | BigQuery管理者(プロジェクト) | ビュー（test_02_view） |
| ③ | BigQuery ジョブユーザー(プロジェクト)/BigQueryデータ閲覧者（test_02データセット） | テーブル（test_01_table） |
| ④ | BigQuery ジョブユーザー(プロジェクト)/BigQueryデータ閲覧者（test_02データセット） | ビュー（test_02_view） |

:::note info
リソース（データセット）を限定した権限付与はBigQueryのデータセットを選択し、「共有」から行えます。
:::
#### パターン①,②
IAMで権限がすべてある為、どちらも問題なく実行できます。
![パターン①,②実行結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984267/ac73455a-0135-570d-d0cb-1ea91621b613.png)
#### パターン③,④
test_01データセットの権限を与えていない為、クエリはエラーとなります。  
（ビューの実行も実態はtest_01_tableを参照している為同じ挙動）
![パターン③,④実行結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984267/2fe38d20-da3f-2136-60b7-cebee21a46e4.png)
```log:error
Access Denied: Table {プロジェクトID}:test_01.test_01_table: User does not have permission to query table {プロジェクトID}:test_01.test_01_table, or perhaps it does not exist in location asia-northeast1.
```

パターン③、④のIAM権限はtest_02データセットのみ閲覧できれば良いですが、  
そこにあるビューも実行できないのでは、分析が行えません。。。  
しかし、パターン③、④のIAMへtest_01データセットやtest_01_tableに対して権限を与えると、不要なデータも参照することが可能になってしまい、セキュリティを担保できません。

:::note info
ここでいう**不要なデータ**はビューで閲覧できるdateとTokyoの列以外の列のデータをさします。  
:::

### 承認済みビュー設定
ここで、今回の記事で紹介する承認済みビュー設定を行います。
test_01データセットからビューを承認します。
![承認済みビュー設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984267/bf31588c-6bd5-57b8-e529-779aa59fbfc6.png)

### 再度ビューとテーブルにクエリを実行
パターン③と④を再度実行してみます。
#### パターン③
test_01の権限を与えていない為、クエリは引き続きエラーとなります。
![パターン③再実行結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984267/2fe38d20-da3f-2136-60b7-cebee21a46e4.png)
#### パターン④
IAMの権限は変えてませんが、ビューを承認したためコチラは参照することができました！
![パターン④再実行結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984267/be02f8d9-df44-b5d9-d376-d4882e93ea3d.png)
テーブルの参照は出来ず、ビューの参照は行えました。  
ビューのクエリで参照する列を絞っている為、テーブルに存在する別の列のデータは参照させず必要なデータだけ閲覧させることができました。
## おわりに
本記事では、BigQueryの承認済みビュー機能を利用して、IAMに権限がなくてもビュー経由でtableを参照しました。  
ビューのクエリで対象を絞ることで、閲覧する項目も絞ることが可能な為、必要なデータのみを閲覧させることが可能です。  
ユースケースの例としては、  
機密情報を扱っている案件などで機密情報を閲覧できるユーザとできないユーザがいる場合に、  
機密情報を保管しているテーブルから機密情報を除外してビューを作成して承認済みビュー設定を行うことで、機密情報を閲覧できないユーザはビューで分析を行うことが可能です！  
今回利用した承認済みビューと似た機能で[承認済みデータセット](https://cloud.google.com/bigquery/docs/authorized-datasets?hl=ja)機能もあります。  
ビュー単位ではなくデータセット単位で権限付与が可能な為、要件によって使い分けると簡潔に権限の付与が可能になると思います！