O Lakebase suporta dois modelos de autenticação independentes: OAuth com identidade Databricks e roles nativas Postgres com senha. Os dois coexistem no mesmo banco, e você escolhe qual usar por identidade ou por caso de uso.

Databricks identities e Postgres roles são sistemas separados. Não há sync automático entre eles. Criar um usuário no Databricks não cria uma role no banco.

Pré-requisito: extensão databricks_auth

Para criar roles OAuth (usuários, service principals, grupos), habilite a extensão no banco de destino:

CREATE EXTENSION IF NOT EXISTS databricks_auth;

Execute isso uma vez por banco. A extensão disponibiliza a função databricks_create_role().


1. Roles OAuth (identidades Databricks)

Usuário

SELECT databricks_create_role('[email protected]', 'USER');

O usuário se autentica gerando um token OAuth via CLI e usando como senha:

databricks postgres generate-database-credential \
  projects/<project-id>/branches/production/endpoints/primary
 
# ou para instâncias Provisioned
databricks database generate-database-credential \
  --request-id $(uuidgen) \
  --json '{"instance_names": ["nome-da-instancia"]}'

Conectar com psql:

export PGPASSWORD="<token gerado acima>"
psql -h <host> -p 5432 -d databricks_postgres -U [email protected]

Service Principal

SELECT databricks_create_role('8c01cfb1-62c9-4a09-88a8-e195f4b01b08', 'SERVICE_PRINCIPAL');

Use o Application ID (UUID) do service principal, não o display name. O PGUSER na string de conexão também é esse UUID.

Grupo

SELECT databricks_create_role('Nome do Grupo', 'GROUP');

Qualquer membro direto ou indireto do grupo pode se autenticar como a role do grupo usando seu token OAuth individual. A validação de membro acontece apenas no momento da autenticação: membros removidos do grupo têm conexões ativas mantidas, mas novas tentativas são recusadas.

export PGPASSWORD="<token OAuth do membro>"
psql -h <host> -p 5432 -d databricks_postgres -U "Nome do Grupo"

2. Roles nativas com senha

Habilite no projeto antes de usar: Settings → Enable Postgres Native Role Login.

CREATE ROLE app_readonly WITH LOGIN PASSWORD 'S3nh@F0rte#2026!';

Requisitos de senha: mínimo 12 caracteres com letras minúsculas, maiúsculas, número e símbolo.

Senhas não expiram automaticamente e são compatíveis com PgBouncer. Use para aplicações que não conseguem renovar credenciais a cada hora.


3. Permissões no banco

System roles pré-criadas

RoleO que tem
databricks_superuserALL PRIVILEGES em todos os databases, schemas e tabelas. Não faz login diretamente.
Role do criador do projetoMembro do databricks_superuser. Dono do banco databricks_postgres.

databricks_create_role() cria a role com permissão de LOGIN apenas. Após criar, conceda permissões explicitamente.

Granularidade de permissões

-- Acesso de leitura a uma tabela específica
GRANT SELECT ON TABLE app.pedidos TO "[email protected]";
 
-- Acesso de escrita
GRANT INSERT, UPDATE, DELETE ON TABLE app.pedidos TO "[email protected]";
 
-- Usar um schema (obrigatório antes de acessar objetos dentro dele)
GRANT USAGE ON SCHEMA app TO "[email protected]";
 
-- Criar objetos dentro de um schema
GRANT CREATE ON SCHEMA app TO "[email protected]";
 
-- Acesso completo a um banco
GRANT ALL PRIVILEGES ON DATABASE databricks_postgres TO app_user;

Default privileges para objetos futuros

Tabelas criadas depois do GRANT não herdam permissões automaticamente. Use ALTER DEFAULT PRIVILEGES para cobrir criações futuras:

ALTER DEFAULT PRIVILEGES IN SCHEMA app
GRANT SELECT ON TABLES TO app_readonly;
 
ALTER DEFAULT PRIVILEGES IN SCHEMA app
GRANT INSERT, UPDATE, DELETE ON TABLES TO app_writer;

4. Service principal em aplicações externas (M2M)

O fluxo machine-to-machine usa o Databricks SDK para gerar tokens OAuth de curta duração (60 minutos) e renová-los automaticamente no pool de conexões.

Configuração do service principal

  1. Crie o service principal em Settings → Identity and access → Service principals
  2. Gere um OAuth secret (lifetime de até 730 dias)
  3. Habilite “Workspace access”
  4. Anote o Client ID (UUID)

Criar a role no banco

