Connecting Databricks
Read the concepts first for push vs pull and snapshots. This page covers what is specific to Databricks.
Where the data comes from
Databricks keeps usage history in system tables in the system catalog,
managed by Unity Catalog:
| Schema | What it holds |
|---|---|
system.billing |
Usage in DBUs and the list prices |
system.compute |
Cluster and SQL-warehouse configuration |
system.lakeflow |
Jobs and job runs |
system.query |
SQL query history |
system.serving |
Model-serving endpoints and their usage |
We read only these. They are separate from your own catalogs, so granting access
to system gives no access to your data.
Prerequisites
- A workspace on Unity Catalog. Without it there are no system tables.
- Databricks Community Edition won't work (no system tables). A trial or paid account on AWS, Azure or GCP does.
- A metastore admin to enable system schemas and grant access.
- For pull mode, an account admin to create the service principal and secret.
Enable the system schemas first
Some system schemas are off until an admin enables them (billing is on by default).
Find your metastore id (Catalog Explorer → metastore details, or
databricks metastores current), then:
databricks system-schemas enable <metastore-id> compute
databricks system-schemas enable <metastore-id> lakeflow
databricks system-schemas enable <metastore-id> query
databricks system-schemas enable <metastore-id> serving
Data starts accumulating from the moment a schema is enabled, so enable them early.
Option A — Push (recommended)
You import a ready-made notebook and schedule it as a daily job. It reads the system tables inside your workspace and uploads the result to us. We have no credential for your workspace and no way in.
Teksoptima Your Databricks workspace
────────── ─────────────────────────
Generates a notebook + upload token ────► 1. Store the token in a secret scope
2. Import the notebook
3. Schedule it as a daily Job
4. Job reads system.* (SELECT only)
validates + stores snapshot ◄─────────── 5. Uploads gzip'd parts over HTTPS
The pieces
| Piece | Concept |
|---|---|
| Secret scope | Databricks' vault. Named teksoptima; holds the upload token (and your salt). The notebook reads it at run time, so the notebook itself contains no secret and can be reviewed, shared, or put in Git. |
| Notebook | Plain, readable code. You can read exactly what leaves your workspace before scheduling it. |
| Job owner | The user or service principal the job runs as. It needs the grants below. |
| Daily job | The schedule. Pause or delete it and uploads stop. |
Grants
Run as a metastore admin; <job-owner> is who the job runs as:
GRANT USE CATALOG ON CATALOG system TO `<job-owner>`;
GRANT USE SCHEMA, SELECT ON SCHEMA system.billing TO `<job-owner>`;
GRANT USE SCHEMA, SELECT ON SCHEMA system.compute TO `<job-owner>`;
GRANT USE SCHEMA, SELECT ON SCHEMA system.lakeflow TO `<job-owner>`;
GRANT USE SCHEMA, SELECT ON SCHEMA system.query TO `<job-owner>`;
GRANT USE SCHEMA, SELECT ON SCHEMA system.serving TO `<job-owner>`;
That's the entire permission footprint: SELECT on metadata, nothing on your data.
Privacy options in the notebook
- Pseudonymise identities (on by default). Emails (query authors, cluster
owners, job run-as) are replaced with
user-+ 12 characters of a salted hash, computed inside your workspace before upload. The salt lives in your secret scope and we never receive it, so we can't reverse it. You can map a hash back to a person with one query in your own workspace. Hashes are stable across uploads, so per-user findings still work. - Share query text (off by default). See the concepts.
Stopping it
Delete the job, or regenerate the upload token in Teksoptima — the old one stops working at once.
Option B — Pull (live) with a service principal
Here Teksoptima connects to your workspace itself. Databricks uses OAuth machine-to-machine (M2M): a non-human identity authenticates with a client ID and secret and receives a short-lived token.
The key idea: a service principal, not a person
A service principal is an identity for software. Using one means the connection doesn't depend on someone's login, MFA or job status, and you can grant it only the access it needs and see exactly what it did.
Like Snowflake, the service principal and its secret belong to your account, so each customer creates their own and enters it in the connection wizard. No Databricks credential is shared across customers.
Moving parts
| Piece | What it is / where to find it |
|---|---|
| Workspace host | The address you sign in at, e.g. dbc-a1b2c3d4-e5f6.cloud.databricks.com (no https://). |
| Workspace ID | The number after ?o= in the URL, or SELECT DISTINCT workspace_id FROM system.billing.usage. |
| SQL warehouse ID | SQL Warehouses → your warehouse → Connection details; the last part of /sql/1.0/warehouses/<id>. |
| Service principal | Account console → User management → Service principals → Add. Its Application ID is the client ID. |
| Client secret | The same principal → Secrets → Generate secret. Shown once; needs an account admin. |
| Grants | The same GRANT statements as above, to the service principal. |
| A small SQL warehouse | Our queries run on it. Use a small one with auto-stop so it's only awake during a pull. |
How a pull works
- We exchange the client ID and secret for an access token at your workspace's
/oidc/v1/token(grant_type=client_credentials). - We run the dataset queries on the warehouse you designated, using the SQL Statement Execution API.
- We store the results as a snapshot.
The access token lasts about an hour and is kept in memory only, never saved. Only the client secret is stored, encrypted (AES-256-GCM), and it is never shown, logged or returned to the browser again after you save it.
Verify the grants
The wizard runs a harmless SELECT … LIMIT 0 against each system table and tells
you by name which one is missing.
Seeing what we did
Every query the service principal runs appears in your own query history and audit log, so you don't have to take our word for it:
SELECT start_time, statement_text
FROM system.query.history
WHERE executed_by = '<service-principal-application-id>'
ORDER BY start_time DESC;
Things that commonly go wrong
| Symptom | Cause |
|---|---|
| "Databricks refused the client id or secret" | Wrong pair, or the principal has no OAuth secret in this workspace; make sure it's added to the workspace. |
| A specific system table is reported missing | That schema isn't enabled, or the grant wasn't applied to the principal. |
| Empty billing or query screens right after setup | Schemas only collect data from when they were enabled; check back after a day. |
| Pulls fail with a warehouse error | The warehouse id is wrong, deleted, or the principal lacks CAN USE on it. |
Undoing it
REVOKE the grants, delete the secret, or delete the service principal — each
cuts access immediately. Switching the connection back to push deletes the
stored secret.
Which should I pick?
- Push if you can import a notebook and schedule a job. We hold nothing of yours and have no inbound path.
- Pull if you'd rather not run a job in your workspace and are comfortable creating a service principal that we hold an encrypted secret for.