Skip to content

feat(lakebase): OBO pool manager for per-user Lakebase connections#343

Draft
pkosiec wants to merge 4 commits intomainfrom
pkosiec/lakebase-obo
Draft

feat(lakebase): OBO pool manager for per-user Lakebase connections#343
pkosiec wants to merge 4 commits intomainfrom
pkosiec/lakebase-obo

Conversation

@pkosiec
Copy link
Copy Markdown
Member

@pkosiec pkosiec commented May 4, 2026

Caution

POC / Do Not Merge — This is a prototype for exploring Lakebase OBO authentication and RLS. Not ready for production.

Summary

  • Adds LakebasePoolManager to the AppKit connector layer for managing per-user Lakebase pg.Pool instances
  • Each user gets their own pool with individual OAuth token refresh via x-forwarded-access-token
  • Enables Row-Level Security (RLS) in Lakebase — queries execute as current_user, so the database enforces access control
  • Updates dev-playground raw driver example with RLS policy and OBO routes (/raw/my-products) alongside existing SP routes (/raw/products)
  • Adds "Raw Driver OBO" tab in the UI with side-by-side SP vs OBO comparison

How it works

  1. createLakebasePoolManager(baseConfig) returns a manager that caches pools by key (user email)
  2. Route handlers extract user email from x-forwarded-email header and token from x-forwarded-access-token
  3. poolManager.getPool(userEmail, { workspaceClient, user }) returns a cached or new pool
  4. RLS policy on the products table filters rows based on current_user

SP routes (table owner) bypass RLS and see all rows. OBO routes see only the user's rows.

Testing setup (eng-nephos-dust-oregon)

1. Create a role for each test user

Go to the Roles & Databases page and create a role matching the user's email (e.g. pawel.kosiec@databricks.com).

2. Grant permissions

Open the SQL Editor and run:

GRANT USAGE ON SCHEMA raw_example TO "user@databricks.com";
GRANT ALL ON ALL TABLES IN SCHEMA raw_example TO "user@databricks.com";
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA raw_example TO "user@databricks.com";
ALTER DEFAULT PRIVILEGES IN SCHEMA raw_example
  GRANT ALL ON TABLES TO "user@databricks.com";

3. Test the app

App URL: https://pk-lakebase-test-3111837193506155.staging.aws.databricksapps.com/lakebase

  • Raw Driver OBO tab: Creates products as the logged-in user, shows RLS-filtered view vs SP view side-by-side
  • Debug endpoint: GET /api/lakebase-examples/raw/debug-token shows forwarded headers

Test plan

  • pnpm build passes
  • pnpm -r typecheck passes
  • pnpm check:fix passes
  • pnpm test — all 1817 tests pass
  • Manual: verify RLS filtering with multiple users

pkosiec added 4 commits May 4, 2026 16:27
Add LakebasePoolManager to the AppKit connector layer, enabling
On-Behalf-Of (OBO) authentication where each user gets their own
pg.Pool with individual OAuth token refresh. This enables
Row-Level Security (RLS) in Lakebase based on current_user identity.

Changes:
- Add createLakebasePoolManager() in appkit connector (pool-manager.ts)
- Export LakebasePoolManager type and factory from @databricks/appkit
- Update dev-playground raw driver example with RLS policy and OBO routes
  - GET/POST /raw/my-products use per-user pools (RLS enforced)
  - GET/POST /raw/products remain on SP pool (RLS bypassed)

Signed-off-by: Pawel Kosiec <pawel.kosiec@databricks.com>
Add console logging to OBO route handlers so pool creation/reuse
is visible in app logs. Add hasPool() to LakebasePoolManager interface.

Signed-off-by: Pawel Kosiec <pawel.kosiec@databricks.com>
- Remove unused plugins (files, genie, jobs, serving) to avoid
  resource resolution errors
- Add database resource env var mappings in app.yaml
- Simplify lakebase plugin to raw driver example only
- Downgrade @databricks/lakebase to 0.2.0 for npm registry compat

Signed-off-by: Pawel Kosiec <pawel.kosiec@databricks.com>
- Change id from SERIAL to UUID with gen_random_uuid() default to avoid
  sequence permission issues with OBO users
- Grant schema/table access to PUBLIC so OBO users can SELECT/INSERT
- Add OboProductsPanel component with full email visibility
- Add debug-token endpoint and use x-forwarded-email header

Signed-off-by: Pawel Kosiec <pawel.kosiec@databricks.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant