BigQueryを活用することで、毎日楽しいデータ生活を送れていますが、データを扱うところでは楽しいだけではやっていけません。個人であれば公開するのも良いでしょうが、企業となればやはり厳重に管理するものです。
そこで今回は、BigQueryではどのようにデータを守ることができるのか?そのあたりを書いていきたいと思います。
※注:本記事は旧UIで解説となりますこと、ご了承ください。
1.BigQueryでの機能
BigQueryではデータを守るために以下のような機能が備わっています。
これらを順に解説していきます。
アクセス権の設定
以下の単位できめ細やかにアクセス権を設定することができます。
- データセット
- テーブル
- 列
- 行(AuthorizedView)
制御しながらデータを見せる
アクセス権とは違い、クエリの結果しか見せない、暗号化してしまうということもできます。
- AuthorizedView
- 暗号化関数
監査ログ
誰がいつ、どこで、何をしたかの監査ログを取ることができます。
- Cloud Logging(今回はこちらに関して触れませんが、とても大事なことです)
2.アクセス権の設定
さまざまな単位でアクセス権を設定できますが、実際の企業では人のアカウントごとに設定していては大変です。そんなときは、Google GroupやGoogle Workspaceのドメインなど、グループごとに割り当てるのが良いかと思います。
データのアクセス権とジョブ(クエリ)の設定について
アクセス権の設定の前に、この件を先に触れます。
BigQueryでは、データにアクセスする権限と、ジョブ(クエリ)を発行する権限が明確に分かれています。前者はBigQueryでデータセットやテーブルに対して付与します。後者はIAMでプロジェクトに対して付与します。
最初のうちは、この点を理解しきれず、「アクセスできない」とか「クエリできない」と悩んだものです。しかし、一度わかると非常に理にかなった機能の分離だと思います。
とても理解しやすいのは、Googleが当初から用意している "bigquery-public-data" です。GCPを契約した人、全員のアクセス権を登録しているわけではないです。誰でもアクセスできる = 公開しているというわけです。では、ここでのクエリ課金はどういう仕組みになっているでしょうか? もちろん、自分が権限を与えられたプロジェクト(複数指定可)に課金されるわけです。
つまり、一部のデータだけを社外の取引先に公開して、『みたいだけ見ていいよ。ただ、クエリ課金はあなたのプロジェクトでお願いね!』といういうことができるのです。CSVでのダウンロードやAPIでのデータ取得ではなく、BigQueryでデータを共有したからそこを見てね!と。あとはご自身自身に必要なかたちで加工や表示ができる。というようになります。
ロールについて
ユーザーに対してプロジェクトとBigQueryに、ロールというものを割り当てていきます。ロールとは色々な権限がまとまってセットされているものです。GCPコンソールの "IAMと管理 → ロール" で確認してみてください。さまざまな権限が割り当てられています。
デフォルトでパターンがいくつか用意されています。もちろん自分でも作ることができます。
プロジェクト(IAM)でユーザーに割り当てるもの
- BigQueryジョブユーザー
- 設定されたプロジェクトのBigQueryでジョブ(クエリ)を発行することができます。つまり、どこのデータを見ようが、ここで設定されたプロジェクトに課金されます。クエリを発行する人には設定してあげましょう。
- 設定されたプロジェクトのBigQueryでジョブ(クエリ)を発行することができます。つまり、どこのデータを見ようが、ここで設定されたプロジェクトに課金されます。クエリを発行する人には設定してあげましょう。
- BigQueryユーザー
- 上記に加え、設定されたプロジェクトのBigQueryのデータセットやテーブルの一覧、データは見れませんが設定されている情報を見ることができます。しかし、BigQuery Storage API経由ではデータを取得することができます。
- 上記に加え、設定されたプロジェクトのBigQueryのデータセットやテーブルの一覧、データは見れませんが設定されている情報を見ることができます。しかし、BigQuery Storage API経由ではデータを取得することができます。
- BigQuery管理者
- BigQueryに対して何でもできるようになるため、管理者にだけ割り当てましょう。
- BigQueryに対して何でもできるようになるため、管理者にだけ割り当てましょう。
BigQuery(データセット・テーブル)でユーザーに割り当てるもの
- BigQueryデータ閲覧者
- 設定されたデータセットやテーブルのデータ・メタデータを閲覧することができます。スケジュールされたクエリも見れます。データセットに付与されている場合は、その中のテーブルの一覧も閲覧することができます。データを見る人にはこれだけで十分だと思います。
- 設定されたデータセットやテーブルのデータ・メタデータを閲覧することができます。スケジュールされたクエリも見れます。データセットに付与されている場合は、その中のテーブルの一覧も閲覧することができます。データを見る人にはこれだけで十分だと思います。
- BigQueryデータ編集者
- 上記に加えて、テーブルやデータの作成・更新・削除、タグ付けなどが行えます。スケジュールされたクエリも作成できます。データを入れ込んだり、編集したり、スケジュールクエリをセットしたりする人にはこれが必要です。
- 上記に加えて、テーブルやデータの作成・更新・削除、タグ付けなどが行えます。スケジュールされたクエリも作成できます。データを入れ込んだり、編集したり、スケジュールクエリをセットしたりする人にはこれが必要です。
- BigQueryデータオーナー
- 上記に加えて、共有設定やデータセットの削除が行えます。データの管理者に対して付与します。
- 上記に加えて、共有設定やデータセットの削除が行えます。データの管理者に対して付与します。
その他(カスタムロール)
ロールを自分で作ることも可能です。例えば、データをロードするだけのバッチをサービスアカウントで運用したとします。それに対してBigQueryデータ編集者を割り当ててしまうと、データの読み込み権限まで与えられているので、そのサービスアカウントを使っていたずらされる可能性がありますよね?
じゃ、どうすれば良いかというとデータをロードするだけの最小限の権限をロールで設定し、付与すればデータを見られる心配はありません。
このようにきめ細かに設定することも可能です。
データセットとテーブル
ユーザーに対してデータセットへ権限を付与した場合は、その配下のテーブルへも同様の権限が継承されます。
しかし、その中でもあるテーブルだけは編集権限を持たせたいといった場合は、そのテーブルだけに対してBigQueryデータ編集者を付与すれば実現できます。
テーブルだけに付与すれば、そのテーブルしか見ることができません。データセットすら見れないし、その中のテーブル一覧も見えません。
データセットに対して付与した場合
このようなかたちで見えます。
テーブルに付与した場合
データセットに対する権限を外して、このうちの "product_master" だけに権限を付与してみたいと思います。
はい、何も見えません。データセットすら見えませんね。
しかし、共有されたテーブルにクエリを発行するときちんと結果が表示されます。
データセットには閲覧権限を、テーブルには編集権限を
では、データセットには閲覧権限を付与しますが、あわせて "product_master" のみに編集権限を付与してみましょう。
まずは "product_master" で、updateが実行できるか確認してみましょう。
残念ながら権限がないと言われて、updateすることができませんでしたね。
このように、あるテーブルのみ編集権限を付与するなど柔軟に設定することができます。どんなときに使うの?ってよく聞かれますが、あるキャンペーンの商品一覧(5,000点あるなど)だけを抽出したいなどという場合に、自由にテーブルの中のデータを操れるようにするために使ったりします。
列について
列ごとに権限を付与することができます。例えば、テーブル内の仕入れ情報は見せたくない、個人情報は見せたくないなどさまざまにあると思います。
これは、Data Catalogのポリシータグを利用して設定することが可能です。こちらは手順を交えて説明します。
ポリシータグの一覧画面
GCPのコンソールからData Catalogの画面に遷移して、ポリシータグの一覧を表示します。
ポリシータグの作成
一覧画面から作成をクリックします。
分類名や説明、ポリシータグ(分類について複数設定可)を入力して保存をクリックします。
作成した分類の内容が表示されます。
アクセス制御の適用をオンにすると、BigQueryでこのタグを設定した列はアクセスすることができなくなります。
ひとまずオンにしてみましょう。
BigQueryの列に適用
テーブルのスキーマ編集画面で適用したいフィールド名(列名)を選択して、ポリシータグを追加をクリックします。
先ほどData Catalogで設定したポリシータグが表示されますので、設定したいものを選んで、ページ下部の選択ボタンをクリックします。
スキーマ編集画面に戻るので保存をクリックしてください。(この作業は特に皆さん忘れがちです)
するとポリシータグに追加されているのがわかります。なお、設定した本人(管理者でも)もいきなり見れなくなりますのでご注意ください。
テーブルのプレビューでも表示されません。
見れるようにするには?
Data Catalogのポリシータグで権限を付与するユーザーを設定します。
まずは付与するタグにチェックを入れます。するとユーザーを追加するメニューが表示されますので、メンバーを追加をクリックします。
新しいメンバーに閲覧を許可するユーザーのメールアドレスを入力します。
ロールの設定でデータカタログ→きめ細かい読み取りを設定、保存をクリックします。(この作業も忘れがちのためご注意ください)
すると、設定したユーザーはアラートなど出ずにデータを見ることができます。
制御しながらデータを見せる
合計はOKだけど生データは見せたくない、そもそも持っているデータ自体を暗号化したいなどのご要望があると思います。ここではそのあたりを解説していきます。
AuthorizedView
Viewとはあらかじめ設定したクエリの結果をテーブルのように見せる仕組みです。
AuthorizedViewでは、そのViewに対してデータの閲覧権限を設定します。よって、そのViewの閲覧権限をユーザーに付与すればデータも見れるということになります。
SELECT
re.product_code ,
ma.product_name ,
ma.company_name ,
sum(re.qty),
sum(re.price * qty)
FROM
`project-data-share.acl_data.product_receipt` as re
JOIN
`project-data-share.acl_data.product_master` as ma
ON
re.product_code = ma.product_code
JOIN
`project-data-share.acl_data.company_master` as com
ON
ma.company_name = com.company_name
WHERE
SESSION_USER() = com.email
GROUP BY
re.product_code,
ma.product_name ,
ma.company_name
例えば、商品ごとに集計したこのようなクエリをViewにして、view_datasetという違うデータセットに保存します。
そして、この元のデータが入っているデータセットの「承認済みビューの共有」で、このViewを選択して追加をクリック。下の完了ボタンをクリックします。
では、データセットに権限をセットしてきましたが、削除してみて生データが入っているテーブルにクエリを発行してみましょう。
エラーになりましたね。権限ないのですから、当たり前ですね。
では、Viewを保存した方のデータセットに閲覧権限を付与して、そのViewに対してクエリを発行してみましょう。
できましたね!
このようにある一定の期間だけ見せたいとか、見せるデータを絞りたいとか、色々な使い方ができると思います。
部門ごとに見せるデータを分けるためにわざわざ新しいテーブルを作るよりも、こちらの方が効率的じゃないかなと思います。
行レベルでの権限
行レベルでの権限
このAuthorizedViewを利用して、クエリを発行したユーザー(メールアドレス)によって行レベルでデータを見せる、見せないの設定ができます。
先ほどは、すべての商品の合計を見ることができました。次は、ユーザーが持っている商品の合計のみを見せてみようと思います。
商品マスタは、このようなテーブルです。会社名が入っていますね。
会社のマスタにアクセスするユーザーの情報(メールアドレス)を付与したテーブルを準備します。Viewに設定するクエリは、下記のようになります。
SELECT
re.product_code ,
ma.product_name ,
ma.company_name ,
sum(re.qty),
sum(re.price * qty)
FROM
`project-data-share.acl_data.product_receipt` as re
JOIN
`project-data-share.acl_data.product_master` as ma
ON
re.product_code = ma.product_code
JOIN
`project-data-share.acl_data.company_master` as com
ON
ma.company_name = com.company_name
WHERE
SESSION_USER() = com.email
GROUP BY
re.product_code,
ma.product_name ,
ma.company_name
クエリ自体は長々となっていますが、何も難しいことはやっていません。ポイントは SESSION_USER() = com.email です。これが、いまアクセスしているユーザーの情報を取得して、その "email" でフィルタしているというものになります。
では、やってみましょう。
bq.acl.test@〜 は、"yy野菜" に設定されていたので、そこのデータしかみれていませんね。
なお、先ほど会社のメールアドレスも設定していたので、そちらも同様に行います。
きちんと "xx商事" がでました。大丈夫ですね。
このようなかたちで、ある特定のデータしか見せたくないなどの場合に便利に使えると思います。
でも、あくまでフィルタしているだけなので、課金は全部のデータに対してかかりますよ。このあたりは "clustered table" などを上手く使ってくださいね。
暗号化関数
BigQueryには暗号化関数が用意されています。それを用いて、データの暗号化と復号をやっていきましょう。まずは、"product_code" とそれに対応したkeyのデータを生成したテーブルを作成します。
CREATE OR REPLACE TABLE
`project-data-share.acl_data.product_key` AS
SELECT
product_code,
KEYS.NEW_KEYSET('AEAD_AES_GCM_256') AS keyset
FROM
`project-data-share.acl_data.product_master`
ここで作成したkeyを使って、そこから "product_master" の "company_name" を暗号化したテーブルを作成します。
CREATE OR REPLACE TABLE
`project-data-share.acl_data.enc_product_master` AS
SELECT
product_code,
product_name,
AEAD.ENCRYPT( (
SELECT
keyset
FROM
`project-data-share.acl_data.product_key` AS key
WHERE
key.product_code = ma.product_code),
ma.company_name,
ma.product_code) AS enc_com_name,
cost
FROM
`project-data-share.acl_data.product_master` AS ma
"company_name" が暗号化されましたね。では、これを復号してみましょう。暗号化したものと似ていますね。
SELECT
product_code,
product_name,
AEAD.DECRYPT_STRING( (
SELECT
keyset
FROM
`project-data-share.acl_data.product_key` AS key
WHERE
key.product_code = ma.product_code),
ma.enc_com_name,
ma.product_code) AS dec_com_name,
cost
FROM
`project-data-share.acl_data.enc_product_master` AS ma
このように、データとしては暗号化して持っているが、keyを使うことで復号できるというものです。
どのようなところで使うかというと、例えば個人の住所などもレコードで持っている場合、データは暗号化して保持しておく、必要なときに復号する、ある一定の期間後はkeyのレコードを削除して復号できないようにする、こうすることでレコード全体を削除やデータのアップデートをすることなく必要なデータだけを残しておくことができます。
3.最後に
いかがでしたしょうか?BigQueryには、さまざまなデータアクセスの権限があります。
要件や場面によって使い分けたり組み合わせたりすることで、データをある程度は守ることができるかなと思います。
そのほか、データのダウンロードは?エクスポートは?監査は?などとも(Cloud LoggingやCloud Data Loss Prevention、Google Vault)と組み合わせることで、さらに強固なものにはできると思います。
(もちろん上記で提供される仕組みだけで万全というわけではありません。)
どうぞ、楽しく安心できるデータライフをお過ごしください。
※本ブログの内容や紹介するサービス・機能は、掲載時点の情報です。