Skip to main content
Last updated: May 18, 2026
For most teams, the standard setup is the simplest path. It grants BigQuery User at the project level. But security-conscious organizations, especially those with shared GCP projects or compliance requirements, want to scope a third-party integration as narrowly as possible. Least-privilege access is the configuration we recommend for enterprise security reviews. With it, Detrics:
  • 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
It takes a few extra steps to set up compared to the standard path, because you pre-create and share the resources yourself instead of letting Detrics provision them. Those extra steps are exactly what guarantees the scoping.

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:
  1. 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.
  2. The ability to read and write data. This can be scoped, and under least-privilege it is scoped to only the dataset you share.
So this setup does include one project-level role: roles/bigquery.jobUser.
The project-level BigQuery Job User role grants no data access whatsoever. It does not let Detrics read, list, or even discover any dataset or table in your project. It only allows Detrics to run jobs, which is the mechanism BigQuery uses to load data. A job will fail with Access Denied unless the service account also holds data permissions on the specific dataset it touches.
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

ScopeRoleWhat it allows
Projectroles/bigquery.jobUserSubmit 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.dataEditorCreate, read, modify, and delete tables in this dataset. Insert and update data.
Bucket (only if you enable image persistence)roles/storage.objectUserUpload, replace, and delete image objects in this one bucket. No access to any other bucket.
Each Detrics destination writes to exactly one BigQuery dataset. If you set up multiple destinations, repeat the dataset-level grant for each one’s dataset.
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:
  1. Navigate to BigQuery
  2. Click your project → Create Dataset
  3. Set the Dataset ID (e.g., detrics_marketing) and Data location
  4. Click Create Dataset
A dataset’s Data location is permanent and cannot be changed after creation. Pick the region you want before clicking Create, and make sure it matches the location you configure in Detrics. To change it later you would have to delete and recreate the dataset.

2. Grant BigQuery Job User at the Project Level

  1. Go to Google Cloud Console → IAM & Admin → IAM
  2. Make sure the correct project is selected in the top dropdown
  3. Click Grant Access
  4. In New principals, paste your Detrics service account email (shown on your destination page)
  5. In Select a role, search for and select BigQuery Job User
  6. Click Save
Do not grant any other project-level role. In particular, avoid BigQuery User, BigQuery Admin, basic Viewer, basic Editor, or basic Owner. Any of these would grant project-wide data access and defeat the purpose of this setup. BigQuery Job User is the only project-level role you need, and it is the only one that grants no data access.

3. Grant BigQuery Data Editor on Your Dataset

  1. In BigQuery Console, click your dataset (the one you created in step 1)
  2. Click SHARINGPermissions
  3. Click ADD PRINCIPAL
  4. Paste the Detrics service account email
  5. Select role BigQuery Data Editor
  6. Click Save
If you have multiple Detrics destinations, repeat this step for each destination’s dataset. Detrics has data access to a dataset only after you complete this grant for it.

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.
  1. 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.
  2. 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.
Grant Storage Object User on the bucket only. Never grant roles/storage.admin or any Storage role at the project level. A project-level Storage role would let Detrics see and write every bucket in your project, which defeats the purpose of this setup.

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 principal allUsers, 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.
We recommend public: a public bucket exposes nothing sensitive (it holds only ad creatives, which are already public in each platform’s ad library) and is the only option that renders images for external report viewers. Choose private only if your org policy forbids public buckets and your audience is your internal team.

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 allUsers later, 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)
If you enabled image persistence, the test also verifies it can write to your pre-created bucket. If any stage fails, see Troubleshooting below.

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
The project-level 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:
  1. Project: go to IAM & Admin → IAM, find the Detrics service account, and remove its BigQuery Job User binding.
  2. Dataset: open the dataset → SHARINGPermissions, and remove the BigQuery Data Editor binding for the service account.
  3. Bucket (only if you set up image persistence): open the bucket → Permissions, and remove the Storage Object User binding for the service account.
Once the grants are removed, Detrics can no longer run jobs or touch your data.
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

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.
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.
The BigQuery Data Editor role wasn’t granted on the dataset itself. Open the dataset in BigQuery Console → SHARINGPermissions and confirm the service account is listed with BigQuery Data Editor.
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.
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.
This means the service account inherited a broader role from somewhere, most commonly a basic Viewer, Editor, or Owner role at the project level, or an explicit grant on another resource. Audit:
  1. Project IAM: confirm the service account has only BigQuery Job User
  2. Each suspicious dataset: open it in BigQuery Console → SHARINGPermissions and remove the service account if present
  3. Each suspicious bucket: open it in Cloud Storage Console → Permissions and remove the service account if present
  4. Inherited roles: basic project roles (Viewer/Editor/Owner) automatically grant data-level read across all datasets and buckets. Look for “Viewers of project X” or “Editors of project X” entries on dataset and bucket sharing panels, since those are inherited from project-level basic roles

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
Choose the standard setup when:
  • 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
Both setups are fully supported, and both support image persistence. You can also start with the standard setup and move to least-privilege later: remove the broader project role, pre-create the resources, and add the scoped grants.