BigQueryの利用ユーザに個別のデータセットやテーブルへのアクセス制御をしてみた(Cloud Shell編)

BigQueryの利用ユーザに対して許可したデータセット/テーブルのみを表示させてアクセスさせるための設定を、少ない権限で実現するための方法。
2023.11.10

BigQueryを利用する際、特定のデータセットやテーブルへのアクセスを利用ユーザに制限したい場合はどうすればよいでしょうか?

先日、Cloud Consoleを利用して、BigQueryの利用ユーザに対して許可したデータセット/テーブルのみを表示させてアクセスさせるための設定を少ない権限で実現するための方法について記しました。

この記事では、Cloud ConsoleによるGUIでの操作ではなく、Cloud Shellを利用して同様のアクセス制御をCLIで実現する方法について記述します。

検証の前提条件と準備

  • 検証の前提条件と必要準備作業、検証パターンについてはこちらに記載していますのでまずはご参照ください。

  • Cloud Shellを利用して検証を行います。

本検証を実施するにあたり参照したドキュメント

データセットへのアクセスの制御  |  BigQuery  |  Google Cloud

テーブルおよびビューへのアクセスの制御  |  BigQuery  |  Google Cloud

BigQuery での IAM の概要  |  Google Cloud

IAM を使用してリソースへのアクセスを制御する  |  Google Cloud

bq コマンドライン ツール リファレンス  |  Google Cloud

検証パターン1

検証パターン1ではユーザに対して以下のアクセス制御を実現します。

  • 許可したデータセットのみ表示させる
  • 許可したテーブルのみアクセスできる
  • 許可したテーブルに対してジョブの実行ができる

パターン1 ①プロジェクトに対するアクセス権付与

「管理者」アカウントにてCloud Consoleにログインし、Cloud Shellを起動します。

「ユーザ」xxxx@yyyy.com に、BigQueryジョブユーザー(roles/bigquery.jobUser)を付与します。

gcloud projects add-iam-policy-binding ProjectID --member=user:xxxx@yyyy.com --role=roles/bigquery.jobUser
bindings:
- members:
  - user:xxxx@yyyy.com
  role: roles/bigquery.jobUser

実行結果より、userに設定したroleが割り当てられていることを確認します。


※コマンド/オプションの補足

projects
プロジェクト操作のためのgcloudサブコマンド。

add-iam-policy-binding ProjectID
IAMポリシーの追加のためのコマンド。ProjectIDを指定する。

--member=
プリンシパルを指定する。ユーザを指定する場合は、user:メールアドレスとする。

--role=
ロールを指定する。ロールはroles/ロール名で指定。


パターン1 ②特定のデータセットに対するアクセス権付与

以下コマンドでデータセットを確認します。

bq ls --datasets=true
  datasetId  
 ----------- 
  dataset_1  
  dataset_2


※コマンド/オプションの補足
bq
BigQueryを操作・管理するためのコマンド。
bqコマンドは以下の構文で実行する。

bq COMMAND [FLAGS] [ARGUMENTS]
[FLAGS]の指定にはブール値をとるものがあり、--FLAGNAME==true または false のように指定する。

ls
データセットなどの情報を一覧表示するためのコマンド。

--datasets=true
データセットを一覧表示する。


ここでは対象プロジェクト配下のデータセットである「dataset_1」にのみアクセス権を付与し、「dataset_2」にはアクセス権を付与しないこととします。

まずは「dataset_1」のリソースに関する情報を、ローカルのjsonファイル(以下dataset1.jsonとしました)に出力します。

bq show --format=prettyjson ProjectID:dataset_1 > dataset1.json


※コマンド/オプションの補足
show
リソースに関する情報を表示するためのコマンド。 ProjectID:データセット名を指定する。

--format= 出力結果のフォーマットを指定。prettyjsonは可読性のあるJSON形式での出力。


dataset1.jsonに出力されたアクセス権限に関わる設定項目をvim等で編集します。

vim dataset1.json

以下のようにaccessセクションに追加したいロールとユーザの情報を加えます。

