Which path applies to you?
This guide covers two setups, and Steps 1–4 are identical for both.
- DoiT resells your Google Cloud and invoices you. Your billing data lives in DoiT's project rather than your own, so skip Steps 5–6 and choose the DoiT-managed tab on the connection form.
- Google invoices you directly. Follow every step, and choose the Direct billing tab on the connection form.
If you work with DoiT for support or tooling but Google still sends your bill, you're on the direct billing path.
Prerequisites
Permissions
A user with the following roles is needed to complete this setup. All of them apply to both paths except the last.
- Organization Admin — for the organization-level binding in Step 3
- Role Administrator — for the custom role in Step 1
- Project IAM Admin — for the project-level bindings in Step 3
- Service Usage Admin — to enable the APIs listed below
- Billing Account Costs Manager or Billing Account Administrator. Not needed if DoiT resells your Google Cloud, since you won't be setting up billing exports.
Enabled APIs
Both paths. Ensure the following APIs are enabled on the project that will host the service account:
bigquery.googleapis.comiam.googleapis.comiamcredentials.googleapis.comcloudresourcemanager.googleapis.com
Enable TABLE_STORAGE_BY_ORGANIZATION
This step applies to both paths. SELECT uses INFORMATION_SCHEMA.TABLE_STORAGE_BY_ORGANIZATION to provide storage visibility across your org, and the view must be explicitly enabled for each region where your BigQuery data resides. Run the following in Cloud Shell to discover all regions in use and enable the view for each automatically.
Allow up to 24 hours for historical data to become available after enabling. SELECT cannot display storage data until this step is complete.
Connecting your account
Steps 1 through 4 are identical for both paths. Throughout, CUSTOMER_PROJECT refers to a project in your organization where SELECT runs its queries — you can use an existing project or create one for this purpose.
Step 1: Create the custom org role
Rather than binding several predefined roles separately, create one custom role at the org level. This gives you a single binding to manage and makes it easy to audit exactly what access SELECT has. It combines the permissions of roles/bigquery.resourceViewer, roles/bigquery.metadataViewer and roles/browser, plus bigquery.config.get, which is required to detect fluid scaling on reservations and is not included in any predefined role.
If you see "role SelectOrgViewer already exists", that's fine — continue to the next step.
Step 2: Create the service account
In your project UI navigate to IAM → Service Accounts → Create Service Account and give it a name, e.g. select-viewer. Click Create and continue, then skip the optional role and group steps and click Done. Alternatively, in Cloud Shell or any environment with gcloud authenticated:
This creates select-viewer@${CUSTOMER_PROJECT}.iam.gserviceaccount.com. Note this email down — you'll need it in the final step.
Step 3: Grant read and query access
First, bind the custom role at the organization level so SELECT can see every project's usage:
Then grant the project-level roles that let SELECT actually run queries and read sessions. These are intentionally scoped to the project only, not the org, to limit the blast radius:
If you see a 403 "User does not have bigquery.jobs.create permission" error when testing the connection, this step was likely skipped or run against the wrong project. Confirm CUSTOMER_PROJECT matches the project ID you entered in SELECT's connection form.
Step 4: Allow SELECT to impersonate the service account
SELECT authenticates by impersonating the service account you just created — nothing leaves your organization. You can find your org-specific SELECT service account email on the Add BigQuery connection form in the SELECT app.
Org policy restrictions: Some organizations enforce constraints/iam.managed.allowedPolicyMembers, which blocks binding external service accounts directly to resources in your org. If you hit an error mentioning this constraint, add SELECT's service account to a Google Group in your organization, then grant roles/iam.serviceAccountTokenCreator to that group on the select-viewer SA instead of binding SELECT's SA directly.
DoiT-managed customers: you're done with the GCP-side setup. Skip Steps 5 and 6 and go straight to Add connection to SELECT — DoiT handles your billing export, so there is no billing setup on your side.
Step 5: Enable billing exports
SELECT needs three billing exports — detailed usage cost, pricing data, and committed use discount data — to give you complete cost visibility. Each is written to BigQuery and all three should land in the same dataset. In the Google Cloud Console, navigate to Billing, then click Billing export in the left pane.
5a. Detailed usage cost export
- On the BigQuery export tab, find Detailed usage cost and click Enable detailed export.
- For Project, select your billing project.
- For the dataset, click create new dataset. Creating a dataset specific to SELECT lets you limit SELECT's access to just the billing data. Enter a dataset ID of your choosing (e.g. billing_export) and choose a multi-region location (US or EU). Note the ID down.
5b. Pricing data export
Back on the Billing export page, find Pricing data, click Enable pricing export, select the same project and dataset as in 5a, and save.
5c. Committed use discount (CUD) data export
Find Committed use discount data, click Enable CUD export, select the same project and dataset, and save. It can take up to 24 hours for the first batch of billing data to appear.
Step 6: Grant read access to the billing dataset
Grant bigquery.dataViewer scoped to only the billing export dataset, so SELECT has no access to your company's data. In BigQuery Studio, navigate to the billing export dataset, click Share → Manage Permissions → Add principal, add the select-viewer service account and assign BigQuery Data Viewer. Alternatively:
Add connection to SELECT
Navigate to the connections tab in SELECT's settings and click Add Connection. The fields differ depending on your billing path.
Enter a connection name (e.g. your organization's name) and fill in:
- Project ID — your CUSTOMER_PROJECT
- Billing export dataset name — e.g. billing_export
- Billing Account ID — e.g. ABCDEF-12345-67810
- Leave Managed by DoiT unchecked.
Click Add. SELECT runs a test query to verify the connection. You'll receive an email when the initial sync completes, usually within a couple of hours.
Troubleshooting
Test fails with a "jobs.create" 403
The project ID you entered must be your own CUSTOMER_PROJECT, and that project needs the bigquery.jobUser grant from Step 3. If you are on the DoiT-managed path, don't enter a DoiT project such as doitintl-cmp-gcp-data — the service account can't run jobs there.
"Permission denied" creating the role or binding
Steps 1 and 3 act at the organization level and need Role Administrator and Organization Admin. Ask whoever owns your org's IAM to run those commands, or to grant you those roles temporarily.
"Service account does not exist"
This comes from Step 4 when SELECT_SERVICE_ACCOUNT doesn't exactly match the email on your connection form. Re-copy it from the top of the connection screen and rerun that command.
Can't find your organization ID?
Your Cloud Console org picker (top-left) shows it. DoiT resale customers who are still stuck can reach out to their DoiT account team, who can look it up from your DoiT billing data.
VPC Service Controls (optional)
Applies to both paths. If your GCP organization has VPC Service Controls enabled with a service perimeter around BigQuery, SELECT's queries will be blocked by default and you'll see "Request is prohibited by organization's policy" when adding the connection. Since SELECT authenticates by impersonating your select-viewer service account, the most reliable fix is an ingress rule scoped to SELECT's GCP project.
ANY_IDENTITY is required because SELECT's service account lives in a different GCP organization than your perimeter, and ANY_SERVICE_ACCOUNT only matches service accounts within the same org. This remains secure: the source is locked to SELECT's project, IAM enforces that only SELECT's service account can impersonate your select-viewer SA, and that SA has read-only BigQuery permissions. Apply it with:
IP allowlisting will not work for most customers. SELECT runs on Google Cloud Run, which routes traffic through Google's internal network and redacts the source IP, so IP-based access levels never match. Always test perimeter changes in dry-run mode before enforcing them.



