Fournit un pool de connexions PostgreSQL pour Databricks Lakebase Autoscaling, avec actualisation automatique des tokens OAuth.
Fonctionnalités clés :
pg.Pool standard, compatible avec n'importe quelle bibliothèque PostgreSQL ou ORM
Actualisation automatique des tokens OAuth (tokens d'une heure, marge d'actualisation de 2 minutes)
Mise en cache des tokens pour limiter les appels d'API
Instrumentation OpenTelemetry intégrée (durée des requêtes, connexions du pool, actualisation des tokens)
Logger AppKit configuré par défaut pour les événements de requête et de connexion
Premiers pas avec Lakebase
Le moyen le plus simple de démarrer avec le plugin Lakebase est d'utiliser la Databricks CLI pour créer une nouvelle application Databricks avec AppKit et le plugin Lakebase déjà installés.
Pour ajouter le plugin Lakebase à votre projet, exécutez la commande databricks apps init, puis sélectionnez le plugin Lakebase dans le menu interactif. La CLI vous guide ensuite dans le choix d'un projet, d'une branche et d'une base de données Lakebase.
Lorsque la question vous est posée, répondez Yes pour déployer l'application sur Databricks Apps dès sa création.
Utilisation de base
import { createApp, lakebase, server } from "@databricks/appkit";await createApp({ plugins: [server(), lakebase()],});
Accéder au pool
Une fois l'initialisation effectuée, accédez à Lakebase via l'objet AppKit.lakebase :
const AppKit = await createApp({ plugins: [server(), lakebase()],});await AppKit.lakebase.query(`CREATE SCHEMA IF NOT EXISTS app`);await AppKit.lakebase.query(`CREATE TABLE IF NOT EXISTS app.orders ( id SERIAL PRIMARY KEY, user_id VARCHAR(255) NOT NULL, amount DECIMAL(10, 2) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)`);const result = await AppKit.lakebase.query( "SELECT * FROM app.orders WHERE user_id = $1", [userId],);// pg.Pool brut (pour les ORM ou un usage avancé)const pool = AppKit.lakebase.pool;// Objets de configuration prêts à l'emploi pour les ORMconst ormConfig = AppKit.lakebase.getOrmConfig(); // { host, port, database, ... }const pgConfig = AppKit.lakebase.getPgConfig(); // pg.PoolConfig
Configuration
Variables d'environnement
Les variables d'environnement requises sont les suivantes :
Variable
Description
LAKEBASE_ENDPOINT
Chemin de la ressource endpoint (ex. projects/.../branches/.../endpoints/...)
PGHOST
Hôte Lakebase (injecté automatiquement en production par la ressource Databricks Apps postgres)
PGDATABASE
Nom de la base de données (injecté automatiquement en production par la ressource Databricks Apps postgres)
PGSSLMODE
Mode TLS - défini sur require (injecté automatiquement en production par la ressource Databricks Apps postgres)
Lors d'un déploiement sur Databricks Apps avec une ressource de base de données postgres configurée, les variables PGHOST, PGDATABASE, PGSSLMODE, PGUSER, PGPORT et PGAPPNAME sont injectées automatiquement par la plateforme. Seule LAKEBASE_ENDPOINT doit être définie explicitement :
Pour le développement local, le fichier .env est généré automatiquement par databricks apps init avec les valeurs correspondant à votre projet Lakebase.
Pour la référence complète de la configuration (SSL, taille du pool, délais d'expiration, journalisation, exemples d'ORM), consultez le README de @databricks/lakebase.
Configuration du pool
Passez un objet pool pour remplacer les valeurs par défaut :
await createApp({ plugins: [ lakebase({ pool: { max: 10, // Nombre max. de connexions du pool (par défaut : 10) connectionTimeoutMillis: 5000, // Délai d'attente de connexion en ms (par défaut : 10000) idleTimeoutMillis: 30000, // Délai d'inactivité des connexions en ms (par défaut : 30000) }, }), ],});
On-Behalf-Of (OBO) — connexions par utilisateur
Lorsque votre application nécessite la sécurité au niveau des lignes (RLS) ou une isolation des données par utilisateur, utilisez asUser(req) pour exécuter les requêtes via un pool de connexions Lakebase propre à chaque utilisateur. Le pool de chaque utilisateur est authentifié avec son identité Databricks : le current_user de PostgreSQL correspond donc à l'utilisateur réel.
Prérequis
Activez l'autorisation utilisateur dans votre Databricks App avec le scope postgres. Consultez User authorization pour les instructions de configuration. Dans votre databricks.yml :
resources: apps: app: user_api_scopes: - postgres
Les applications dont l'ossature est générée avec databricks apps init et le plugin Lakebase incluent cette configuration automatiquement.
Chaque utilisateur de l'application doit disposer d'un rôle Postgres dans Lakebase. Créez-en un avec la Databricks CLI :
Vous pouvez également créer des rôles dans l'interface Lakebase, sous Branch Overview → Add role.
note
N'accordez pas databricks_superuser aux utilisateurs OBO — les superutilisateurs contournent la RLS. Utilisez plutôt des grants à granularité fine.
Utilisation
Aucune configuration nécessaire — il suffit d'appeler asUser(req) :
const AppKit = await createApp({ plugins: [server(), lakebase()],});// Requête via le service principal (par défaut — contourne la RLS en tant que propriétaire de la table)const all = await AppKit.lakebase.query("SELECT * FROM app.orders");// Requête dans le contexte de l'utilisateur (pool par utilisateur, RLS appliquée)app.get("/api/my-orders", async (req, res) => { const result = await AppKit.lakebase .asUser(req) .query("SELECT * FROM app.orders ORDER BY created_at DESC"); res.json(result.rows);});
Lorsque asUser(req) est appelé :
Le token et l'identité de l'utilisateur sont extraits des en-têtes x-forwarded-access-token et x-forwarded-email (définis automatiquement par Databricks Apps).
Un pg.Pool propre à l'utilisateur est créé (ou réutilisé) à partir de ses identifiants OAuth.
query() et pool utilisent le pool de l'utilisateur — current_user dans PostgreSQL reflète son identité.
Exemple de sécurité au niveau des lignes
-- En tant que service principal (lors de la configuration de l'application) :ALTER TABLE app.orders ENABLE ROW LEVEL SECURITY;CREATE POLICY user_orders ON app.orders FOR ALL TO PUBLIC USING (owner = current_user);-- Accorder les droits pour que les utilisateurs OBO puissent interroger les donnéesGRANT USAGE ON SCHEMA app TO PUBLIC;GRANT SELECT, INSERT ON ALL TABLES IN SCHEMA app TO PUBLIC;
Fonctionnement
Le pool du service principal (AppKit.lakebase.pool) est toujours créé et utilisé pour les opérations DDL, l'amorçage des données et les requêtes d'administration.
Les pools par utilisateur sont créés au premier appel à asUser(req) et mis en cache par identité d'utilisateur. Chaque pool dispose de son propre cycle d'actualisation du token OAuth.
Les connexions inactives au sein des pools par utilisateur se ferment automatiquement (délai d'inactivité de 30 s). Les objets de pool vides sont nettoyés périodiquement.
À l'arrêt, tous les pools (service principal + utilisateur) sont fermés proprement.
En mode développement (NODE_ENV=development), si aucun token utilisateur n'est disponible, asUser(req) bascule sur le pool du service principal en émettant un avertissement.
RLS et superutilisateurs
Les superutilisateurs PostgreSQL contournent entièrement la sécurité au niveau des lignes (RLS). Les utilisateurs disposant du rôle databricks_superuser verront toutes les lignes, quelles que soient les politiques RLS. Pour garantir l'application de la RLS, utilisez des grants à granularité fine plutôt que le rôle de superutilisateur.
Permissions de base de données
Lorsque vous créez l'application avec la ressource Lakebase en suivant le guide Démarrage, le service principal se voit automatiquement accorder la permission CONNECT_AND_CREATE sur la ressource postgres. Il peut ainsi se connecter à la base de données et créer de nouveaux objets, mais pas accéder aux schémas ou aux tables existants.
Développement local
Pour développer localement avec une base de données Lakebase déployée :
Déployez d'abord l'application. Le service principal crée le schéma et les tables de la base de données lors du premier déploiement. Les applications générées avec databricks apps init s'en chargent automatiquement : elles vérifient au démarrage si les tables existent et n'en créent pas si c'est le cas.
Accordez le rôle databricks_superuser (ignorez cette étape si vous êtes propriétaire du projet Lakebase — vous disposez déjà d'un accès complet) :
# Créer un nouveau rôle avec databricks_superuserdatabricks postgres create-role "projects/{project_id}/branches/{branch_id}" \ --json '{"spec": {"identity_type": "USER", "postgres_role": "user@example.com", "membership_roles": ["DATABRICKS_SUPERUSER"]}}'
Pour accorder le rôle superutilisateur à un rôle existant, utilisez update-role :
Vous pouvez également gérer les rôles dans l'interface Lakebase Autoscaling, sur la page Branch Overview de votre projet → Add role / Edit role.
Exécutez l'application localement : votre identité d'utilisateur Databricks (adresse e-mail) sert à l'authentification OAuth. Le rôle databricks_superuser donne un accès DML complet (lecture/écriture des données) mais pas DDL (création de schémas ou de tables) — d'où l'importance de déployer au préalable (voir la note ci-dessous).
Pour les autres utilisateurs, répétez l'étape 2 afin de créer un rôle OAuth avec databricks_superuser pour chacun d'eux.
tip
L'authentification par mot de passe Postgres est une alternative plus simple, qui évite la complexité des permissions de rôle OAuth. Elle exige toutefois de définir un mot de passe pour l'utilisateur sur la page Branch Overview de l'interface Lakebase Autoscaling.
Pourquoi déployer d'abord ?
Lors du déploiement de l'application, le service principal crée les schémas et les tables et en devient le propriétaire. databricks_superuser donne un accès DML complet (lecture/écriture) mais pas DDL : le développement local ne fonctionne donc qu'une fois le schéma créé.
Si vous lancez d'abord npm run dev, ce sont vos identifiants qui deviennent propriétaires du schéma et l'application déployée se heurte à une erreur permission denied. Pour rétablir la situation, exportez d'abord vos données (pg_dump ou copie temporaire du schéma), puis supprimez le schéma et redéployez. Après le redéploiement, le service principal recrée le schéma au démarrage. (La propriété d'un schéma PostgreSQL est liée au rôle qui l'a créé et ne peut pas être réattribuée par des utilisateurs ordinaires.)
Permissions à granularité fine
Dans la plupart des cas, databricks_superuser suffit. Si vous avez plutôt besoin de grants au niveau du schéma, consultez la documentation officielle :
Déployez et exécutez l'application au moins une fois avant d'appliquer ces grants, afin que le service principal initialise d'abord le schéma de la base de données.
Remplacez subject par l'adresse e-mail de l'utilisateur et schema par le nom de votre schéma :
CREATE EXTENSION IF NOT EXISTS databricks_auth;DO $$DECLARE subject TEXT := 'your-subject'; -- Adresse e-mail de l'utilisateur, par exemple name@databricks.com schema TEXT := 'your_schema'; -- Remplacez 'your_schema' par le nom de votre schémaBEGIN -- Créer le rôle OAuth pour l'identité Databricks PERFORM databricks_create_role(subject, 'USER'); -- Accès à la connexion et au schéma EXECUTE format('GRANT CONNECT ON DATABASE "databricks_postgres" TO %I', subject); EXECUTE format('GRANT ALL ON SCHEMA %s TO %I', schema, subject); -- Privilèges sur les objets existants EXECUTE format('GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA %s TO %I', schema, subject); EXECUTE format('GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA %s TO %I', schema, subject); EXECUTE format('GRANT ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA %s TO %I', schema, subject); EXECUTE format('GRANT ALL PRIVILEGES ON ALL PROCEDURES IN SCHEMA %s TO %I', schema, subject); -- Privilèges par défaut sur les objets futurs EXECUTE format('ALTER DEFAULT PRIVILEGES IN SCHEMA %s GRANT ALL ON TABLES TO %I', schema, subject); EXECUTE format('ALTER DEFAULT PRIVILEGES IN SCHEMA %s GRANT ALL ON SEQUENCES TO %I', schema, subject); EXECUTE format('ALTER DEFAULT PRIVILEGES IN SCHEMA %s GRANT ALL ON FUNCTIONS TO %I', schema, subject); EXECUTE format('ALTER DEFAULT PRIVILEGES IN SCHEMA %s GRANT ALL ON ROUTINES TO %I', schema, subject);END $$;
Databricks Developer Hub
Prêt à lancer votre prochaine application agentique en quelques minutes ?