CREATE EXTENSION IF NOT EXISTS databricks_auth;
SELECT databricks_create_role('8c01cfb1-62c9-4a09-88a8-e195f4b01b08', 'SERVICE_PRINCIPAL');
GRANT USAGE ON SCHEMA app TO "8c01cfb1-62c9-4a09-88a8-e195f4b01b08";
GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA app TO "8c01cfb1-62c9-4a09-88a8-e195f4b01b08";

Variáveis de ambiente necessárias

DATABRICKS_HOST=https://<workspace>.azuredatabricks.net
DATABRICKS_CLIENT_ID=8c01cfb1-62c9-4a09-88a8-e195f4b01b08
DATABRICKS_CLIENT_SECRET=<oauth-secret>
 
PGHOST=<host do endpoint>
PGPORT=5432
PGDATABASE=databricks_postgres
PGUSER=8c01cfb1-62c9-4a09-88a8-e195f4b01b08  # o UUID, não o display name
PGSSLMODE=require
LAKEBASE_ENDPOINT=projects/<id>/branches/production/endpoints/primary

Obter host e endpoint via CLI

databricks postgres list-endpoints \
  projects/<project-id>/branches/production -o json
 
databricks postgres list-databases \
  projects/<project-id>/branches/production -o json

Rotação de token em Python (psycopg3)

O pool chama generate_database_credential() ao abrir cada nova conexão, garantindo token fresco:

import uuid
import psycopg3
from psycopg3.pool import ConnectionPool
from databricks.sdk import WorkspaceClient
 
w = WorkspaceClient()  # lê DATABRICKS_HOST, CLIENT_ID, CLIENT_SECRET do ambiente
 
endpoint = os.environ["LAKEBASE_ENDPOINT"]
 
def get_connection():
    token = w.database.generate_database_credential(
        request_id=str(uuid.uuid4()),
        endpoint_name=endpoint,
    ).token
    conn_str = (
        f"host={os.environ['PGHOST']} port=5432 "
        f"dbname={os.environ['PGDATABASE']} "
        f"user={os.environ['PGUSER']} password={token} sslmode=require"
    )
    return psycopg3.connect(conn_str)
 
pool = ConnectionPool(open=get_connection, min_size=2, max_size=10)

Rotação de token em Java (HikariCP)

Configure maxLifetime de 45 minutos para reciclar conexões antes do token expirar (token dura 60 min):

HikariConfig config = new HikariConfig();
config.setMaxLifetime(45 * 60 * 1000); // 45 minutos em ms
config.setDataSource(new LakebaseDataSource(workspaceClient, endpointName));
HikariDataSource pool = new HikariDataSource(config);

Verificar identidade conectada

SELECT current_user, current_database();
-- retorna o UUID do service principal como current_user

5. Permissões por branch

Branches herdam as roles e permissões do banco no momento da criação. Cada nova branch já tem todas as roles existentes.

Criar uma branch

databricks postgres create-branch projects/<project-id> feature-xyz \
  --json '{"spec": {"ttl": "7d"}}'

A branch exige uma política de expiração: ttl (duração relativa), expire_time (data absoluta) ou no_expiry: true.

Proteger a branch de produção

databricks postgres update-branch \
  projects/<project-id>/branches/production \
  spec.is_protected \
  --json '{"spec": {"is_protected": true}}'

Branches protegidas não podem ser deletadas acidentalmente.

Adicionar um colaborador a uma branch específica

Pela UI: Branch Overview → Add role → selecione a identidade → atribua databricks_superuser ou uma role customizada.

Por SQL, conectado à branch de destino:

-- Dar permissão a um usuário específico apenas nessa branch
GRANT USAGE ON SCHEMA app TO "[email protected]";
GRANT SELECT ON ALL TABLES IN SCHEMA app TO "[email protected]";

Roles criadas em uma branch existem apenas nessa branch. Roles do banco-pai existem em todas as branches criadas a partir dele.


6. Registro no Unity Catalog (acesso read-only via lakehouse)

Registrar o banco no Unity Catalog cria um catálogo read-only, acessível via SQL Warehouses e notebooks sem conexão Postgres direta.

Requisito: privilégio CREATE CATALOG no metastore.

-- Após registro, conceder acesso ao catálogo criado
GRANT USE CATALOG ON CATALOG lakebase_prod TO `time-de-dados`;
GRANT SELECT ON CATALOG lakebase_prod TO `time-de-dados`;

O catálogo UC é read-only. Writes continuam via conexão Postgres direta.


Limites de conexão

LimiteValor
Idle timeout24 horas
Lifetime máximo por conexão3 dias
Expiração do token OAuth60 minutos (enforcement só no login)
Expiração do OAuth secret do SPaté 730 dias

Conexões

Referências