> ## Documentation Index
> Fetch the complete documentation index at: https://docs.oleander.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# External Connections

> Connect BigQuery, Snowflake, and Snowflake Horizon to your oleander lake.

oleander lets you connect external storage systems so you can query them alongside your Iceberg tables — joining cloud warehouse data with your lake data in a single SQL statement.

Connections are managed in [Settings → Lake](https://oleander.dev/app/settings/lake).

***

## BigQuery

Connect a Google Cloud project to query BigQuery tables directly from the oleander lake via DuckDB.

### Setup

1. Navigate to [Settings → Lake](https://oleander.dev/app/settings/lake) and open **BigQuery connections**.
2. Give the connection a name (lowercase letters, numbers, underscores — e.g. `my_bq`).
3. Enter your GCP **Project ID**.
4. Paste your **service account JSON**. The service account needs `roles/bigquery.dataViewer` (or narrower table-level permissions).

The service account key is stored encrypted and is never returned to the browser after saving.

### Querying

Once connected, every BigQuery table in that project is reachable in DuckDB queries as `connection_name.dataset.table`:

```sql theme={null}
-- Query a BigQuery table
SELECT *
FROM my_bq.analytics.events
WHERE _PARTITIONDATE = '2024-06-01'
LIMIT 100;

-- Join BigQuery with your Iceberg lake
SELECT e.user_id, u.plan
FROM my_bq.analytics.events e
JOIN oleander.default.users u ON e.user_id = u.id
WHERE e.event_type = 'signup';
```

***

## Snowflake

Connect a Snowflake account to query your Snowflake tables from the oleander lake. Authentication uses key-pair signing — no passwords are stored.

### Setup

1. Navigate to [Settings → Lake](https://oleander.dev/app/settings/lake) and open **Snowflake connections**.
2. Fill in the required fields:

| Field                  | Description                                                                                        |
| ---------------------- | -------------------------------------------------------------------------------------------------- |
| **Name**               | A short identifier for this connection (e.g. `prod_sf`)                                            |
| **Account identifier** | Your Snowflake account in `orgname-accountname` format                                             |
| **Username**           | The Snowflake user to authenticate as                                                              |
| **Private key**        | RSA private key in PEM format (the user must have the matching public key registered in Snowflake) |

3. Optionally specify a default **warehouse**, **database**, and **role** to scope queries.

### Generating a key pair

If you don't already have a key pair registered with Snowflake:

```bash theme={null}
# Generate an RSA key pair
openssl genrsa -out snowflake_key.pem 2048
openssl rsa -in snowflake_key.pem -pubout -out snowflake_key.pub

# Register the public key with your Snowflake user
ALTER USER my_user SET RSA_PUBLIC_KEY='<contents of snowflake_key.pub>';
```

Paste the contents of `snowflake_key.pem` into the **Private key** field in oleander. The key is stored encrypted.

### Querying

Tables are accessible as `connection_name.schema.table` in DuckDB:

```sql theme={null}
-- Query a Snowflake table
SELECT *
FROM prod_sf.public.orders
WHERE created_at >= '2024-01-01'
LIMIT 100;

-- Join Snowflake with your Iceberg lake
SELECT o.order_id, c.segment
FROM prod_sf.public.orders o
JOIN oleander.default.customers c ON o.customer_id = c.id;
```

***

## Snowflake Horizon

Snowflake Horizon is Snowflake's built-in Iceberg catalog, powered by [Polaris](https://www.polaris.io/). Registering it in oleander gives you full Iceberg REST catalog access — including DuckDB queries, Polars workloads, and Spark jobs — against your Snowflake-managed Iceberg tables.

### Setup

1. Navigate to [Settings → Lake](https://oleander.dev/app/settings/lake) and open **External catalogs**.
2. Select **Snowflake Horizon** as the catalog type.
3. Fill in the required fields:

| Field              | Description                                                                           |
| ------------------ | ------------------------------------------------------------------------------------- |
| **Name**           | A short catalog name (e.g. `sf_horizon`)                                              |
| **Catalog URI**    | Your Snowflake account URL, e.g. `https://orgname-accountname.snowflakecomputing.com` |
| **Database**       | The Snowflake database to expose as an Iceberg catalog                                |
| **Role**           | The Snowflake role used to access the catalog                                         |
| **Cloud provider** | `aws`, `gcp`, or `azure`                                                              |
| **Region**         | The cloud region your Snowflake account is in                                         |

4. Choose an authentication method:

<Tabs>
  <Tab title="Personal Access Token (PAT)">
    Generate a PAT in Snowflake and paste it into the **Secret** field. This is the simplest option.

    ```sql theme={null}
    -- Generate a PAT in Snowflake
    ALTER USER my_user ADD PROGRAMMATIC ACCESS TOKEN my_pat;
    ```
  </Tab>

  <Tab title="Key-pair">
    Use an RSA key pair for authentication. Provide:

    | Field           | Description                                   |
    | --------------- | --------------------------------------------- |
    | **Username**    | The Snowflake user                            |
    | **Private key** | RSA private key in PEM format                 |
    | **Passphrase**  | Passphrase for the private key (if encrypted) |

    The same key pair used for a Snowflake connection can be reused here.
  </Tab>
</Tabs>

### Querying

Once registered, the catalog is available under its name in DuckDB, Polars, and Spark:

```sql theme={null}
-- DuckDB: query a Snowflake Horizon Iceberg table
SELECT species, COUNT(*) AS n
FROM sf_horizon.default.flowers
GROUP BY 1
ORDER BY n DESC;
```

```python theme={null}
# Polars script mode
flowers = scan("sf_horizon.default.flowers")
result = flowers.group_by("species").agg(pl.len().alias("count"))
```

<Note>
  Credential vending is handled automatically via the Iceberg REST protocol — no S3 or GCS credentials need to be configured manually.
</Note>
