Back to blog
RLSSupabaseguide

RLS mistakes: the 2026 guide for Supabase, PostgreSQL, and multi-tenant access control

Published on 2026-04-118 min readFlorian

Why this cluster exists

RLS, or Row Level Security, became a central keyword in modern stacks because it allows teams to expose a database or data API while keeping fine-grained isolation between users, roles, or tenants.

The problem is simple: many teams say they "have RLS" when what they really did was enable a setting, copy two policies, or shift trust toward a JWT, a privileged role, or a function that bypasses the original intent.

The PostgreSQL documentation is very clear. Without policies, if a user already has the necessary SQL privileges, all rows remain available. Once RLS is enabled, normal access must be allowed by a policy. And if no policy exists, the behavior becomes default-deny.

Mistake #1: believing that enabling RLS is enough

Enabling RLS is a step. It is not an authorization model.

On Supabase, the documentation explicitly recommends that tables in an exposed schema should have RLS enabled. But that does not guarantee that the policies are correct. An over-permissive or poorly designed policy can still allow exactly what you meant to block.

That is where false confidence starts: the team knows RLS is enabled and concludes the problem is solved.

Mistake #2: protecting SELECT but not INSERT, UPDATE, or DELETE

PostgreSQL supports command-specific policies. That is powerful, but it creates a very common trap: reads are controlled while modifications remain too broad.

In practice, that leads to cases like:

  • the user cannot read a row but can still modify it;
  • inserts are allowed with an arbitrary owner_id;
  • a USING clause exists, but the WITH CHECK clause does not prevent a row from being moved to another tenant.
  • That is one reason RLS mistakes often show up as business bugs before they are recognized as security vulnerabilities.

    Mistake #3: trusting the wrong JWT data

    The Supabase documentation makes an important point: data stored in raw_user_meta_data can be modified by the authenticated user. It is not a safe place for authorization state.

    Another subtle issue is freshness. A JWT is not always current. A policy built on stale claims can keep making the wrong decision even after the real role changed.

    In other words: if your security model depends on fragile or outdated identity metadata, your RLS may look neat while deciding on unstable inputs.

    Mistake #4: forgetting the roles that bypass RLS

    The PostgreSQL docs state that superusers and roles with BYPASSRLS always bypass row security. Table owners usually bypass it too unless configured otherwise.

    On the Supabase side, the documentation also states that service keys can bypass RLS. They should never be exposed in the browser or delegated to client-side logic.

    This is a frequent failure mode in fast-moving apps: the policy looks restrictive, but an RPC, Edge Function, worker, or admin script actually runs through a role that sees everything.

    Mistake #5: believing RLS covers the whole surface

    RLS protects rows. It does not secure by itself:

  • buckets and files;
  • exports;
  • webhooks;
  • Edge Functions;
  • overpowered RPC endpoints;
  • logs and operator surfaces;
  • application routes that bypass the database layer.
  • That is why Supabase RLS: 5 common mistakes should be read alongside a broader application review, not as a self-sufficient checklist.

    What to connect in your stack

    If you use Supabase or PostgreSQL in a modern product architecture, always connect RLS to these adjacent topics:

  • PostgreSQL and CVE-2018-1058 for privilege discipline and SQL environment hygiene;
  • Firebase security rules mistakes for the parallel rules-engine problem in another stack;
  • Supabase audit if your exposure flows through tables, RPC, Storage, and Edge Functions;
  • Full Audit if you also want the surrounding application surface reviewed.
  • Our take

    RLS is one of the best defense-in-depth mechanisms available in modern stacks. But it does not forgive fuzzy business rules, overpowered roles, or shortcut-heavy implementation.

    In 2026, the right question is not "did you enable RLS?" The right question is: which policies actually decide, for which commands, based on which identity inputs, and through which paths can that logic still be bypassed?

    Related articles

    Three adjacent analyses to keep exploring the same attack surface.

    Need an external review of your HR SaaS?

    Share your product, stack, and client context. We will come back with the right review scope.

    Discuss your audit