---
title: GA4 via BigQuery
slug: ga4-via-bigquery
createdAt: 2026-10-30T18:05:19.227Z
---

Chord uses a service account in your Google Cloud project to copy your GA4 export out of BigQuery and into your Cloud Storage bucket.

You create the account, grant it four roles, and send Chord the account details and a JSON key.

Before you start, you need an active [GA4 to BigQuery link](https://support.google.com/analytics/answer/9823238) and a landing bucket that [Chord can read](https://docs.chord.co/sharing-data-with-chord-from-cloud-storage#configuring-an-integration-for-google-cloud-storag).

:::hint{type="info"}
Pick one way to set this up, not both.

**Option A** uses the Google Cloud console.

**Option B** runs the same steps with the gcloud CLI.

Both end in the same place. Then go to [What to send Chord](#what-to-send-chord).
:::

## Option A: Google Cloud console

### Create the service account

Use the project that holds your `analytics_<property_id>` dataset.

1. In the Google Cloud console, open the **Create service account** page and select that project.
2. Enter a name, for example `chord-ga4`. Google builds the account ID from it, and you cannot change the ID later.
3. Click **Create and continue**, then **Done**. You will grant the roles in the next section, so you can skip the role step here.

:::hint{type="info"}
You need the Create Service Accounts role (`roles/iam.serviceAccountCreator`) on the project. To grant roles you also need Project IAM Admin (`roles/resourcemanager.projectIamAdmin`). A new service account can take a minute or more before it is usable.
:::

### Grant the roles

Grant each role at the narrowest level Google allows. You will need the service account's email, for example `chord-ga4@your-project-id.iam.gserviceaccount.com`.

**On the project.**

BigQuery Job User and BigQuery Read Session User can only be granted on a project, folder or organization, never on a single dataset.

1. Open **IAM & Admin → IAM** and select your project.
2. Click **Grant access**.
3. Enter the service account email under **New principals**.
4. Add the roles **BigQuery Job User** and **BigQuery Read Session User**, then click **Save**.

**On the dataset.**

BigQuery Data Viewer only needs to cover your GA4 dataset.

1. In the Google Cloud console, open **BigQuery**.
2. In **Explorer**, expand your project, click **Datasets**, and select the `analytics_<property_id>` dataset.
3. Click **Sharing → Permissions**, then **Add principal**.
4. Enter the service account email.
5. In **Select a role**, choose **BigQuery Data Viewer**.
6. Click **Save**, then **Close**.

**On the bucket.**

Storage Object Admin only needs to cover your landing bucket.

1. Open **Cloud Storage → Buckets** and click the bucket name.
2. Open the **Permissions** tab and click **Grant access**.
3. Enter the service account email under **New principals**.
4. In **Select a role**, choose **Storage Object Admin**, then click **Save**.

### Create a JSON key

1. Open the **Service accounts** page and select your project.
2. Click the email address of the service account.
3. Open the **Keys** tab.
4. Click **Add key**, then **Create new key**.
5. Select **JSON** as the key type and click **Create**.

The key file downloads once and Google cannot show it again.

:::hint{type="danger"}
The JSON key is a secret. Send it to Chord through a secure channel, never by email or Slack. Delete your local copy once Chord confirms the connection works.
:::

## Option B: gcloud CLI

Skip this section if you used Option A. It does the same thing from the command line.

Set these values first.

```javascript
PROJECT_ID=your-project-id
DATASET=analytics_123456789
BUCKET=your-bucket-name
SA=chord-ga4
SA_EMAIL=$SA@$PROJECT_ID.iam.gserviceaccount.com
```

Create the account.

```javascript
gcloud iam service-accounts create $SA \
  --project=$PROJECT_ID \
  --display-name="Chord GA4 replication"
```

Grant the two project-level roles.

```javascript
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:$SA_EMAIL" --role="roles/bigquery.jobUser"

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:$SA_EMAIL" --role="roles/bigquery.readSessionUser"
```

Grant Data Viewer on the dataset. Run this in the BigQuery query editor.

```javascript
GRANT `roles/bigquery.dataViewer`
  ON SCHEMA `your-project-id`.analytics_123456789
  TO "serviceAccount:chord-ga4@your-project-id.iam.gserviceaccount.com"
```

Grant Storage Object Admin on the bucket.

```javascript
gcloud storage buckets add-iam-policy-binding gs://$BUCKET \
  --member="serviceAccount:$SA_EMAIL" --role="roles/storage.objectAdmin"
```

Create the key.

```javascript
gcloud iam service-accounts keys create chord-ga4-key.json \
  --iam-account=$SA_EMAIL
```

The key file `chord-ga4-key.json` is saved in your current folder. Treat it as a secret, as in Option A.

## What to send Chord

1. **Service account email.** For example `chord-ga4@your-project-id.iam.gserviceaccount.com`.
2. **JSON key.** The key file, through a secure channel.
3. **GCP project ID.** The project that holds the dataset.
4. **Dataset name.** Usually `analytics_<property_id>`.
5. **Bucket name.** The full path, starting with `gs://`.

There is no setup screen in Hub for this source yet. Chord configures the connection from these values.

## Rotating and revoking access

**Rotation.** Google recommends rotating keys regularly. Create a new key, send it to Chord, wait for Chord to confirm it works, then delete the old key. Google advises disabling a key before deleting it, because a deleted key cannot be restored.

**Revoking access.** Deleting the key cuts off Chord's access, and replication stops until you send a new one. To delete a key, open the service account, open the **Keys** tab, and click **Delete** next to the key. Deleting a key does not cancel short-lived credentials already issued from it. To cut those off as well, disable or delete the service account.

## Troubleshooting

**Why can't I create the JSON key?**

Your organization may enforce the `iam.disableServiceAccountKeyCreation` policy. Google turns it on by default for organizations created on or after May 3, 2024. An organization policy administrator can exempt your project. They tag the project `not_enforced` and update the policy so it applies to everything except tagged resources. This needs the Organization Policy Administrator, Organization Viewer and Tag Administrator roles. See [Google's guide](https://docs.cloud.google.com/iam/docs/keys-create-delete).

**Why does Chord report a permission error?**

Check that all four roles are in place. The two BigQuery roles must be on the project, Data Viewer on the dataset, and Storage Object Admin on the bucket.

***

**Need help?** Contact your Chord representative or email [support@chord.co](mailto\:support@chord.co).
