Tampilan yang diotorisasi dan tampilan terwujud

Dokumen ini menjelaskan cara membuat tampilan yang diotorisasi dan tampilan terwujud di BigQuery.

Tampilan yang diotorisasi dan tampilan terwujud yang diotorisasi memungkinkan Anda membagikan hasil kueri dengan pengguna dan grup tertentu tanpa memberi mereka akses ke data sumber yang mendasarinya. Tampilan atau tampilan terwujud diberi akses ke data, bukan pengguna. Anda juga dapat menggunakan kueri SQL yang membuat tampilan atau tampilan terwujud untuk membatasi kolom yang dapat dikueri pengguna.

Saat membuat tampilan yang diotorisasi atau tampilan terwujud di set data lain, set data dari data sumber dan set data tampilan yang diotorisasi harus berada di lokasi regional yang sama.

Untuk mendapatkan informasi tentang cara memberikan otorisasi untuk semua tampilan dalam set data, bukan memberi otorisasi untuk masing-masing tampilan, lihat Set data yang diotorisasi.

Sebelum memulai

Berikan peran Identity and Access Management (IAM) yang memberi pengguna izin yang diperlukan untuk melakukan setiap tugas dalam dokumen ini.

Izin yang diperlukan

Untuk membuat atau memperbarui tampilan yang diotorisasi, Anda memerlukan izin pada set data yang berisi tampilan dan pada set data yang memberikan akses ke tampilan tersebut.

Izin pada set data yang berisi tampilan

Tampilan diperlakukan sebagai resource tabel di BigQuery, sehingga pembuatan tampilan memerlukan izin yang sama seperti pembuatan tabel. Anda juga harus memiliki izin untuk membuat kueri setiap tabel yang direferensikan oleh kueri SQL tampilan.

Untuk membuat tampilan, Anda memerlukan izin IAM bigquery.tables.create. Peran IAM roles/bigquery.dataEditor yang telah ditetapkan mencakup izin yang diperlukan untuk membuat tampilan.

Selain itu, jika Anda memiliki izin bigquery.datasets.create, Anda dapat membuat tampilan dalam set data yang Anda buat. Agar dapat membuat tampilan untuk data yang bukan milik Anda, Anda harus memiliki izin bigquery.tables.getData untuk tabel tersebut.

Untuk mengetahui informasi lebih lanjut tentang peran dan izin IAM di BigQuery, lihat Peran dan izin yang telah ditetapkan.

Izin pada set data yang memberikan akses ke tampilan

Untuk memperbarui properti set data, Anda memerlukan izin IAM berikut:

  • bigquery.datasets.update
  • bigquery.datasets.setIamPolicy (hanya diperlukan saat memperbarui kontrol akses set data di Konsol Google Cloud)

Peran IAM roles/bigquery.dataOwner yang telah ditetapkan mencakup izin yang Anda perlukan untuk memperbarui properti set data.

Selain itu, jika memiliki izin bigquery.datasets.create, Anda dapat memperbarui properti set data yang Anda buat.

Untuk mengetahui informasi lebih lanjut tentang peran dan izin IAM di BigQuery, lihat Peran dan izin yang telah ditetapkan.

Memberi otorisasi untuk tampilan

Untuk memberikan akses lihat ke set data, ikuti langkah-langkah berikut:

Konsol

  1. Buka halaman BigQuery di Konsol Google Cloud.

    Buka BigQuery

  2. Di panel Explorer, luaskan project Anda dan pilih set data.

  3. Klik Lihat tindakan, lalu klik Buka.

  4. Di panel Dataset info, klik Sharing, lalu pilih Authorize Views.

  5. Untuk Authorize view, ketik nama tampilan yang akan diotorisasi.

  6. Klik Tambahkan otorisasi.

  7. Klik Close.

