Last updated: May 18, 2026
- Can fully operate transfers and schema migrations
- Has data access to only the BigQuery dataset you share with it, and nothing else
- Cannot see, list, or read any other dataset, table, or bucket in your project, not even their names
Before You Start
Have these ready:- A GCP project where Detrics will load your data.
- Someone with IAM Admin on the project. Granting a project-level role requires permission to edit the project’s IAM policy (Project IAM Admin or Owner). If that isn’t you, you can email these exact steps to whoever manages the project. In Detrics, open the BigQuery destination setup and use Send setup instructions.
- The Detrics service account email. It’s shown on your destination page in Detrics. Create the BigQuery destination in Detrics first, since you’ll need this email for the grants below.
The data Detrics loads lives in your GCP project, so BigQuery storage and query costs are billed by Google directly to you. This applies to both the standard and least-privilege setups.
Why a Project-Level Grant Is Still Needed
Detrics’ write path needs two distinct kinds of permission, and it is important to understand the difference:- The ability to submit jobs to BigQuery. This covers queries, load jobs, and DML that actually move your marketing data into BigQuery. In BigQuery, running a job is a project-level action; it cannot be scoped to a single dataset.
- The ability to read and write data. This can be scoped, and under least-privilege it is scoped to only the dataset you share.
roles/bigquery.jobUser.
In other words: the project-level scope is a mechanical requirement for loading data, not a window into your project. All actual data access comes exclusively from the dataset-level grant you make on the dataset you share. Combining a project-level jobUser with a dataset-level dataEditor gives Detrics exactly what it needs and nothing more.
Image storage, if you enable it, works the same way: a bucket-scoped grant lets Detrics write creatives to exactly one bucket and nowhere else.
Required Roles
| Scope | Role | What it allows |
|---|---|---|
| Project | roles/bigquery.jobUser | Submit BigQuery jobs (queries, load jobs, DML). No data access: it cannot read, list, or see any dataset. |
| Dataset (only the one you share) | roles/bigquery.dataEditor | Create, read, modify, and delete tables in this dataset. Insert and update data. |
| Bucket (only if you enable image persistence) | roles/storage.objectUser | Upload, replace, and delete image objects in this one bucket. No access to any other bucket. |
The dataset (and the image bucket, if you use one) must be pre-created by you under this configuration, because Detrics won’t have permission to create them automatically. This is one of the extra steps; see Pre-creating the Resources for why.
Step-by-Step Setup
1. Pre-create the BigQuery Dataset
In Google Cloud Console:- Navigate to BigQuery
- Click your project → Create Dataset
- Set the Dataset ID (e.g.,
detrics_marketing) and Data location - Click Create Dataset
2. Grant BigQuery Job User at the Project Level
- Go to Google Cloud Console → IAM & Admin → IAM
- Make sure the correct project is selected in the top dropdown
- Click Grant Access
- In New principals, paste your Detrics service account email (shown on your destination page)
- In Select a role, search for and select BigQuery Job User
- Click Save
3. Grant BigQuery Data Editor on Your Dataset
- In BigQuery Console, click your dataset (the one you created in step 1)
- Click SHARING → Permissions
- Click ADD PRINCIPAL
- Paste the Detrics service account email
- Select role BigQuery Data Editor
- Click Save
4. (Optional) Enable Image Persistence
If you want Detrics to store ad-creative images alongside your data, it is done with a bucket-scoped grant that keeps everything off any project-level Storage role. Skip this step entirely if you don’t use image persistence.- Pre-create the bucket. In Cloud Storage, click Create. Use the bucket name you’ll configure in Detrics, pick the same region as your dataset, and enable Uniform bucket-level access.
- Grant Detrics a bucket-scoped role. On the bucket’s Permissions tab, click Grant Access, paste your Detrics service account email, select the role Storage Object User, and click Save.
Public or private bucket, your call
Detrics stores every creative image in your bucket the same way regardless of this choice. What changes is the URL form Detrics writes next to each row — and therefore who can see the image in a dashboard or report:- Public bucket → Detrics writes a public URL (
https://storage.googleapis.com/…). The image renders for anyone viewing the report, including external or shared viewers. Make it public on the bucket’s Permissions tab: click Grant Access, add the principalallUsers, and assign the role Storage Object Viewer. - Private bucket → Detrics writes an authenticated URL (
https://storage.cloud.google.com/…). The image renders only for viewers signed into Google with IAM read access to the bucket — typically your own team inside BigQuery or Looker. Everyone else gets a Google sign-in screen instead of the image.
Bucket access mode
On the destination’s Image Storage card you control which URL form Detrics writes:- Auto (default) — Detrics detects whether the bucket is publicly readable (when you create the destination, on every Test Connection, and at the start of each sync) and picks the matching URL form for you. If you grant or revoke
allUserslater, it follows on the next sync. - Public — always write the public URL. Use when you know the bucket is public.
- Private — always write the authenticated URL. Use when your bucket is intentionally private.
Switching the mode only affects new image rows. URLs already written to BigQuery keep the host they were stored with — re-sync the affected window if you need existing rows updated.
5. Test the Connection
In Detrics, open your destination and click Test Connection. The test runs through these stages:- BigQuery Connectivity
- Project Access
- Dataset Permissions (verifies your pre-created dataset)
- Table Permissions (creates and deletes a test table inside the dataset)
- Job Permissions (loads and reads a test row)
What Detrics Can and Cannot Do
With this configuration, Detrics has access to a precise, verifiable subset of your project.Can do (within the dataset and bucket you shared, only)
- Create, alter, and drop tables
- Insert, update, and delete rows
- Read data from tables it created
- Run queries that reference only the dataset you shared
- Run schema migrations using its safe temp-table-then-rename pattern
- Upload, replace, and remove ad-creative images in the granted bucket (only if image persistence is enabled)
Cannot do (anywhere else in your project)
- See the existence or names of datasets you did not share
- List tables or read metadata in datasets you did not share
- Query data from any dataset you did not share
- Create or delete datasets
- Access any other Cloud Storage bucket
- Read IAM policies, billing data, or any other GCP resource
BigQuery Job User role does not change any of this. It grants the ability to run jobs, not to read data. You can confirm exactly what permissions the service account has at any time using the IAM Policy Troubleshooter in the GCP Console.
Pre-creating the Resources
In the standard setup, Detrics auto-creates the dataset (and the image bucket) on first use. Under least-privilege, those creation permissions are intentionally not granted, because the ability to create datasets is project-wide and would broaden Detrics’ reach. So you create the dataset yourself once during setup, and the bucket too if you use image persistence. This is the main reason least-privilege has a few extra steps. Day-to-day operation needs no further intervention from you: Detrics manages tables and rows within the dataset, and image objects within the bucket, on its own. Each Detrics destination uses its own dataset. If you add another destination later, pre-create its dataset and repeat the dataset-level grant.Revoking Access
To disconnect Detrics, remove the role bindings you granted:- Project: go to IAM & Admin → IAM, find the Detrics service account, and remove its
BigQuery Job Userbinding. - Dataset: open the dataset → SHARING → Permissions, and remove the
BigQuery Data Editorbinding for the service account. - Bucket (only if you set up image persistence): open the bucket → Permissions, and remove the
Storage Object Userbinding for the service account.
Your existing data is not affected. Every table and row Detrics already loaded stays exactly where it is. It lives in your dataset, in your project, and it is yours to keep. Revoking access only stops future syncs; it never deletes data.
Troubleshooting
Test fails at Stage 4 (Table Permissions) with 'datasets.create permission denied'
Test fails at Stage 4 (Table Permissions) with 'datasets.create permission denied'
The dataset doesn’t exist yet and Detrics tried to create it. Pre-create the dataset in BigQuery Console (see Step 1 above) and re-run the test.
Test fails at Stage 1 (BigQuery Connectivity) with 'jobs.create permission denied'
Test fails at Stage 1 (BigQuery Connectivity) with 'jobs.create permission denied'
The
BigQuery Job User role wasn’t granted at the project level, or hasn’t propagated yet. Confirm the role is assigned in IAM & Admin → IAM, then wait ~60 seconds and retry.Test fails at Stage 4 (Table Permissions) with 'tables.create permission denied'
Test fails at Stage 4 (Table Permissions) with 'tables.create permission denied'
The
BigQuery Data Editor role wasn’t granted on the dataset itself. Open the dataset in BigQuery Console → SHARING → Permissions and confirm the service account is listed with BigQuery Data Editor.Image persistence fails with 'storage.objects.create permission denied'
Image persistence fails with 'storage.objects.create permission denied'
The
Storage Object User role wasn’t granted on the bucket, the bucket doesn’t exist yet, or the role hasn’t propagated. Open the bucket in Cloud Storage Console → Permissions and confirm the service account is listed with Storage Object User. If you pre-created the bucket but Detrics still can’t reach it, double-check the bucket name matches exactly what you configured on the destination page.Ad creatives show up as broken images in reports
Ad creatives show up as broken images in reports
The bucket is private. Embedded images need a publicly reachable URL. If you want creatives to render inside dashboards, make the bucket public by granting
allUsers the Storage Object Viewer role on the bucket’s Permissions tab. If you intentionally keep the bucket private, this is expected: the images are still stored, they just won’t render embedded.Service account can read a dataset or bucket you didn't share
Service account can read a dataset or bucket you didn't share
When to Use This Setup
Choose least-privilege when:- Your GCP project is shared with other workloads or contains sensitive data
- Your security or compliance team requires least-privilege access for third-party integrations
- You want a defense-in-depth posture even if Detrics’ credentials were ever compromised
- The GCP project is dedicated to Detrics (no other data lives there)
- You’d rather not pre-create the dataset (and bucket) yourself
- Convenience matters more than scope-limited access in your context