Skip to content

rfc(data): pilot PostgreSQL RLS with Prisma and Hyperdrive #550

Description

@tiankaima

Decision context

Prisma ORM 7.8 can query RLS-protected PostgreSQL tables, but its current schema/migration DSL does not model policies. Prisma Next's new @@rls support is Early Access and is not a reason to migrate this production app immediately. Policies therefore require reviewed SQL migrations.

Cloudflare Hyperdrive uses transaction-mode pooling. Request identity cannot be stored with session-global SET; it must be set with transaction-local set_config(..., true) and every protected query must run on that same transaction/connection.

Applying RLS to every table at once would break the current shared Prisma-client/service pattern and would conflate user-owned, collaborative, public catalog, auth, importer, and audit data.

RFC and pilot

  1. Classify every model by owner and access class: user-owned, collaborative/public, auth-provider, importer/catalog, admin/audit.
  2. Define distinct migration-owner, runtime-app, auth-service, loader, and admin roles. Runtime roles must not own tables or have BYPASSRLS; use FORCE ROW LEVEL SECURITY where appropriate.
  3. Add withUserDbContext(userId, tx => ...) that starts a transaction, sets transaction-local context, and passes only the transaction client to protected services.
  4. Pilot on one clear user-owned domain such as Todo with raw SQL policies, service plumbing, and production-like Prisma/Hyperdrive tests.
  5. Roll out by table family only after correctness and latency are measured. Auth tables, append-only audit, and public importer/catalog data need explicit separate decisions rather than policy-count targets.

Acceptance criteria

  • With no user context, protected access is default-deny.
  • User A cannot read/write User B rows; WITH CHECK rejects forged ownership.
  • Runtime role is non-owner/no-BYPASSRLS; service/loader/admin roles have documented least privilege.
  • All protected queries, including nested operations, run inside the same context transaction and pool reuse does not leak identity.
  • SQL migrations replay in shadow/CI databases and introspection drift is understood.
  • Pilot records query count, transaction duration, and Hyperdrive latency before broader rollout.
  • The final model matrix explicitly explains any table not using RLS.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: dataPrisma, migrations, seed/import pipelines, transactions, and persistence invariantsarea: infrastructureProduction runtime, Cloudflare, storage, containers, deployment, and releasesenhancementNew feature or requestreleased

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions