> For the complete documentation index, see [llms.txt](https://docs.mediarithmics.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.mediarithmics.io/setup-and-monitor/collect-and-manage-your-data/sync-with-your-data-warehouse/warehouse-compatibilities.md).

# Warehouse compatibilities

Supported warehouse providers, and the exact access each one needs.

## Your goal

Prepare your warehouse so the platform can read the data you want to expose - with the narrowest access that still supports the synchronisation strategy you need.

## Expected outcome

A dedicated service account, the right permissions, and a credentials file the platform accepts.

## Supported providers

| Provider            | Authentication                                                                            |
| ------------------- | ----------------------------------------------------------------------------------------- |
| **Google BigQuery** | A service account and a credentials JSON file.                                            |
| **Snowflake**       | A service account with key-pair authentication, and a credentials JSON file you assemble. |

In both cases the service account needs **at least read access** on the data you want to expose, plus **editing rights on the working schema** if you want strategies that handle updates and deletes. See [Sync with your data warehouse](/setup-and-monitor/collect-and-manage-your-data/sync-with-your-data-warehouse.md#the-decision-that-shapes-everything-else).

Where the warehouse is the [source of truth](/setup-and-monitor/plan-and-integrate/choose-your-deployment-mode.md#the-three-modes) for the datamart, the platform writes into it as well as reading from it, so a working schema is required rather than optional, and object storage in your environment is needed for [live tracking](/setup-and-monitor/collect-and-manage-your-data/sync-with-your-data-warehouse/replicate-live-tracking-to-your-warehouse.md).

## Google BigQuery

{% stepper %}
{% step %}

### Enable the Cloud Resource Manager API

In the Google Cloud Console, go to **APIs & Services > Library**, search for **Cloud Resource Manager API**, open it, and click **Enable**.
{% endstep %}

{% step %}

### Create a working schema, if you need one

Only required for strategies handling updates and deletes. Create a dedicated dataset in your project:

```sql
CREATE SCHEMA IF NOT EXISTS `project-name.mediarithmics_dataset`
OPTIONS (
  location = 'EU',
  description = 'Working schema mediarithmics'
);
```

{% endstep %}

{% step %}

### Create a dedicated service account

In the Google Cloud Console, under IAM & Admin > Service Accounts, select your project and create a service account, giving it a name, an ID, and a description.
{% endstep %}

{% step %}

### Grant access

Recommended - read-only access to your data, with these roles **at project level**:

* `bigquery.jobUser`
* `bigquery.dataViewer`

And, if applicable, this role **only on the working schema**:

* `bigquery.dataEditor`

<details>

<summary>Granting narrower access</summary>

If you do not want to give `bigquery.dataViewer` at project level, assign it only to specific datasets, tables, or views. In that case you must add these permissions **at project level**:

* `bigquery.datasets.get`
* `bigquery.tables.list`
* `bigquery.tables.get`

To assign them, create a custom role carrying the `bigquery.jobUser` role plus those three permissions.

If `bigquery.dataViewer` is still too broad, you can assign the `bigquery.tables.getData` permission at table level only.

</details>
{% endstep %}

{% step %}

### Generate a credentials JSON file

On the service account, open the **…** menu, choose **Manage keys**, then **Add key > Create new key**, select **JSON**, and create. The key downloads automatically.

{% hint style="warning" %}
You need at least the `roles/iam.serviceAccountKeyAdmin` role to perform these actions.
{% endhint %}
{% endstep %}
{% endstepper %}

## Snowflake

Connecting to Snowflake requires **key-pair authentication**.

{% stepper %}
{% step %}

### Create the service account and grant permissions

Start from this template. It creates a dedicated service account, role, and warehouse for mediarithmics; gives the service account read-only access on a database of your choice and all its content; and creates a working schema inside the database with full read and write access for the service account.

```sql
-- =============================================================
-- Setup variables - update these values for your environment
-- =============================================================
SET mics_username          = 'MICS_USER';
SET mics_default_warehouse = '<warehouse>';
SET mics_database          = '<database>';
SET mics_default_namespace = '<database.schema>';
SET mics_default_role      = 'MICS_ROLE';

USE ROLE ACCOUNTADMIN;

-- Provision resources: warehouse, role and service user
CREATE WAREHOUSE IF NOT EXISTS identifier($mics_default_warehouse);
CREATE ROLE IF NOT EXISTS identifier($mics_default_role);

CREATE USER IF NOT EXISTS identifier($mics_username)
    TYPE              = SERVICE
    DEFAULT_WAREHOUSE = $mics_default_warehouse
    DEFAULT_NAMESPACE = $mics_default_namespace
    DEFAULT_ROLE      = $mics_default_role;

-- Role assignments
GRANT ROLE identifier($mics_default_role) TO ROLE SYSADMIN;
GRANT ROLE identifier($mics_default_role) TO USER identifier($mics_username);

-- Warehouse access
GRANT USAGE ON WAREHOUSE identifier($mics_default_warehouse) TO ROLE identifier($mics_default_role);

-- Read-only access on the database, schemas, tables and views
-- (includes future objects to cover tables/views created later)
GRANT USAGE  ON DATABASE identifier($mics_database)                      TO ROLE identifier($mics_default_role);
GRANT USAGE  ON ALL SCHEMAS   IN DATABASE identifier($mics_database)     TO ROLE identifier($mics_default_role);
GRANT SELECT ON ALL TABLES    IN DATABASE identifier($mics_database)     TO ROLE identifier($mics_default_role);
GRANT SELECT ON ALL VIEWS     IN DATABASE identifier($mics_database)     TO ROLE identifier($mics_default_role);
GRANT SELECT ON FUTURE TABLES IN DATABASE identifier($mics_database)     TO ROLE identifier($mics_default_role);
GRANT SELECT ON FUTURE VIEWS  IN DATABASE identifier($mics_database)     TO ROLE identifier($mics_default_role);

-- Dedicated working schema with full ownership
USE identifier($mics_database);
CREATE SCHEMA IF NOT EXISTS mediarithmics_schema;
GRANT OWNERSHIP ON SCHEMA mediarithmics_schema TO ROLE identifier($mics_default_role);
```

Adapt it as needed:

* To restrict access to specific tables or views, the minimum permissions are `USAGE on DATABASE`, `USAGE on SCHEMA`, and `SELECT on TABLES` - or views.
* If you do not need the working schema, omit the last part of the script.
  {% endstep %}

{% step %}

### Configure key-pair authentication

Generate a private key:

```bash
openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out rsa_key.p8 -nocrypt
```

Then the matching public key:

```bash
openssl rsa -in rsa_key.p8 -pubout -out rsa_key.pub
```

Assign the public key to the service account, from the Snowflake interface or CLI:

```sql
ALTER USER <MICS_USER> SET RSA_PUBLIC_KEY='MIIBIjANBgkqh...';
```

{% hint style="info" %}

* **Exclude the public key delimiters** in the SQL statement.
* To run this query you need either the `MODIFY PROGRAMMATIC AUTHENTICATION METHODS` or `OWNERSHIP` privilege on the user, or the `SECURITYADMIN` role or higher.
  {% endhint %}
  {% endstep %}

{% step %}

### Assemble the credentials file

```json
{
  "user": "MICS_USER",
  "account": "ORGANIZATION_NAME-ACCOUNT_NAME",
  "database": "DATABASE",
  "private_key": "-----BEGIN PRIVATE KEY-----\nMII..."
}
```

| Field         | What it holds                                                                                      |
| ------------- | -------------------------------------------------------------------------------------------------- |
| `user`        | The user you associated the public key with.                                                       |
| `account`     | Snowflake's "account identifier" - usually the organisation name and the account name, hyphenated. |
| `database`    | The database containing the data you want to expose.                                               |
| `private_key` | The private key generated above, matching the public key on the user.                              |

{% hint style="warning" %}
The private key must be **on a single line**: replace every line break in the key with a `\n` separator.
{% endhint %}
{% endstep %}
{% endstepper %}

## Verify

* The credentials file is accepted when you declare the warehouse - an incorrect permission set raises an error at that point. See [Data warehouse sync](/setup-and-monitor/collect-and-manage-your-data/sync-with-your-data-warehouse/data-warehouse-sync.md).
* The service account can read the tables you intend to expose, and nothing more.
* If you created a working schema, the service account can write in it.

{% hint style="danger" %}
Credentials files contain private keys. Treat them as secrets: do not commit them, and do not paste them into shared documents or tickets.
{% endhint %}

## Related pages

<table data-view="cards" data-search="false"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Data warehouse sync</strong></td><td>Declaring the warehouse and choosing strategies.</td><td><a href="/setup-and-monitor/collect-and-manage-your-data/sync-with-your-data-warehouse/data-warehouse-sync.md">Data warehouse sync</a></td></tr><tr><td><strong>Sync with your data warehouse</strong></td><td>The working-schema decision, and the strategy table.</td><td><a href="/setup-and-monitor/collect-and-manage-your-data/sync-with-your-data-warehouse.md">Sync with your data warehouse</a></td></tr><tr><td><strong>Manage API access</strong></td><td>How credentials are handled elsewhere on the platform.</td><td><a href="/setup-and-monitor/manage-the-platform/manage-api-access.md">Manage API access</a></td></tr></tbody></table>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.mediarithmics.io/setup-and-monitor/collect-and-manage-your-data/sync-with-your-data-warehouse/warehouse-compatibilities.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
