What is row-level security (RLS)?
When app code forgets a filter, the database still holds back the rows your user shouldn't see.
Want to see it first? Book a demo

RLS — Row-level security (RLS) is a database feature that attaches access policies to individual rows. A query returns only the rows the current user is allowed to see, enforced by the database rather than the application. It protects data even when application code is wrong.
Also known as: row-level security
Why it matters
Most apps rely on their own code to decide what a user may see. That code filters results before they reach your screen. Row-level security moves that choice down into the database itself. You attach a policy to a table that says which rows a given user may read or write. Your database then applies it on every query, whatever the app's code asked for. If a bug in the app forgets to filter a query, RLS still blocks rows the user shouldn't see. The block holds even when the app gets it wrong.
What trips teams up is how several policies on the same table combine. In most setups, policies join with OR logic by default. A row shows up if it meets any one policy that applies, not only if it meets all of them. That's the trap. One loose policy, maybe written for an in-house tool or to make testing easier, can quietly undo every strict policy on the same table. It opens up rows those other policies were meant to guard. So you should check how the policies on a table work together, not only whether each looks right on its own. That's what catches the problem before real data leaks.
How RLS is applied
- 1
Enable RLS on a table
The table goes from open access to access gated by policy.
- 2
Define access policies
You write rules that say which rows a given user or role may see or change.
- 3
A query runs against the table
Any query, from the app or a direct link, has to pass the policies.
- 4
The database filters rows
Only rows that match a policy are returned or changed.
- 5
Policies are reviewed for how they combine
The policies on one table are checked together, not only one by one.
The mistake to watch for
Questions
- How is RLS different from role-based access control?
- Role-based access control most often sets what a role can do in the app or in a feature. RLS sets which rows in a database table a query returns. The database applies it, whatever the app meant to do.
- Does RLS protect against bugs in application code?
- Yes, and that's one of its main strengths. The database applies the policy rather than trusting the app to filter right. A bug in app code that forgets a filter still can't expose rows the RLS policy blocks.
- Why is it dangerous to add a permissive RLS policy?
- Policies on the same table are most often joined with OR logic. One policy that grants broad access, even one added for a small in-house job, can override every stricter policy on that table.