Intermediate·Lakebase

Connecting to Lakebase, roles and permissions

kept in this browser

How clients reach a Lakebase compute over TLS, the choice between one-hour OAuth tokens and Postgres passwords, and how Databricks identities become roles.

On this page14

What it is

A Lakebase compute is reached like any Postgres server: a host, port 5432, a database, a user and a password, over TLS. What is particular to Lakebase is where the password comes from and what the user is.

  • The user is a Postgres role. It can stand for a Databricks identity — a user, a service principal or a group — or be a plain Postgres role with a password.
  • The password is either a short-lived OAuth token issued by Databricks for that identity, or a native Postgres password that does not expire.

Any Postgres client works: psql, pgAdmin, DBeaver, JDBC and every language driver.

Why it exists

A database password is a long-lived secret that ends up in configuration files, CI variables and laptops, and nobody knows who else holds it. Databricks already knows who a user or a service principal is; issuing a token from that identity means the database login inherits the platform’s identity, its group memberships and its offboarding. When someone leaves, their Databricks access is removed and their tokens stop being issued.

Native passwords remain for the clients that cannot fetch a token every hour, and for the connection pooler, which does not accept tokens.

How it works

The connection string

Each compute has a host of the form ep-…, carrying the compute’s identifier; the regional form is ep-….database.<region>.cloud.databricks.com. TLS is mandatory:

host=ep-xxxx.database.us-east-1.cloud.databricks.com port=5432 dbname=databricks_postgres user=alice@example.com sslmode=require

The branch’s page in the Lakebase app shows the exact string for each compute and role.

OAuth tokens

A token is valid for one hour and is checked only when the connection is opened. An open connection is not closed when its token expires, but every new connection needs a current one. A token is scoped to one workspace.

databricks postgres generate-database-credential \
  projects/shop/branches/production/endpoints/primary --output json
from databricks.sdk import WorkspaceClient
import psycopg

w = WorkspaceClient()
cred = w.postgres.generate_database_credential(
    endpoint="projects/shop/branches/production/endpoints/primary"
)

with psycopg.connect(
    host="ep-xxxx.database.us-east-1.cloud.databricks.com",
    dbname="databricks_postgres",
    user="alice@example.com",
    password=cred.token,
    sslmode="require",
) as conn:
    print(conn.execute("select current_user").fetchone())

A long-running service must fetch a fresh token before opening new connections, typically in the pool’s connection factory rather than once at start-up.

Native passwords

A Postgres role with a password connects without Databricks in the path, and the password does not expire. For projects created since May 2026, password logins are off by default; they are switched on under the project’s settings, in Database connections. Store such passwords as secrets (see Secrets and credentials), never in code.

Every connection, whatever the login

Two limits apply to all connections: one idle for 24 hours is closed, and one open for three days may be closed. Clients should expect to reconnect.

Roles for Databricks identities

The project owner’s role exists from the start. For anyone else, a role is created for their Databricks identity, from the Lakebase app, the REST API, or SQL:

CREATE EXTENSION IF NOT EXISTS databricks_auth;

SELECT databricks_create_role('alice@example.com', 'USER');
SELECT databricks_create_role('data-apps', 'GROUP');

The type is USER, SERVICE_PRINCIPAL or GROUP. A new role receives LOGIN and nothing else: what it may read or write is granted separately, with ordinary Postgres grants. A group role is shared by its members: anyone in the Databricks group can log in as it. Group names are case-sensitive.

databricks_superuser

Lakebase does not hand out the real Postgres superuser. In its place is databricks_superuser, a role with CREATEDB, CREATEROLE and BYPASSRLS, which inherits pg_read_all_data, pg_write_all_data and pg_monitor. It cannot log in itself (NOLOGIN); roles are made members of it. The project owner is.

Membership is effectively full access to the data on that branch, row-level security included. Grant it to people who administer the database, not to applications.

Granting access

Permissions inside the database are plain Postgres:

GRANT USAGE ON SCHEMA orders TO "data-apps";
GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA orders TO "data-apps";
ALTER DEFAULT PRIVILEGES IN SCHEMA orders GRANT SELECT, INSERT, UPDATE ON TABLES TO "data-apps";

These are separate from the project permissions (CAN CREATE, CAN USE, CAN MANAGE), which govern branches and computes, and from Unity Catalog grants, which govern warehouse queries on a registered catalog. See Privileges: GRANT, REVOKE, and DENY for the Unity Catalog side.

The connection pooler

Each compute has a built-in PgBouncer in transaction mode, on a host of the form <endpoint-id>-pooler…, accepting up to 10,000 client connections and sharing a much smaller number of Postgres connections among them. It suits serverless functions and applications with many short connections.

It has two restrictions that decide whether you can use it:

  • It accepts password roles only, not OAuth tokens.
  • In transaction mode, anything tied to a session breaks: SQL PREPARE, session-level SET, LISTEN/NOTIFY, advisory locks. pg_dump and schema migrations must connect directly, not through the pooler.

Not supported

Native logical replication and tablespaces are not available. Changes leave Postgres through the Lakebase change data feed, from Postgres into Delta instead.

Example

A reporting service that logs in as a service principal, with a role that can only read one schema:

CREATE EXTENSION IF NOT EXISTS databricks_auth;
SELECT databricks_create_role('4f1c2e9a-…', 'SERVICE_PRINCIPAL');   -- the application ID
GRANT USAGE ON SCHEMA reporting TO "4f1c2e9a-…";
GRANT SELECT ON ALL TABLES IN SCHEMA reporting TO "4f1c2e9a-…";

The service authenticates to Databricks as the service principal, requests a token each time its pool opens a connection, and connects directly to the compute. It cannot write, and it cannot see any other schema.

Common mistakes

  • Caching one token for the life of the process. It works for an hour, then every new connection fails. Refresh per connection.
  • Pointing an OAuth client at the pooler. The pooler takes passwords only.
  • Running migrations through the pooler. Session state and pg_dump need a direct connection.
  • Granting databricks_superuser to an application. It bypasses row-level security and can read and write everything.
  • Forgetting sslmode=require. Connections without TLS are refused.
  • Assuming a new role can read. databricks_create_role gives login only; grants come after.
Report a problem with this page
What kind of problem?

Reports about "Connecting to Lakebase, roles and permissions" go to the maintainer, not to a public thread.

Suggest a resource
What kind?

Nothing appears on the site automatically. A person reads every suggestion, checks the link and writes the note that goes with it.