How it works
Bag of words uses the BigQuery client library against oneproject_id. During indexing it reads INFORMATION_SCHEMA.COLUMNS and INFORMATION_SCHEMA.TABLE_OPTIONS in each dataset, so table and column descriptions you have set in BigQuery are picked up and given to the agent. If that enriched read fails on your configuration, it falls back to a plain table/column listing.
Tables are exposed to the agent as dataset.table. Queries run as BigQuery query jobs, with the cost controls below applied to every job.
Before you start
- A Google Cloud project with BigQuery enabled and at least one dataset.
- Permission to create a service account and a key for it in that project (
roles/iam.serviceAccountKeyAdmin, or ask a project admin). - For per-user sign-in only: permission to create an OAuth 2.0 client under APIs & Services → Credentials, and a configured OAuth consent screen.
- Network access from the Bag of words host to
bigquery.googleapis.com.
Step 1 — Create the service account
This identity is the shared credential — it indexes the datasets and, unless you require per-user sign-in, runs everyone’s queries.1
Create the service account
In the Google Cloud Console → IAM & Admin → Service Accounts → Create service account. Name it something like
bow-bigquery.2
Grant it BigQuery roles
Grant, at project level or on the specific datasets:
- BigQuery Data Viewer (
roles/bigquery.dataViewer) — read table data and metadata. - BigQuery Job User (
roles/bigquery.jobUser) — create the query jobs.
3
Create a JSON key
On the service account → Keys → Add key → Create new key → JSON. The file downloads once.
Step 2 — Create an OAuth client (per-user sign-in only)
Skip this step if everyone will share the service account. For Sign in with Google, Bag of words needs a Google Cloud OAuth 2.0 client, separate from the service account.1
Create the OAuth 2.0 client ID
In the Console → APIs & Services → Credentials → Create credentials → OAuth client ID. Choose Web application as the type.
2
Add the redirect URI
Under Authorized redirect URIs, add:Replace
<your-bow-host> with your Bag of words base URL.3
Copy the client ID and secret
These go into the
oauth_client_id and oauth_client_secret fields on the connection. Without both, per-user sign-in cannot start.4
Check the consent screen scope
Bag of words requests the read-only BigQuery scope,
https://www.googleapis.com/auth/bigquery.readonly, plus offline access so the token can be refreshed. Make sure that scope is allowed on your OAuth consent screen. If the app is in Testing status, add each user as a test user, or publish it internally.Step 3 — Add the connection in Bag of words
Go to Data Sources → Add data source → Google BigQuery.Authentication modes
Service Account JSON
Paste the contents of the downloaded key file intocredentials_json. This is the identity used for schema indexing, and for queries whenever no per-user credential applies.
The oauth_client_id and oauth_client_secret fields live alongside it: they are not used by the service account itself, they are the OAuth client from Step 2 that per-user sign-in needs. Fill them in on the same connection if you plan to enable per-user access.
Sign in with Google
Each user clicks Connect on the data source and completes a Google sign-in. Their token carries the read-only BigQuery scope, so discovery and queries run with their own BigQuery permissions — dataset-level access, row-level security, and audit logs all resolve to that person rather than the shared service account. To force this, enable Require user authentication on the data source. Indexing and schema refresh, which have no user in context, continue to run as the service account.Per-user authentication on a database connector requires an Enterprise license. See Authentication.
Troubleshooting
Provided BigQuery credentials are neither valid JSON content nor a readable server file path
Provided BigQuery credentials are neither valid JSON content nor a readable server file path
The
credentials_json field did not parse as JSON. Paste the entire contents of the key file, including the outer braces, and check nothing was truncated. A server-side file path is also accepted, but only if the file is readable by the Bag of words process.Access Denied: User does not have bigquery.jobs.create permission
Access Denied: User does not have bigquery.jobs.create permission
The service account has a data role but not BigQuery Job User. Reads still need a query job. Grant
roles/bigquery.jobUser on the project named in project_id.Query exceeded limit for bytes billed
Query exceeded limit for bytes billed
The query would have scanned more than
maximum_bytes_billed. Either raise the cap, or narrow the question — partition and clustering filters are the usual fix. This is the cap doing its job.Per-user sign-in never starts
Per-user sign-in never starts
oauth_client_id and oauth_client_secret must both be set on the connection; sign-in fails immediately if either is missing. Also confirm the redirect URI registered on the OAuth client exactly matches https://<your-bow-host>/api/connections/oauth/callback.Some datasets are missing
Some datasets are missing
Only the datasets listed in the
dataset field are indexed. Add them as a comma-separated list, and confirm the identity in use has read access to each — with per-user sign-in, a dataset the service account can see may still be invisible to an individual, and vice versa.