shuheishuhei

BigQuery の機密情報を Policy Tag でアクセス制御する

2025-09-30

こんにちは。株式会社 Belong にて Data Platform チームに所属する Shuhei です。

先日、EXPO 2025 大阪・関西万博へ行ってきました。持参した日傘と折りたたみ椅子に助けられつつ、180 分待ちを 2 セットこなしました!行列の耐性はだいぶついたと思います。

さて、Belong では dbt × BigQuery でデータ分析基盤を構築しています。

最近、データ分析基盤で機密情報を取り扱う場面がありました。普段のデータ連携とは一味違うアプローチをいくつか経験しましたので、記事としてまとめていければと思っています。

その中でも今回は BigQuery の Policy Tag を用いたカラムレベルアクセスコントロールについて共有できればと思います。

BigQuery Policy Tag による Column Level Access Control

BigQuery の Policy Tag を使用することで、カラムレベルでの細かなアクセス制御が可能になります。まずは、アクセス制御を実現するリソースについて簡単に抑えておきましょう。

  • Taxonomy
    • 複数の Policy Tag を階層的にまとめる分類階層
  • Policy Tag
    • Taxonomy に属する構成要素で、BigQuery のカラムにアタッチすることで、カラムレベルのアクセス制御を実現する

Policy Tag を BigQuery のテーブルのカラムにアタッチすることにより、以下の 2 つの機能を実現できます。

  1. アクセス制御
  • ユーザーやグループによって、特定のカラムへのアクセスを制限
  1. データマスキング
  • データの見え方を制御し、機密情報を適切にマスキング

アクセス制御

Policy Tag を用いることで Tag ごとにプリンシパルを紐づけ、それぞれの権限を管理することができます。

policy_tag_access_control

出典:https://cloud.google.com/bigquery/docs/column-level-security-intro?hl=ja#example_use_case

例えば、図のように high, medium, low と Business Criticarity に応じた Policy Tag を作成し、

Image

BigQuery のテーブルのカラムにアタッチすることで、アクセス制御を行うことができます。下記は nameemail に Policy Tag medium をアタッチした例となります。

Image

Policy Tag をアタッチした BigQuery のカラムへは、通常の Viewer (roles/viewerroles.bigquery.dataViewer など) の権限を持っていたとしてもアクセスができません。

Access Denied: BigQuery BigQuery: User has neither fine-grained reader nor masked get permission to get data protected by policy tag "[taxonomy] : medium" on columns [table_path].email, [table_path].name.

別途、きめ細かい読み取り / datacatalog.categoryFineGrainedReader が必要となります。

データマスキング

さらに、Policy Tag を用いることでデータマスキングも行うことができます。データマスキングを使用することで、カラムにはアクセス可能である一方、見える値はマスキングされた値として出力することができます。

policy_tag_data_masking

出典:https://cloud.google.com/bigquery/docs/column-data-masking-intro?hl=ja#mask_data_with_policy_tags

Policy Tag にはデータマスキングルールとプリンシパルを紐づけることができます。マスキングルールには標準で用意されているものだけでも多くの種類がありますので、眺めてみると興味深いです。UDF ベースでカスタムのルールを作成することもできます。

Data masking rules

ここでは Email のマスクを試してみましょう。Masking ruleEmail mask と指定することで実現できます。プリンシパルにはマスク後のデータを閲覧できるユーザーを指定してください。

Image

マスクされたカラムに対して SELECT してみると、下記のようにメールアドレスのユーザー名を XXXXX のようにマスクした状態で閲覧することができます。

Image

Policy Tag によるデータマスキングの特徴としては、プリンシパルごとにクエリ結果がそれぞれ異なった形で出力できることです。その部門や役職等に応じて、データの見え方を柔軟に調整することができるのです。

アクセス制御およびデータマスキングの重要なポイントとしては、ポリシーのルールがデータ自身から分離されていることだと感じました。機密情報を含むテーブルと、マスクされたテーブルを別々に作成する必要はないのです。データの値自体や構造を変更することなく、柔軟なアクセス制御が実現できるところがうれしいですね。

実装方法

dbt を用いた Policy Tag の付与

dbt プロジェクトでは、以下のように Policy Tag をカラムに付与できます。

dbt でデータモデルを管理しつつ、同時に Policy Tag というセキュリティポリシーも管理できるのはうれしいポイントです。Terraform で Policy Tag を付与する方法もあるとは思いますが、データモデルとインフラとでリポジトリが分離されている場合、管理面では不便な点もあるでしょう。