bq

  1. Tulis informasi set data yang ada (termasuk kontrol akses) ke file JSON menggunakan perintah bq show. Jika set data berada dalam project selain project default Anda, tambahkan project ID ke nama set data dalam format berikut: project_id:dataset.

    bq show \
    --format=prettyjson \
    project_id:dataset > path_to_file

    Dengan keterangan:

    • project_id adalah project ID Anda.
    • dataset adalah nama set data Anda.
    • path_to_file adalah jalur ke file JSON di komputer lokal Anda.

    Contoh:

    Masukkan perintah berikut untuk menulis kontrol akses bagi mydataset ke file JSON. mydataset berada di project default Anda.

    bq show --format=prettyjson mydataset > /tmp/mydataset.json
    

    Masukkan perintah berikut untuk menulis kontrol akses bagi mydataset ke file JSON. mydataset berada di myotherproject.

    bq show --format=prettyjson \
    myotherproject:mydataset > /tmp/mydataset.json
    
  2. Tambahkan tampilan yang diotorisasi ke bagian "akses" file JSON.

    Misalnya, bagian akses file JSON set data akan terlihat seperti berikut:

    {
     "access": [
      {
       "role": "READER",
       "specialGroup": "projectReaders"
      },
      {
       "role": "WRITER",
       "specialGroup": "projectWriters"
      },
      {
       "role": "OWNER",
       "specialGroup": "projectOwners"
      }
      {
       "role": "READER",
       "specialGroup": "allAuthenticatedUsers"
      }
      {
       "role": "READER",
       "domain": "[DOMAIN_NAME]"
      }
      {
       "role": "WRITER",
       "userByEmail": "[USER_EMAIL]"
      }
      {
       "role": "READER",
       "groupByEmail": "[GROUP_EMAIL]"
      },
      {
       "view":{
       "datasetId": "[DATASET_NAME]",
       "projectId": "[PROJECT_NAME]",
       "tableId": "[VIEW_NAME]"
       }
      }
     ],
    }

  3. Setelah pengeditan selesai, gunakan perintah bq update dan sertakan file JSON menggunakan flag --source. Jika set data berada dalam project selain project default Anda, tambahkan project ID ke nama set data dalam format berikut: project_id:dataset.

    bq update \
    --source path_to_file \
    project_id:dataset

    Dengan keterangan:

    • path_to_file adalah jalur ke file JSON di komputer lokal Anda.
    • project_id adalah project ID Anda.
    • dataset adalah nama set data Anda.

    Contoh:

    Masukkan perintah berikut untuk memperbarui kontrol akses bagi mydataset. mydataset berada di project default Anda.

     bq update --source /tmp/mydataset.json mydataset
    

    Masukkan perintah berikut untuk memperbarui kontrol akses bagi mydataset. mydataset berada di myotherproject.

     bq update --source /tmp/mydataset.json myotherproject:mydataset
    
  4. Untuk memverifikasi perubahan kontrol akses, masukkan kembali perintah show tanpa perlu menuliskan informasi tersebut ke file.

    bq show --format=prettyjson [DATASET]
    

    atau

    bq show --format=prettyjson [PROJECT_ID]:[DATASET]
    

API

Panggil datasets.patch dan gunakan properti access untuk memperbarui kontrol akses. Untuk informasi selengkapnya, lihat Set Data.

Karena metode datasets.update menggantikan seluruh resource set data, datasets.patch adalah metode yang lebih disukai untuk memperbarui kontrol akses.

Go

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Go di Panduan memulai BigQuery menggunakan library klien. Untuk mengetahui informasi selengkapnya, lihat Dokumentasi referensi BigQuery Go API.

Untuk melakukan autentikasi ke BigQuery, siapkan Kredensial Default Aplikasi. Untuk informasi selengkapnya, lihat Menyiapkan autentikasi untuk library klien.

import (
	"context"
	"fmt"

	"cloud.google.com/go/bigquery"
)

// updateViewDelegated demonstrates the setup of an authorized view, which allows access to a view's results
// without the caller having direct access to the underlying source data.
func updateViewDelegated(projectID, srcDatasetID, viewDatasetID, viewID string) error {
	// projectID := "my-project-id"
	// srcDatasetID := "sourcedata"
	// viewDatasetID := "views"
	// viewID := "myview"
	ctx := context.Background()
	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}
	defer client.Close()

	srcDataset := client.Dataset(srcDatasetID)
	viewDataset := client.Dataset(viewDatasetID)
	view := viewDataset.Table(viewID)

	// First, we'll add a group to the ACL for the dataset containing the view.  This will allow users within
	// that group to query the view, but they must have direct access to any tables referenced by the view.
	vMeta, err := viewDataset.Metadata(ctx)
	if err != nil {
		return err
	}
	vUpdateMeta := bigquery.DatasetMetadataToUpdate{
		Access: append(vMeta.Access, &bigquery.AccessEntry{
			Role:       bigquery.ReaderRole,
			EntityType: bigquery.GroupEmailEntity,
			Entity:     "example-analyst-group@google.com",
		}),
	}
	if _, err := viewDataset.Update(ctx, vUpdateMeta, vMeta.ETag); err != nil {
		return err
	}

	// Now, we'll authorize a specific view against a source dataset, delegating access enforcement.
	// Once this has been completed, members of the group previously added to the view dataset's ACL
	// no longer require access to the source dataset to successfully query the view.
	srcMeta, err := srcDataset.Metadata(ctx)
	if err != nil {
		return err
	}
	srcUpdateMeta := bigquery.DatasetMetadataToUpdate{
		Access: append(srcMeta.Access, &bigquery.AccessEntry{
			EntityType: bigquery.ViewEntity,
			View:       view,
		}),
	}
	if _, err := srcDataset.Update(ctx, srcUpdateMeta, srcMeta.ETag); err != nil {
		return err
	}
	return nil
}

