Goal: let a team query curated results without seeing raw tables.
Setup:
1. Create the view in a "sharing" dataset: a SQL query over the restricted source dataset.
2. Authorize the view on the source dataset: add the view to the source dataset's access list as an authorized view.
3. Grant the readers roles/bigquery.dataViewer on the SHARING dataset only. They get zero permissions on the source dataset.
Why this works: BigQuery checks the view's permissions, not the reader's, when the view is authorized. The reader never touches raw tables.
Traps:
- Forgetting step 2 gives readers "Access Denied" on the source tables even though they can "see" the view. Authorization is the step everyone skips.
- Views in the SAME dataset as the tables do not isolate anything. Use a separate sharing dataset.
- Authorized views cannot reference other authorized views in some configurations; keep the chain one level or test it.
- Row-level security and column masking are complementary: authorized views for coarse sharing, masked columns for fine-grained.
Also consider: materialized views for performance, but plain authorized views for access control. Do not confuse the two purposes.
Verify: as a test reader identity with only sharing-dataset access, query the view successfully and confirm direct queries on source tables fail.