BigQueryのアクセス制御をまとめてみた

# BigQueryのアクセス制御をまとめてみた
この記事は[セゾン情報システムズ Advent Calendar 2022](https://qiita.com/advent-calendar/2022/sisco) 5 日目の記事です。

## はじめに
Google Cloud Next 22 の「[データ活用から管理までを知るエキスパートが語る BigQuery 使いこなしの秘訣 〜初入門の方法からこれからのデータ基盤運用まで〜](https://cloud.withgoogle.com/next/catalog?session=HIVE102-JP&utm_source=copylink&utm_medium=social)」というセッションで、BigQuery の権限管理の話題があがりました。
（リンクの動画を見るには Google Cloud Next に登録必要があると思われます）
利用者の立場だと普段権限周りを意識しませんが、BigQuery では細かいアクセス制御を行うことができます。
この記事では BigQuery でできるアクセス制御をまとめました。

## 指定できるロール/権限について
BigQuery に関するロール/権限は、ドキュメントにまとまっています。

https://cloud.google.com/bigquery/docs/access-control?hl=ja

特定のユースケースを想定した事前定義ロールが用意されているのでそれを使うこともできますし、
任意の権限だけを付与したカスタムロールを作ることもできます。

## IAM をつかったアクセス制御
データセット、テーブル、ビューのレベルでアクセス制御が可能です。

データセットのアクセス制御は、データセット情報の「共有」→「権限」から管理できます。
![データセット情報ページ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426544/483a9ae4-022e-d4d8-d4da-c3c60e7ed48a.png)

権限一覧ではロール一覧が表示され、ロールを開くと紐づいているユーザーやサービスアカウントなどを確認できます。
![データセット権限の一覧.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426544/2015f8dd-e097-c26b-0bab-fb71fb4a01c5.png)


「プリンシパルの追加」では、プリンシパルと割り当てるロールの指定ができます。
IAM のプリンシパル追加と設定画面が似ているのでわかりやすいですね。
![データセット権限にプリンシパル追加.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426544/d82500f6-3a66-d38d-bc66-dc7f8a6ef11e.png)


テーブル/ビューの権限も、テーブル/ビュー情報の「共有」から管理できます。
![テーブル情報.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426544/f8ad6868-5210-d90e-3bf2-002364921032.png)


プリンシパルの一覧や追加のページは、データセットと同じでした。

## 認可によるアクセス制御
BigQuery には承認済みビューや承認済みデータセットといった、管理者が認可した制御があります。

### 承認済みビュー
BigQuery のビューとは、DBのビューと同じく、任意のテーブルから必要なデータのみを取得して作った仮想テーブルです。
ビューへのアクセスは、ソースとなったテーブルへのアクセス権限も必要になりますが、
承認済みビューを使うと、ソーステーブルへのアクセス権限がないユーザーでもアクセスできることができます。

#### 検証
チュートリアルを参考に、承認済みビューの作成と動作を確認しました。

https://cloud.google.com/bigquery/docs/share-access-views?hl=ja

管理者権限をもつアカウント（以降メインアカウント）とアクセス制御がかかるアカウント（以降サブアカウント）を用意し、メインアカウント側に1つのテーブルと2つのビューを作りました。

 - authorized_view：private_table から作ったビュー。後工程で承認済みビューに変更する。
 - private_table：ソーステーブル。
 - private_view：private_table から作ったビュー。

![テーブルとビュー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426544/571bc88b-8e87-4a02-138e-c8f1516f5399.png)


メインアカウントの「IAMと管理」→「IAM」→「アクセス権の付与」を開き、サブアカウントに、`BigQuery ユーザー` ロールを付与します。
![BigQueryユーザーロール追加.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426544/d4b8be2a-9d54-c5e2-e462-0c80df8d3acd.png)


この時点で、サブアカウントからテーブルやビューを見ようとすると、下記エラーが発生します。
```
Access Denied: Table :<PROJECT ID>:dataset.private_view: Permission bigquery.tables.get denied on table <PROJECT ID>:dataset.private_view (or it may not exist).
```

メインアカウントの BigQuery のページに戻ります。
サブアカウントに authorized_view, private_view の BigQuery データ閲覧者ロールを付与します。
![authorized_view権限追加.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426544/5754cf19-ccbc-ea85-0aba-d5ff436d0b1a.png)
![private_view権限追加.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426544/e4a36a35-e68e-a067-5d52-0b0603f64515.png)


データセット情報の「共有」→「ビューを承認」を開き、authorized_view のみ承認を追加します。
これで承認済みビューの作成は完了です。
![ビューの承認.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426544/a06de836-430c-e71f-8266-a00664ad42ab.png)

サブアカウントからどう見えるのかを確認します。
まず authorized_view を確認します。
ビューの情報を見ることができ、authorized_view に対してクエリも実行できました。
![image (8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426544/2c05670d-ff1a-910b-d7ce-293e3fb7e7e8.png)
![image (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426544/469feee4-dc6f-66be-a6df-e82f19eb6974.png)

次に private_view を見てみます。
private_view もビューの情報はみることができました。
![image (10).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426544/c15c1331-b767-595d-d034-8517dcf249b9.png)


しかし、private_view に対してクエリを実行しようとすると、エラーが発生し失敗しました。
```
Access Denied: Table <PROJECT ID>:dataset.private_table: User does not have permission to query table <PROJECT ID>:dataset.private_table, or perhaps it does not exist in location asia-northeast1.
```

![image (11).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426544/3d66f750-1cad-9b6e-0ea4-536f1854c640.png)


### 承認済みデータセット
承認済みビューとして扱いたいビューデータが複数ある場合、ビューごとに権限付与や承認をするのは手間になります。
データセットにビューを集約し、そのデータセットを承認済みデータセットにすることで、データセット内のすべてのビューが承認済みとなります。

## 参考ドキュメント
https://cloud.google.com/bigquery/docs/control-access-to-resources-iam?hl=ja

https://cloud.google.com/bigquery/docs/table-access-controls?hl=ja

https://cloud.google.com/bigquery/docs/table-access-controls-intro?hl=ja#authorized_views

https://blog.g-gen.co.jp/entry/bigquery-authorized-view-and-dataset


以上です。誰かの参考になれば幸いです。