Skip to main content
Supabase

Supabase Auth plus RLS: keep rows where they belong

Published Feb 16, 202611 min read
Supabase Auth plus RLS: keep rows where they belong

Supabase Auth gets you users quickly. Row Level Security (RLS) is what keeps those users from reading each other's rows when you add a second tenant.

This post is the pairing we use on Next.js SaaS apps: model ownership first, then policies that match how you actually query.

Start with the simplest safe data model

Most SaaS apps end up needing an organization/workspace model. A safe baseline looks like:

  • users (or profiles) tied to auth.users
  • organizations
  • organization_members (user ↔ org with role)
  • Your tables include organization_id (and sometimes created_by)

Even if you don’t expose orgs in the UI on day one, modeling ownership early prevents painful migrations later.

RLS: make the database enforce ownership

With RLS enabled, the database will only return rows the current user is allowed to see. That means:

  • Even if a buggy API route forgets a filter, your data is still protected.
  • You can safely build more features without re-auditing every query.

A practical RLS pattern

For a table like projects:

  1. Add organization_id to the row.
  2. Enable RLS.
  3. Add a policy that checks membership in that organization.

The exact SQL will vary, but the logic is always:

  • User can read/write rows where they’re a member of organization_id.

Don’t trust client input for ownership

Two common mistakes:

  • Taking organization_id from the client and writing it directly.
  • Allowing users to set created_by arbitrarily.

Prefer server-side derivation:

  • Read the active org from session/context
  • Enforce it in your server action / route handler
  • Let RLS be the final gate

Auth patterns that work well with Next.js

In App Router projects, the best results come from:

  • Server-side session checks (Server Components / route handlers)
  • A small number of client components for interactive UI
  • Minimal “auth logic” duplicated across the app

If you want a deeper breakdown, see /blog/nextjs-app-router-auth-patterns.

Checklist: secure defaults for a template

  • RLS enabled on all tenant-owned tables
  • A membership table and role columns
  • Server-only writes for ownership fields
  • API routes validate entitlements server-side
  • Clear docs explaining how to extend policies

For a concrete reference, SaaSForge Core ships this pattern at production depth: workspace-scoped RLS, 4-role RBAC, membership tables, and audit logs on mutations. SaaSForge AI adds pgvector for RAG with the same RLS boundaries, and its database docs walk through schema + policies. For the full stack rationale, see our tech stack page.

Newsletter

Get the BoilerlyKit newsletter

Practical Next.js SaaS launch tips, delivered when we ship something worth sharing.

We respect your inbox. See our privacy policy.