# Connect Databricks SQL with a service principal

## When to use this

You want a Databricks SQL warehouse behind a swarmvia endpoint: agents and
scheduled jobs under one concurrency limit, authenticated as a service
principal whose secret never leaves swarmvia. The Databricks JDBC driver is
on Maven Central and takes an OAuth machine-to-machine token.

## Setup

### 1. The service principal

In the account console create a service principal, give it **Can use** on the
SQL warehouse and `SELECT` on the catalogs and schemas it should read, then
generate an OAuth secret for it. Unity Catalog grants are the boundary;
Databricks runs every statement as the principal.

### 2. The source

**Sources → New source → JDBC data source → Databricks SQL.** Placeholders
come from the warehouse's *Connection details* tab: workspace host and HTTP
path. The URL becomes:

```
jdbc:databricks://dbc-a1b2345c-d6e7.cloud.databricks.com:443;httpPath=/sql/1.0/warehouses/abc123
```

### 3. The credential

**OAuth 2.0 client credentials**: token URL
`https://{workspace-host}/oidc/v1/token`, client id and secret from step 1,
scope `all-apis`, token property `Auth_AccessToken`. The preset sets
`AuthMech=11` and `Auth_Flow=0`, which is how the driver takes a token you
supply instead of fetching one itself.

A personal access token works too, as the secret property `PWD` with `UID`
set to `token`, but it belongs to a person and expires with them.

### 4. Query

```bash
curl https://databricks.swarmvia.cloud \
  -H "X-Swarmvia-Key: $SWARMVIA_KEY" \
  -H "content-type: application/json" \
  -d '{"queries":[{"sql":"SELECT c.country, COUNT(*) FROM main.sales.orders o JOIN main.sales.customers c USING (customer_id) WHERE o.ordered_at >= ? GROUP BY 1","params":["2026-01-01"]}]}'
```

## Tips

- A stopped warehouse starts on the first query and the connection waits for
  it; set the source's statement timeout above the warehouse's start time or
  the first call of the morning fails with `57014`.
- The Databricks driver buffers results aggressively. If wide results hit
  `max_result_bytes`, lower `maxRows` per query.

## See also

- [JDBC sources](/docs/sources/jdbc)
- [Async](/docs/sources/async) for queries that outlive `waitMs`
