How to Set Up Restricted Access in BigQuery Using Views
In this post, we'll create a restricted dataset with views to get you safely started with ContextFlo without exposing any data you don't want.
The Approach
- 1.Set up a service account with only the ability to run queries
- 2.Create a dedicated dataset containing only views
- 3.Grant the service account Data Viewer on that dataset only
- 4.Set up authorized views so the views can read from source tables
Step 1: Set Up a Service Account
You can either ask ContextFlo support for a service account email (Option A — no JSON key needed), or create your own in GCP (Option B).
Option A: Grant Access to ContextFlo's Service Account
Grant BigQuery Job User
Go to IAM & Admin → IAM → Grant Access. Add this principal:
Assign the role BigQuery Job User.
Grant Data Viewer on Your Views Dataset
This is covered in Step 3 below. You'll add the same service account email as a Data Viewer on your views dataset. Then skip ahead to Step 6 to connect in ContextFlo (no JSON key upload needed).
That's it — continue to Step 2 to create your views dataset, then skip to Step 6 (no JSON key needed).
Option B: Create Your Own Service Account
Create the Account
Go to IAM & Admin → Service Accounts → + CREATE SERVICE ACCOUNT:
- • Name:
contextflo-restricted - • Description:
Restricted read access via views only
Assign BigQuery Job User
Grant only BigQuery Job User at the project level. Do not add Data Viewer here — we'll add that at the dataset level in Step 3.
Download the JSON Key
After creating the account, find it in the list → ⋮ → Manage keys → ADD KEY → Create new key → JSON.
{
"type": "service_account",
"project_id": "your-project-id",
"private_key_id": "abc123...",
"private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n",
"client_email": "[email protected]",
"client_id": "123456789...",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token"
}Store this file securely — never commit it to version control.
Step 2: Create a Views-Only Dataset
Create the Dataset
In BigQuery Console, click your project name → Create Dataset:
- • Dataset ID:
restricted_views - • Location: Same region as your source datasets
Create Views
Create views that select from your source tables:
-- Example: expose only non-PII order data CREATE VIEW `project.restricted_views.orders` AS SELECT order_id, order_date, product_category, revenue FROM `project.raw_data.orders` WHERE order_date >= '2024-01-01'
Step 3: Grant Dataset-Level Access
On the restricted_views dataset, go to Sharing → Permissions → Add Principal. Paste the service account email and assign BigQuery Data Viewer.
The service account can now see the views but can't query them yet — the views reference tables the account doesn't have access to. That's where authorized views come in.
Step 4: Authorize the Views on Source Datasets
Key gotcha: Authorized views are configured on the source dataset (the one being read from), not on the dataset where the view lives.
Go to the Source Dataset
Navigate to the dataset that contains the source tables (e.g., raw_data). Click Sharing → Authorize Views.
Add Your View
Enter the full view path: project.restricted_views.orders and click Add Authorization.
Repeat for Every Source Dataset
If your view joins across multiple datasets, authorize the view on each one.
Step 5: Verify the Setup
Should work:
SELECT * FROM `project.restricted_views.orders` LIMIT 10
Should fail with "Access Denied":
SELECT * FROM `project.raw_data.orders` LIMIT 10
If the view query fails with "Access Denied", check which source dataset is missing the authorized view.
Step 6: Connect to ContextFlo
In ContextFlo, go to Settings → Data Sources → + Add Data Source → BigQuery.
- Connection Name: A friendly name (e.g., "Analytics Views")
- Project ID: Your GCP project ID
- Location: Dataset region (e.g., "US", "EU")
- Service Account JSON: Upload the JSON key (Option B only — Option A users can skip this)
Click Test Connection, then Connect. ContextFlo will discover only the views in restricted_views.
Chained Views
If a view references another view, you need to authorize on every dataset in the chain:
restricted_views.summary
→ analytics.orders_enriched (view)
→ raw_data.orders (table)
→ raw_data.customers (table)Authorize restricted_views.summary on analytics, and analytics.orders_enriched on raw_data. Keep your view hierarchy shallow — one level is easiest to manage.
Quick Reference
| Where | What | Why |
|---|---|---|
| Project level | BigQuery Job User | Allows running queries |
| Views dataset | BigQuery Data Viewer | Can see and query the views |
| Each source dataset | Authorized View | Lets the view read source tables |
Questions? Reach out at [email protected]