For the complete documentation index, see llms.txt. This page is also available as Markdown.

Understanding Row Level Security

Row Level Security, or RLS, is one of the most important protections built into your Supabase database. This guide explains what it is in plain terms and shows a simple before-and-after example of what it actually does.


What is Row Level Security?

Think of a database table as a big shared spreadsheet. Without any protection, anyone who can connect to that table can see every row in it — every customer, every order, every message, regardless of who it belongs to.

Row Level Security lets you set rules that control who is allowed to see which rows. Instead of one big open spreadsheet, each person only sees the rows that are actually theirs — as if the spreadsheet quietly filtered itself depending on who was looking at it.

It's called "row level" because the rule is applied per row, not per table. The table itself still holds everyone's data — RLS just decides, row by row, who's allowed to see or touch each one.


Why you should enable RLS

By default, a brand-new Supabase table has no Row Level Security — meaning it's wide open to anyone with access to your project's API. That's fine for quick testing, but risky the moment real user data is involved.

You should thus enable RLS by default on your project because:

  • It protects your clients' or users' data from being visible to people who shouldn't see it — even by accident.

  • It works no matter which app, tool, or workflow connects to your database (n8n, a website, a mobile app) — the protection lives in the database itself, not in any one piece of software you build on top of it.

  • It's a standard expected by most security and compliance reviews.

💡 In short: RLS is the difference between "we trust every app we ever build to filter data correctly" and "it's structurally impossible for the wrong person to see the wrong row."


A simple before-and-after example

Imagine a table called orders, storing every customer's orders in one place.

Before RLS (not recommended):

Any logged-in user who queries the orders table gets back all orders — their own, and everyone else's. A bug or oversight in an app built on top of this table could easily expose one customer's orders to another.

After RLS (recommended):

A rule is added saying, in effect: "A user may only see rows where they are the customer on the order." Now, when that same user queries orders, the database automatically filters the results for them — they only ever see their own orders, even if the app asks for everything. There's nothing left for a bug to accidentally expose, because the database itself won't hand over rows that aren't theirs.

The user experience doesn't change at all — but the safety guarantee is completely different.


How to turn it on, with an example

Let's walk through turning RLS on for a real table — using the same orders example from above, where each order belongs to one customer.

  1. Open your Supabase dashboard and select your project.

  2. Create your orders table (Creating Databases and Vector Databases in Supabase).

    1. . In the left sidebar, click SQL Editor.

    2. Click New Query.

    3. Paste the following:

    4. Click Run.

  3. In the left sidebar, click Table Editor.

  4. Select your orders table.

  5. Click the RLS disabled button near the top of the table view, then click Enable RLS.

At this point, something important happens: RLS is now on, but no rules exist yet — so nobody can see any rows at all, not even the owner. This is intentional. Supabase would rather show nothing than accidentally show everything. The next step is to add a rule that lets the right people back in.

  1. Click Add RLS Policy.

  2. Under Policy Name, give it a name, for example Users can view their own orders.

  3. Check Table on — it should already show public.orders, since you opened this from that table. If not, select it from the dropdown.

  4. Leave Policy Behavior as set to Permissive — this just means the rule grants access rather than restricting it further; it's the right choice for a first policy on a table.

  5. Under Policy Command for, choose SELECT (this covers "viewing" rows).

  6. Leave Target Roles to on its default — this applies the rule to everyone, and RLS itself still restricts each person to their own rows.

  7. Below those options, Supabase shows the policy being built for you as SQL, ending in an incomplete line:

Click into that area and replace the comment with:

In plain terms, this says: "Only show this row if the person asking is the same person listed as the customer on it." auth.uid() is Supabase's way of identifying who's currently asking; customer_id is the column on your orders table that stores which customer the order belongs to.

In the end,r your policy should look something like this:

  1. Click Save policy.

From this point on, any query against orders automatically returns only the rows belonging to whoever is asking, exactly like the "After RLS" example earlier in this guide.

💡 Tip: If you have several kinds of access to define — for example, customers viewing their own orders and staff viewing all orders — you can add multiple policies to the same table. Each one covers a different case, and Supabase combines them automatically.


What this means for you day to day

You generally don't need to think about RLS while building — once it's set up correctly for a table, it works quietly in the background. It only becomes something to actively think about when:

  • You create a brand-new table and want to define who should see its rows.


Need help? Contact the GLBNXT support team or ask a GLBNXT agent to walk you through the steps.

Last updated

Was this helpful?