Java

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Java di Panduan memulai BigQuery menggunakan library klien. Untuk mengetahui informasi selengkapnya, lihat Dokumentasi referensi BigQuery Java API.

Untuk melakukan autentikasi ke BigQuery, siapkan Kredensial Default Aplikasi. Untuk informasi selengkapnya, lihat Menyiapkan autentikasi untuk library klien.

import com.google.cloud.bigquery.Acl;
import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.Dataset;
import com.google.cloud.bigquery.DatasetId;
import com.google.cloud.bigquery.Table;
import java.util.ArrayList;
import java.util.List;

// Sample to grant view access on dataset
public class GrantViewAccess {

  public static void runGrantViewAccess() {
    // TODO(developer): Replace these variables before running the sample.
    String srcDatasetId = "MY_DATASET_ID";
    String viewDatasetId = "MY_VIEW_DATASET_ID";
    String viewId = "MY_VIEW_ID";
    grantViewAccess(srcDatasetId, viewDatasetId, viewId);
  }

  public static void grantViewAccess(String srcDatasetId, String viewDatasetId, String viewId) {
    try {
      // Initialize client that will be used to send requests. This client only needs to be created
      // once, and can be reused for multiple requests.
      BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

      Dataset srcDataset = bigquery.getDataset(DatasetId.of(srcDatasetId));
      Dataset viewDataset = bigquery.getDataset(DatasetId.of(viewDatasetId));
      Table view = viewDataset.get(viewId);

      // First, we'll add a group to the ACL for the dataset containing the view. This will allow
      // users within that group to query the view, but they must have direct access to any tables
      // referenced by the view.
      List<Acl> viewAcl = new ArrayList<>();
      viewAcl.addAll(viewDataset.getAcl());
      viewAcl.add(Acl.of(new Acl.Group("example-analyst-group@google.com"), Acl.Role.READER));
      viewDataset.toBuilder().setAcl(viewAcl).build().update();

      // Now, we'll authorize a specific view against a source dataset, delegating access
      // enforcement. Once this has been completed, members of the group previously added to the
      // view dataset's ACL no longer require access to the source dataset to successfully query the
      // view
      List<Acl> srcAcl = new ArrayList<>();
      srcAcl.addAll(srcDataset.getAcl());
      srcAcl.add(Acl.of(new Acl.View(view.getTableId())));
      srcDataset.toBuilder().setAcl(srcAcl).build().update();
      System.out.println("Grant view access successfully");
    } catch (BigQueryException e) {
      System.out.println("Grant view access was not success. \n" + e.toString());
    }
  }
}

Python

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Python di Panduan memulai BigQuery menggunakan library klien. Untuk mengetahui informasi selengkapnya, lihat Dokumentasi referensi BigQuery Python API.

Untuk melakukan autentikasi ke BigQuery, siapkan Kredensial Default Aplikasi. Untuk informasi selengkapnya, lihat Menyiapkan autentikasi untuk library klien.

from google.cloud import bigquery

client = bigquery.Client()

# To use a view, the analyst requires ACLs to both the view and the source
# table. Create an authorized view to allow an analyst to use a view
# without direct access permissions to the source table.
view_dataset_id = "my-project.my_view_dataset"
# Make an API request to get the view dataset ACLs.
view_dataset = client.get_dataset(view_dataset_id)

