Skip to content

feat(gates/postgres): withPostgres and withPostgresAdmin#75

Draft
tomaspozo wants to merge 3 commits into
FUNC-577/gates-corefrom
FUNC-577/gates-core-with-postgres
Draft

feat(gates/postgres): withPostgres and withPostgresAdmin#75
tomaspozo wants to merge 3 commits into
FUNC-577/gates-corefrom
FUNC-577/gates-core-with-postgres

Conversation

@tomaspozo

Copy link
Copy Markdown
Member

Adds a postgres gate pair at the @supabase/server/gates/postgres subpath — direct Postgres access from a handler while keeping Supabase's auth model.

What's added

  • withPostgresctx.postgres: RLS-scoped pg client. Each operation runs as the caller's JWT (claims + connection role pinned to a single transaction, PostgREST-style), so auth.uid() and RLS policies behave exactly as through PostgREST. Requires upstream jwtClaims (composing it outside withSupabase is a compile-time error).
  • withPostgresAdminctx.postgresAdmin: RLS-bypassing client. No prerequisites.
  • Each client exposes query(text, params?) (its own auth-scoped transaction) and tx(fn) (multi-statement atomicity). No implicit request-wide transaction; every operation is a self-contained short transaction, so no after-handler cleanup hook is needed.

Notes for review

  • First runtime-specific gate. Uses pg (node-postgres) → the subpath is Node/Deno-only, not Workers/edge. The pg import is confined to this module; verified the package root never pulls pg into its bundle.
  • pg added to dependencies, @types/pg to devDependencies.
  • Role clamp: the user client's connection role is clamped to authenticated/anon and can never be flipped to service_role by a token claim — RLS bypass is exclusively withPostgresAdmin's job.

Testing

  • Integration suite (index.test.ts) self-skips unless SUPABASE_DB_URL is set; the @ts-expect-error compile-fail assertion runs in CI via typecheck regardless. Validated against a real Postgres 16 container: RLS scoping, cross-user isolation, tx commit/rollback, admin RLS-bypass, anon role for null claims, connection-leak baseline.
  • Also exercised end-to-end as a real Supabase Edge Function (user / anon-via-secret / no-credential paths).
  • pnpm typecheck, lint, test, and the JSR slow-type check are clean (gate exports carry explicit Gate<…> annotations).

Stacks on FUNC-577/gates-core.

🤖 Generated with Claude Code

tomaspozo added 3 commits June 6, 2026 21:55
RLS-scoped (ctx.postgres) and RLS-bypassing (ctx.postgresAdmin) pg clients,
exposed at the ./gates/postgres subpath. Node/Deno-only; the pg import is
confined to this module so the package root stays edge-safe. Each operation
owns its connection lifecycle (self-contained short transactions), so no
after-handler cleanup hook is required. The user client's connection role is
clamped to authenticated/anon and never service_role.
Integration suite self-skips unless SUPABASE_DB_URL is set. Covers RLS-scoped
reads, multi-statement tx commit/rollback, admin RLS-bypass, anon role for null
claims, a connection-leak baseline, and a compile-fail assertion that
withPostgres requires an upstream jwtClaims.
@pkg-pr-new

pkg-pr-new Bot commented Jun 7, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@supabase/server@75

commit: 2f22d52

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