はじめに:全員オーナーは危険です
BigQueryを一人で使っているうちは、権限のことを意識する場面はほとんどありません。自分のプロジェクトに自分がいるだけなので、何でもできて当然です。
ところが、チームでデータを触り始めると話が変わります。マーケ担当も見たい、外注のエンジニアにも触ってほしい、社長もたまにダッシュボードを開く——こうして関わる人が増えたとき、いちばん手早い解決策に見えるのが「全員にオーナー権限(オーナー、または BigQuery 管理者)を渡す」やり方です。
たしかに、全員がオーナーなら「権限が足りなくて動かない」というトラブルは起きません。けれども、これはかなり危険な状態です。
- 誰でもテーブルを削除できる(しかも他人のテーブルも)
- 誰でも他人にアクセス権を付与できてしまう
- 退職・契約終了した人の権限を消し忘れると、外から全データに触れる穴が残る
- 「誰が何をできるのか」が誰にも分からなくなる
特に中小規模のEC事業では、BigQueryの中に売上・顧客・広告費といった事業の根幹データが集まっています。これを「全員フルアクセス」で運用するのは、店の金庫を開けっ放しにしておくのに近い状態です。
この記事では、BigQueryのアクセス制御を支える IAM(Identity and Access Management) の考え方を整理し、主要なロールの違い、データセット単位での権限付与、行・列レベルのセキュリティ、そして権限の棚卸しまでを、チーム運用の目線でまとめます。
最小権限の原則:必要な分だけ渡す
アクセス制御を設計するときの大前提が、最小権限の原則(Principle of Least Privilege) です。ひとことで言えば「その人が仕事をするのに必要な権限だけを渡し、それ以上は渡さない」という考え方です。
なぜこれが大事なのでしょうか。理由は主に2つあります。
- 事故の被害を小さくできる — 読み取りしかできない人は、誤ってテーブルを消すことができません。権限の範囲が、そのまま「やらかせる範囲」の上限になります。
- 何かあったときに原因を絞りやすい — 「書き込みできるのはこの3人だけ」と決まっていれば、データが壊れたときに調べる対象が一気に狭まります。
「とりあえず広めに渡しておいて、困ったら絞る」という運用は、現実にはまず絞られません。困っていないからです。だからこそ、最初に狭く始めて、足りなければ足す方向で設計するのが安全です。
もうひとつ意識したいのが、権限は付与する相手の「単位」も最小に寄せる という点です。後で詳しく触れますが、個人アカウント一つひとつに権限を付けていくより、役割ごとのグループに付けるほうが、増えすぎを防ぎやすくなります。
BigQueryのIAMは、この最小権限を実現しやすいように、役割ごとに細かく分かれた 事前定義ロール を用意しています。次の節で見ていきましょう。
主要なロールの違いを理解する
BigQueryのIAMロールは「権限のセットに名前を付けたもの」です。ユーザーやグループに対してロールを割り当てることで、「この人はこれができる」を決めます。
チーム運用でまず押さえておきたい主要なロールは次のとおりです。ロール名は roles/ から始まる正式名で示します。
roles/bigquery.dataViewer(データ閲覧者)
テーブルやビューのデータを 読み取る ための権限です。データの中身を見たり、クエリで参照したりできますが、テーブルを変更したり削除したりはできません。
「数値を見たいだけ」「ダッシュボードのもとになるデータを参照したいだけ」というメンバーには、基本的にこのロールが出発点になります。
roles/bigquery.dataEditor(データ編集者)
データセット内のテーブルを 作成・更新・削除 できる権限です。dataViewer の読み取りに加えて、テーブルの中身を書き換えたり、新しいテーブルを作ったりできます。
データを加工してデータマートを作る人や、ETLの処理を回す人に向いています。ただし、他人にアクセス権を付与する権限は含まれていません。
roles/bigquery.jobUser(ジョブユーザー)
プロジェクト内で ジョブ(クエリ・ロード・エクスポートなど)を実行する ための権限です。ここが少し分かりにくいポイントなので、強調しておきます。
jobUserは「ジョブを実行できる」だけで、「データを読める」わけではありません。逆にdataViewerは「データを読める」だけで、「クエリを実行する」権限を持ちません。
つまり、メンバーが実際にクエリを書いて結果を得るには、データへのアクセス権(dataViewer など)と、ジョブ実行権(jobUser)の両方 が必要になります。片方だけだと「権限はあるはずなのにクエリが動かない」という典型的なつまずきが起きます。
実務では、jobUser をプロジェクトレベルで付与し、データへのアクセス権はデータセット単位で細かく付与する、という組み合わせがよく使われます。
roles/bigquery.user(ユーザー)
プロジェクト内でジョブを実行でき、新しいデータセットを作成でき、自分が作ったデータセットには編集者としてアクセスできる、という比較的広めのロールです。jobUser よりできることが多い一方、dataEditor のように既存の全データセットを書き換えられるわけではありません。
「自分の作業用データセットを自由に作って試行錯誤したい」アナリストなどに向いています。
その他の上位ロール
このほかに、データセット内の権限管理まで含めて任せられる roles/bigquery.dataOwner(データオーナー)や、プロジェクト全体を管理できる roles/bigquery.admin(管理者)があります。これらは強力なので、付与するのは本当に管理を任せる少数のメンバーに限るのが安全です。
役割と組み合わせの目安
中小ECチームでよくある役割に当てはめると、おおまかには次のような組み合わせになります。あくまで出発点として、実態に合わせて調整してください。
| 役割の例 | 主なロールの組み合わせ |
|---|---|
| 数値を見たいだけの担当・経営層 | jobUser(プロジェクト)+ dataViewer(必要なデータセット) |
| データを加工するアナリスト | jobUser(プロジェクト)+ dataEditor(作業用データセット) |
| 試行錯誤するデータ担当 | user(プロジェクト) |
| 基盤を管理する責任者 | admin(プロジェクト、少数のみ) |
基本ロールはなるべく使わない
GCP には、IAM の歴史的な経緯から「閲覧者」「編集者」「オーナー」という 基本ロール(旧プリミティブロール) も存在します。これらはプロジェクト全体に効く非常に広い権限で、BigQuery 以外のサービスにも影響します。
手軽ではあるのですが、最小権限の観点では大ざっぱすぎます。たとえばプロジェクトの「編集者」を付けると、BigQuery のテーブル操作だけでなく、ほかのサービスの設定変更までできてしまいます。
特別な理由がなければ、基本ロールではなく、ここまで紹介してきた BigQuery 専用の事前定義ロールを使うのがおすすめです。「何ができるか」を必要な範囲に閉じ込められるからです。
データセット単位で権限を付与する
ロールはプロジェクト全体に対しても付与できますが、BigQueryの大きな利点は データセット単位(さらにテーブル単位)でアクセス権を絞れる ことです。
たとえば、こんな分け方が考えられます。
raw_*… 生データを置くデータセット。書き込めるのはETL担当だけmart_*… 集計済みのデータマート。多くのメンバーにdataViewerを付与sandbox_*… 各自の試し書き用。本番データとは分離
このように、データセットを「中身の機密度」や「触ってよい人の範囲」で分けておくと、権限の設計がぐっと素直になります。「顧客の個人情報を含むデータセットは閲覧者を絞り、集計後の数値だけ広く見せる」といった運用も、データセットを分けておけば自然に実現できます。
データセットレベルの権限付与は、コンソールのデータセット設定画面の「共有」から行えるほか、bq コマンドや Terraform でも管理できます。チームの規模が大きくなってきたら、権限の付与状況をコードで管理しておくと、変更履歴が残って棚卸しもしやすくなります。
なお、個人ではなく Google グループに対してロールを付与する 運用にしておくと、入退社のたびに個別の権限をいじらずに、グループへの追加・削除だけで済みます。「マーケチーム」グループに dataViewer を付けておき、人の出入りはグループのメンバー管理で吸収する、という形です。
グループ運用にはもう一つ利点があります。棚卸しのときに「このデータセットを見られるのは誰か」を、グループのメンバー表を見るだけで把握できることです。個人へのバラバラな付与だと、誰がどこに紐づいているかを追うだけで一苦労ですが、グループに集約しておけば見通しがよくなります。
外注やパートナーへの一時的なアクセス
中小ECの現場では、スポットで外注のエンジニアやコンサルにデータを見てもらう場面もあります。このときも考え方は同じで、必要なデータセットに、必要なロールだけを、必要な期間だけ 付与します。
具体的には、専用のグループ(たとえば「外部パートナー」)を一つ用意し、そこに閲覧に必要なデータセットの dataViewer とプロジェクトの jobUser を付けておきます。契約が終わったらグループからメンバーを外すだけで、アクセスを一括で止められます。個人アカウントに直接付けてしまうと、終了後の消し忘れが起きやすいので避けましょう。
さらに細かく:行・列レベルのセキュリティ
データセットやテーブル単位の制御で足りないケースもあります。「同じテーブルでも、人によって見せたい行・列が違う」場合です。
このときに使えるのが、BigQuery の 列レベルセキュリティ と 行レベルセキュリティ です。
- 列レベルセキュリティ … ポリシータグ(Data Catalog のタグ)を列に付け、そのタグへのアクセス権を持つ人だけが該当列を読めるようにします。たとえば
emailやphoneといった個人情報の列だけを、特定のメンバーから隠せます。 - 行レベルセキュリティ … 行レベルアクセスポリシーを定義し、条件に合う行だけを見せます。たとえば「店舗担当者には自分の店舗の行だけ」を見せる、といった出し分けができます。
これらは強力ですが、設計と運用の手間も増えます。まずはデータセット・テーブル単位の制御をきちんと組み、「同一テーブル内で人によって見せ分けたい」という明確な要件が出てきたときに、行・列レベルのセキュリティを検討する、という順序が現実的です。
⚠️ 権限は定期的に棚卸しする
アクセス制御は「一度設計して終わり」ではありません。チームは時間とともに変わります。
- 退職・契約終了したのに権限が残っている
- 一時的に付けた強い権限を消し忘れている
- 「もう使っていないデータセット」に広いアクセス権が残っている
こうした「権限の置き忘れ」は、放っておくとそのままセキュリティ上の穴になります。そこで、定期的な 棚卸し(アクセスレビュー) を運用に組み込んでおくことをおすすめします。
最低限、次のことを四半期に一度くらいのペースで確認するとよいでしょう。
- いま誰に、どのロールが付与されているかを一覧で確認する
- 退職・異動・契約終了したメンバーの権限が残っていないか確認する
- 強すぎるロール(オーナー・管理者)が必要以上に付いていないか見直す
- 使われていないデータセットや、不要になったアクセス権を整理する
権限付与の状況は、IAM ポリシーの確認に加えて、誰が何にアクセスしたかを 監査ログ(Cloud Audit Logs) で追うこともできます。「付与されている権限」と「実際に使われている権限」の両面から見ると、棚卸しの精度が上がります。
棚卸しを習慣にしておくと、いざ監査やトラブルが起きたときにも「うちはちゃんと管理できています」と胸を張れる状態を保てます。
まとめ
BigQueryのアクセス制御は、はじめに少し設計しておくだけで、その後の運用がずっと安全で楽になります。要点を整理します。
- 全員オーナーは避ける — 事故の被害も、原因究明の難しさも大きくなります
- 最小権限の原則で始める — 狭く始めて、足りなければ足す
- 主要ロールの違いを押さえる —
dataViewer(読む)、dataEditor(書く)、jobUser(実行する)、user(実行+自分のデータセット作成)。特に「データへのアクセス権」と「ジョブ実行権」は別物だと意識する - データセット単位で絞る — 機密度や利用者の範囲でデータセットを分け、グループ単位で権限を付与する
- 必要なら行・列レベルへ — 同一テーブル内で見せ分けたいときの選択肢
- 定期的に棚卸しする — 置き忘れた権限が穴になる前に整理する
権限設計は地味な作業ですが、データを資産として安心して使い続けるための土台です。コスト面の管理とあわせて整えておくと、BigQuery運用全体の見通しがよくなります。コストについてはBigQueryのクエリコストを月1万円以下に抑える7つの実践テクニックと、BigQueryのINFORMATION_SCHEMAでクエリコストと実行履歴を自動監視するもあわせてご覧ください。