analyst_group_email = "data_analysts@example.com"
access_entries = view_dataset.access_entries
access_entries.append(
    bigquery.AccessEntry("READER", "groupByEmail", analyst_group_email)
)
view_dataset.access_entries = access_entries

# Make an API request to update the ACLs property of the view dataset.
view_dataset = client.update_dataset(view_dataset, ["access_entries"])
print(f"Access to view: {view_dataset.access_entries}")

# Group members of "data_analysts@example.com" now have access to the view,
# but they require access to the source table to use it. To remove this
# restriction, authorize the view to access the source dataset.
source_dataset_id = "my-project.my_source_dataset"
# Make an API request to set the source dataset ACLs.
source_dataset = client.get_dataset(source_dataset_id)

view_reference = {
    "projectId": "my-project",
    "datasetId": "my_view_dataset",
    "tableId": "my_authorized_view",
}
access_entries = source_dataset.access_entries
access_entries.append(bigquery.AccessEntry(None, "view", view_reference))
source_dataset.access_entries = access_entries

# Make an API request to update the ACLs property of the source dataset.
source_dataset = client.update_dataset(source_dataset, ["access_entries"])
print(f"Access to source: {source_dataset.access_entries}")

Menghapus otorisasi ke tampilan

Untuk menghapus otorisasi ke tampilan:

Konsol

  1. Buka halaman BigQuery di Konsol Google Cloud.

    Buka BigQuery

  2. Di panel Explorer, luaskan project Anda dan pilih set data.

  3. Klik Berbagi > Otorisasi tampilan.

  4. Klik Hapus otorisasi.

  5. Klik Tutup.

Kuota dan batas

  • Tampilan yang diotorisasi tunduk pada batas set data. Untuk mengetahui informasi selengkapnya, lihat Batas set data.
  • Jika Anda menghapus tampilan yang diotorisasi, perlu waktu hingga 24 jam untuk menghapus semua referensi ke tampilan tersebut dari sistem. Untuk menghindari error, tunggu 24 jam sebelum menggunakan kembali nama tampilan yang dihapus, atau buat nama unik untuk tampilan Anda.

Menerapkan akses tingkat baris dengan tampilan

Tampilan dapat digunakan untuk membatasi akses ke kolom tertentu. Jika ingin membatasi akses ke masing-masing baris dalam tabel, Anda tidak perlu membuat tampilan terpisah untuk setiap pengguna atau grup. Sebagai gantinya, Anda dapat menggunakan fungsi SESSION_USER() untuk menampilkan alamat email pengguna saat ini.

Untuk menampilkan baris yang berbeda kepada pengguna yang berbeda, tambahkan kolom lain ke tabel Anda yang berisi pengguna yang diizinkan untuk melihat baris tersebut. Kemudian, buat tampilan yang menggunakan fungsi SESSION_USER(). Pada contoh berikut, nama pengguna disimpan di kolom allowed_viewer:

SELECT
  COLUMN_1,
  COLUMN_2
FROM
  `dataset.view`
WHERE
  allowed_viewer = SESSION_USER()

Keterbatasan pendekatan ini adalah Anda dapat memberikan akses hanya kepada satu pengguna dalam satu waktu. Anda dapat mengatasi keterbatasan ini dengan membuat allowed_viewer sebagai kolom berulang. Pendekatan ini memungkinkan Anda menyediakan daftar pengguna untuk setiap baris. Namun, meskipun Anda menggunakan kolom berulang, menyimpan nama pengguna dalam tabel tetap mengharuskan Anda melacak secara manual setiap pengguna yang memiliki akses ke setiap baris.

Sebagai gantinya, isi kolom allowed_viewer dengan nama grup, dan buat tabel terpisah yang memetakan grup ke pengguna. Tabel yang memetakan grup ke pengguna akan memiliki skema yang menyimpan nama grup dan nama pengguna. Contoh: {group:string, user_name:string}. Pendekatan ini memungkinkan Anda mengelola informasi pengguna dan grup secara terpisah dari tabel yang berisi data.

Jika tabel pemetaan diberi nama private.access_control, kueri SQL yang digunakan untuk membuat tampilan yang diotorisasi adalah:

SELECT
  c.customer,
  c.id
FROM
  `private.customers` c
INNER JOIN (
  SELECT
    group
  FROM
    `private.access_control`
  WHERE
    SESSION_USER() = user_name) g
ON
  c.allowed_group = g.group

Langkah berikutnya