> For the complete documentation index, see [llms.txt](https://learn.moselle.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://learn.moselle.io/getting-started/onboarding/setup-integrations/bigquery.md).

# BigQuery

Connect Google BigQuery to Moselle with a read-only service account. Step-by-step setup in the Google Cloud console or gcloud, then send the key securely from Moselle — about 15 minutes.

{% hint style="info" %}
**Quick Answer:** Moselle reads sales, inventory, and order tables straight from your BigQuery project using a **read-only service account** that you create. Create the service account, grant it three BigQuery roles, download its JSON key, then paste the key and your project details into the secure form at **Settings → Integrations → BigQuery**. Moselle's team connects it from there. Setup takes about 15 minutes and needs someone who can manage IAM in your Google Cloud project.
{% endhint %}

## What this connection does

Moselle syncs the tables you choose from your BigQuery project into Moselle so forecasts, replenishment plans, and reports stay current — no exports. The connection is **read-only**: the service account can only read the datasets you grant, and Moselle can never write to your project.

BigQuery is an **assisted integration**: you create the service account and send its key securely, and the Moselle team handles the connection, data checks, and table mapping with you.

## What you'll need

* [ ] A Google Cloud user who can manage IAM on the project (**Owner**, or **Project IAM Admin** plus **Service Account Admin** and **Service Account Key Admin**)
* [ ] Your **project ID** (for example `acme-analytics-prod`)
* [ ] The **location** of your datasets (a multi-region like `US` or `EU`, or a region like `europe-west2`)
* [ ] The **dataset and table names** you want Moselle to sync

{% hint style="warning" %}
Some organizations block service account key creation with an organization policy (`iam.disableServiceAccountKeyCreation`). If key creation fails in step 3, ask your Google Cloud org admin for an exception on this project, or [contact us](mailto:support@moselle.io) and we'll work through an alternative.
{% endhint %}

## Set it up

{% stepper %}
{% step %}

### Create a service account

{% tabs %}
{% tab title="Google Cloud console" %}

1. Open the [Google Cloud console](https://console.cloud.google.com/) and select the project that holds your data
2. Go to **IAM & Admin → Service Accounts** and click **+ Create service account**
3. Name it `moselle-reader` and give it a description like "Moselle read-only access"
4. Click **Create and continue**, then **Done** (you'll grant roles in the next step)
   {% endtab %}

{% tab title="gcloud CLI" %}
Replace `<PROJECT_ID>` with your project ID.

{% code overflow="wrap" %}

```bash
gcloud iam service-accounts create moselle-reader \
  --project=<PROJECT_ID> \
  --display-name="Moselle read-only access"
```

{% endcode %}
{% endtab %}
{% endtabs %}

**Expected Result:** A service account with an email like `moselle-reader@<PROJECT_ID>.iam.gserviceaccount.com`.
{% endstep %}

{% step %}

### Grant read access

The service account needs three roles:

| Role                           | Where                  | What it allows                                      |
| ------------------------------ | ---------------------- | --------------------------------------------------- |
| **BigQuery Job User**          | Project                | Run read queries, billed to your project            |
| **BigQuery Read Session User** | Project                | Read table data efficiently, billed to your project |
| **BigQuery Data Viewer**       | Project or one dataset | Read the tables themselves                          |

{% tabs %}
{% tab title="Google Cloud console" %}

1. Go to **IAM & Admin → IAM** and click **+ Grant access**
2. In **New principals**, paste the service account email from step 1
3. Add the role **BigQuery Job User**
4. Add a second role, **BigQuery Read Session User**
5. Add a third role, **BigQuery Data Viewer**, then click **Save**

To limit Moselle to a single dataset instead of the whole project, skip **BigQuery Data Viewer** here and grant it on that dataset: open the dataset in **BigQuery Studio**, click **Sharing → Permissions → Add principal**, paste the service account email, and choose **BigQuery Data Viewer**.
{% endtab %}

{% tab title="gcloud CLI" %}
{% code overflow="wrap" %}

```bash
gcloud projects add-iam-policy-binding <PROJECT_ID> \
  --member="serviceAccount:moselle-reader@<PROJECT_ID>.iam.gserviceaccount.com" \
  --role="roles/bigquery.jobUser"

gcloud projects add-iam-policy-binding <PROJECT_ID> \
  --member="serviceAccount:moselle-reader@<PROJECT_ID>.iam.gserviceaccount.com" \
  --role="roles/bigquery.readSessionUser"

gcloud projects add-iam-policy-binding <PROJECT_ID> \
  --member="serviceAccount:moselle-reader@<PROJECT_ID>.iam.gserviceaccount.com" \
  --role="roles/bigquery.dataViewer"
```

{% endcode %}

To limit Moselle to a single dataset, grant **BigQuery Data Viewer** on that dataset from the console (**Sharing → Permissions**) instead of the project-wide binding above.
{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Job User** and **Read Session User** make your project the billing project for Moselle's reads — without **Read Session User** the connection test passes but table reads are denied. **Data Viewer** grants the read itself and can be narrowed to a single dataset. If you narrow it, tell us which dataset in step 5.
{% endhint %}
{% endstep %}

{% step %}

### Create a JSON key

{% tabs %}
{% tab title="Google Cloud console" %}

1. Go to **IAM & Admin → Service Accounts** and click `moselle-reader`
2. Open the **Keys** tab, then **Add key → Create new key**
3. Choose **JSON** and click **Create**

A file like `<PROJECT_ID>-xxxxxxxx.json` downloads to your computer.
{% endtab %}

{% tab title="gcloud CLI" %}
{% code overflow="wrap" %}

```bash
gcloud iam service-accounts keys create moselle-reader-key.json \
  --iam-account=moselle-reader@<PROJECT_ID>.iam.gserviceaccount.com
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
Google shows the private key only once, in this file. Keep it somewhere secure — you'll paste its contents into Moselle in step 5, and Moselle never shows it back to you.
{% endhint %}
{% endstep %}

{% step %}

### Gather your project details

Alongside the key, have these ready:

| Field          | Example                                                                                                   |
| -------------- | --------------------------------------------------------------------------------------------------------- |
| Project ID     | `acme-analytics-prod`                                                                                     |
| Location       | `US`, `EU`, or a region like `europe-west2`                                                               |
| Dataset        | `analytics`                                                                                               |
| Tables to sync | `analytics.sales_orders`, `analytics.inventory_levels`, `analytics.purchase_orders`, `analytics.products` |

Your project ID is shown in the project picker at the top of the Google Cloud console. Each dataset's location is on its **Details** tab in **BigQuery Studio**.
{% endstep %}

{% step %}

### Send it securely from Moselle

1. Log in to Moselle and go to **Settings → Integrations → BigQuery**, or open this link directly: [app.moselle.io/settings/integrations?integration=bigquery](https://app.moselle.io/settings/integrations?integration=bigquery)
2. Click **Connect** on the BigQuery card
3. In the **Credentials** box, paste:
   * The full contents of the **JSON key file** from step 3
   * Your **project ID** and **location**
   * The **datasets and tables** you want synced
4. Click **Send securely**

**Expected Result:** You'll see a **"BigQuery credentials sent"** confirmation. Our team takes it from there and will be in touch once the connection is live.

{% hint style="warning" %}
**Never share the key file over email, Slack, or chat.** The Settings form encrypts your credentials as soon as they reach us, and they are never shown again — so keep your own secure copy in case you need to rotate the key.
{% endhint %}

{% hint style="info" %}
The BigQuery card won't switch to **Connected** on its own — our team confirms with you directly once your first sync is verified.
{% endhint %}
{% endstep %}

{% step %}

### Connection test and table mapping

Once your key is submitted, the Moselle team runs a test read to confirm access to the tables you listed. If anything needs adjusting — most often a missing role or a dataset the account can't see — we'll contact you with the specific change needed.

We then schedule a short session to confirm which tables and columns feed your sales, inventory, purchase orders, and product catalog, and how sales roll up into Moselle channels.

**Expected Result:** Your BigQuery data is syncing into Moselle. From here it refreshes automatically.
{% endstep %}
{% endstepper %}

## What this costs you

{% hint style="info" %}
**Short version:** Moselle's reads are billed to your project under BigQuery's normal on-demand pricing. On a daily sync of typical sales and inventory tables this is usually a few dollars a month or less. Moselle adds **no storage cost**.
{% endhint %}

* **Tables** — read directly with BigQuery's Storage Read API, billed by the amount of data read. No query runs, so there is no scan charge.
* **Views** — run as a query on each sync, billed by the data scanned. Keeping the underlying tables partitioned by date, or having the view include only the history Moselle needs, keeps scans small.
* **Network egress** — Moselle reads from outside Google Cloud, so Google's network egress pricing may apply to the data read. For most sales and inventory tables this is small.
* **Storage** — **$0 added.** Moselle reads your existing tables and stores nothing new in your project.

## Revoking access

You stay in control. To pause or remove Moselle's access at any time:

* **Rotate the key** — delete the key from the service account's **Keys** tab and send a new one via the secure form
* **Remove access entirely** — delete the `moselle-reader` service account, or remove its IAM roles

## Frequently Asked Questions

<details>

<summary>Can I point Moselle at a view instead of a raw table?</summary>

Yes. Views are the easiest way to give Moselle exactly the columns and history it needs. Grant \*\*BigQuery Data Viewer\*\* on the dataset containing the view — and on the underlying dataset if the view reads from another one.

</details>

<details>

<summary>My data is spread across several projects. Which one do I use?</summary>

Moselle reads from one project, which is also the project billed for the reads. If some of your tables live in other projects, create views in that project that read from them, and grant \*\*BigQuery Data Viewer\*\* on the source datasets in the other projects.

</details>

<details>

<summary>Key creation is blocked by an organization policy. What now?</summary>

Ask your org admin to exempt this project from \`iam.disableServiceAccountKeyCreation\`, or \[contact us]\(mailto:<support@moselle.io>) and we'll work through an alternative with you.

</details>