BigQuery configurations - Policy tags

models:
  - name: users
    columns:
      - name: email
        description: '顧客のメールアドレス'
        policy_tags:
          - 'projects/your-project/locations/asia-northeast1/taxonomies/taxonomy_name/policyTags/email'
      - name: name
        description: '顧客の名前'
        policy_tags:
          - 'projects/your-project/locations/asia-northeast1/taxonomies/taxonomy_name/policyTags/name'

Terraform を用いた Policy Tag の作成

Policy Tag は Terraform で作成・管理できます。

resource "google_data_catalog_taxonomy" "test_taxonomy" {
  project                = "test_project"
  region                 = "asia-northeast1"
  display_name           = "Test Taxonomy"
  description            = "テスト用分類"
  activated_policy_types = ["FINE_GRAINED_ACCESS_CONTROL"]
}

resource "google_data_catalog_policy_tag" "name" {
  taxonomy     = google_data_catalog_taxonomy.test_taxonomy.id
  display_name = "Name"
  description  = "顧客の名前をアクセス制御するポリシータグ"
}

resource "google_data_catalog_policy_tag" "email" {
  taxonomy     = google_data_catalog_taxonomy.test_taxonomy.id
  display_name = "Email"
  description  = "顧客のメールアドレスをマスキングするポリシータグ"
}

resource "google_bigquery_datapolicy_data_policy" "mask_email" {
  project          = "test_project"
  location         = "asia-northeast1"
  data_policy_id   = "mask_email_by_policy_tag"
  policy_tag       = google_data_catalog_policy_tag.email.name
  data_policy_type = "DATA_MASKING_POLICY"

  data_masking_policy {
    predefined_expression = "EMAIL_MASK"
  }
}

google_data_catalog_taxonomy

google_data_catalog_policy_tag

google_bigquery_datapolicy_data_policy

Policy Tag の利点

Policy Tag を紹介していく中で同時にメリットにも触れてはいましたが、ここでは Policy Tag の概要 で紹介しきれなかった利点について紹介します。

機密情報だけを除いたプレビューが機能する

BigQuery テーブルのプレビュー機能では、Policy Tag がアタッチされたカラムを除いたカラムのプレビューを確認することができます。

機密情報へのアクセスは制限しつつ、プレビュー機能の利便性は享受できるため、利用者がデータの概要を安全に把握することができると感じました。

Policy Tag をアタッチしていないとき Image

Policy Tag を nameemail にアタッチしたとき Image

組織内を横断する形で使用可能

Policy Tag とそれを束ねる Taxonomy はリージョンリソースです。したがって、同一のロケーションであれば、組織内のプロジェクトを横断する形で Policy Tag を使用することができます。

Introduction to column-level access control

したがって、中央集権的に Policy Tag を管理しつつ、各ドメインの DWH へ付与することができるため、統一的な管理が可能となります。各ドメインで独自に機密情報へのアクセスを制御すると定義が散り散りになってしまい、運用上デメリットが多いかと思いますので、こちらもうれしいポイントだなと思いました。

Policy Tag の注意点

テーブルの replace による Policy Tag の消失

Policy Tag はテーブルの replace (洗替) により、Policy Tag が外れることがあるため、注意が必要です。気づかぬうちに Policy Tag が外れていて機密情報にアクセスできていた!ということは避けなければなりません。

bq load によるテーブルの replace であれば、Schema の指定の際に Policy Tag を指定可能ですので、まずはこのアプローチを検討するとよいのではないでしょうか。

REST Resource: tables

テーブル以外へのアタッチ不可

Policy Tag はテーブルのカラムへのアタッチを前提としています。ビューのカラムにはアタッチすることができないことに注意が必要です。

ただし、テーブルからビューへのアクセス制御の伝播は可能です。

Does BigQuery column-level sec work for views?

まとめ

今回は、BigQuery で Policy Tag を用いた機密情報保護についてご紹介しました。

Policy Tag を用いることで、データとは分離されたルールにより、プリンシパルに応じてデータの見せ方を柔軟に変更できることが興味深いと思いました。本稿が Policy Tag 活用の一助になれば幸いです。

Belong ではこのように BigQuery を用いたデータプライバシー保護を含む DWH の構築を積極的に実施しています! Data Platform チームに興味を持っていただけた方は是非 Entrancebook をご覧ください!

No table of contents available for this content