{
  "access": [
    {
      "role": "WRITER",
      "specialGroup": "projectWriters"
    },
    {
      "role": "OWNER",
      "specialGroup": "projectOwners"
    },
    {
      "role": "OWNER",
      "userByEmail": "aaaa@bbbb.jp"
    },
    {
      "role": "READER",
      "specialGroup": "projectReaders"
    },
    #以下を追加(上の行の末尾に","の追記も忘れずに)
    {
      "role": "roles/bigquery.user",
      "userByEmail": "xxxx@yyyy.com"
    }
  ],


※設定の補足
"role":
付与するロールを指定する。

"userByEmail":
権限付与対象のユーザのメールアドレスを指定する。
ほかにgroupByEmaildomainが指定できる。

編集したdataset1.jsonのリソース情報を「dataset_1」に反映します。

bq update --source bqshow.json ProjectID:dataset_1


※コマンド/オプションの補足
update
リソースを変更するコマンド。

--source=
リソースの更新に使用されるローカルJSONファイルへのパスを指定。

※データセットに適用するroles/bigquery.userユーザーには以下の権限が含まれます。

  • データセットのメタデータへのアクセスと読み取り
  • データセット内のテーブルの一覧表示

roles/bigquery.userの最低適用対象はデータセットであり、データセット配下のテーブルには継承されません。最低適用対象がテーブルである roles/bigquery.dataViewer といったロールをデータセットに適用すると、データセット配下の全てのテーブルに継承されるため、個別のテーブルへのアクセス制御はできなくなります。


リソース情報が反映されたかを確認します。

bq show --format=prettyjson ProjectID:dataset_1

パターン1 ③特定のテーブルに対するアクセス権付与

以下コマンドでデータセットを確認します。

$ bq ls ProjectID:dataset_1
  tableId   Type    Labels   Time Partitioning   Clustered Fields  
 --------- ------- -------- ------------------- ------------------ 
  table_1   TABLE                                                  
  table_2   TABLE


※コマンド/オプションの補足
bq lsにProjectID:データセット名を指定するとテーブルのリストが一覧表示されます。

ここでは「table_1」にのみアクセス権を付与し、「table_2」にはアクセス権を付与しないこととします。

bq add-iam-policy-binding --member=user:xxxx@yyyy.com \
  --role=roles/bigquery.dataViewer dataset_1.table_1


※コマンド/オプションの補足
add-iam-policy-binding
テーブルやビューのIAMポリシーを変更するコマンド。変更対象のテーブルはデータセット名.テーブル名で指定する。

--member=
プリンシパルを指定する。ユーザを指定する場合、user:メールアドレスとする。

--role=
ロールを指定する。ロールはroles/ロール名で指定。


パターン1 ユーザによるアクセス確認

「ユーザ」アカウントにてCloud Consoleにログインします。

[BigQuery] → [BigQuery Studio] → [エクスプローラ] を確認します。

データセットに関しては、roles/bigquery.userを付与された[dataset_1]のみ表示され、アクセス権限を付与されていない[dataset_2]は表示されません。

テーブルに関しては、roles/bigquery.dataViewerを付与された[table_1]が表示されました。

[table_1]に対してクエリの実行もできます。

アクセス権限を付与されていない[table_2]はツリー上に表示されますが、アクセス拒否されます。

検証パターン2

検証パターンではユーザに対して以下のアクセス制御を実現します。

  • 許可したテーブルのみアクセスできる
  • 許可したテーブルに対してジョブの実行ができる
  • データセットの情報にはアクセスさせない

パターン2 データセットからアクセス権限を削除

「管理者」アカウントにてCloud Consoleにログインし、Cloud Shellを起動します。

パターン1 が完了した状態で、対象プロジェクト配下のデータセットである「dataset_1」から「ユーザ」xxxx@yyyy.comのアクセス権限を削除します。

vim等でdataset1.jsonを編集します。

vim dataset1.json

dataset1.jsonからパターン1で追加したアクセス権限に関わる設定を削除します。

{
  "access": [
    {
      "role": "WRITER",
      "specialGroup": "projectWriters"
    },
    {
      "role": "OWNER",
      "specialGroup": "projectOwners"
    },
    {
      "role": "OWNER",
      "userByEmail": "aaaa@bbbb.jp"
    },
    {
      "role": "READER",
      "specialGroup": "projectReaders"
    }
    #以下4行を削除(上の行の末尾から","の削除も忘れずに)
    {
      "role": "roles/bigquery.user",
      "userByEmail": "xxxx@yyyy.com"
    }
  ],

編集したdataset1.jsonのリソース情報を「dataset_1」に反映します。

bq update --source bqshow.json ProjectID:dataset_1

リソース情報が反映されたかを確認します。

bq show --format=prettyjson ProjectID:dataset_1

パターン2 ユーザによるアクセス確認

「ユーザ」アカウントにてCloud Consoleにログインします。

[BigQuery] → [BigQuery Studio] → [エクスプローラ] を確認します。

パターン1で表示されていた「dataset_1」が表示されなくなりました。

[table_1]に対するアクセス権限は削除していないため、[table_1]のURLに直接アクセスすると、[table_1]の情報を表示することができます。

このとき、ツリー上に表示されなくなっていた[dataset_1]がツリー上に表示されましたが、[dataset_1]を選択するとアクセス拒否されることがわかります。

おわりに

BigQueryのデータセットやテーブルに対する具体的なアクセス制御がCLIコマンドによる設定でも実現できることを検証によって明らかにしました。本記事がBigQueryでのデータ管理をより安全に行う一助となれば幸いです。