> For the complete documentation index, see [llms.txt](https://docs.glbnxt.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.glbnxt.com/tutorials/guides/supabase/supabase-rls.md).

# 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](https://docs.glbnxt.com/tutorials/guides/supabase/supabase-create-db-vdb)).
   1. . In the left sidebar, click **SQL Editor**.
   2. Click **New Query**.
   3. Paste the following:

      ```sql
      create table orders (
      id bigserial primary key,
      customer_id uuid not null references auth.users(id) default auth.uid(),
      product_name text not null,
      amount numeric not null,
      created_at timestamptz default now()
      );
      ```
   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.

5. Click **Add RLS Policy**.
6. Under **Policy Name**, give it a name, for example `Users can view their own orders`.
7. Check **Table on** — it should already show `public.orders`, since you opened this from that table. If not, select it from the dropdown.
8. 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.
9. Under **Policy Command for**, choose **SELECT** (this covers "viewing" rows).
10. Leave **Target Roles to** on its default — this applies the rule to everyone, and RLS itself still restricts each person to their own rows.
11. Below those options, Supabase shows the policy being built for you as SQL, ending in an incomplete line:

```sql
using (
  -- Provide a SQL expression for the using statement
);
```

Click into that area and replace the comment with:

```sql
auth.uid() = customer_id
```

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:

```sql
create policy "policy_name"
on "public"."places"
as PERMISSIVE
for SELECT
to public
using (
auth.uid() = customer_id
);
```

12. 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.*


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.glbnxt.com/tutorials/guides/supabase/supabase-rls.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
