AnswersAuth & data

Row-level security in plain English

Row-level security means every record decides who is allowed to read or write it, and the server enforces that decision. In SQL you write these rules as policies on each table, which is flexible and easy to get wrong. In Gemmein you write no policies. You pick one of eight plain-English safety rules per collection, and the server enforces it.

01 / WHAT IT MEANS

What row-level security means

Most access bugs come from checking permissions in the app, where a determined person can route around them. Row-level security moves the decision to the data itself. Each record carries the rule for who may read or write it, and the server enforces that rule on every query. The client cannot ask for more than the rule allows.

02 / THE SQL WAY

Row-level security in SQL

In Postgres and tools built on it, row-level security is a set of policies you write per table in SQL. You enable it, then define who can select, insert, update and delete which rows. It is flexible and correct when done right, but you have to get it right on every table. If RLS is off on a table, or a policy is too loose, the query returns rows it shouldn't, with no error.

03 / THE GEMMEIN WAY

Gemmein's eight safety rules

Every collection has one of eight plain-English safety rules. You choose it in the collection’s file in your project, and the server enforces it on every read and write. There is nothing to enable and no policy to leave open.

RuleWhat it means
privateEach signed-in person sees and edits only their own records.
sharedEvery signed-in person reads every record and adds their own.
admin_writeEveryone signed in can read. Only the app owner can write.
public_readReadable without signing in. Only the app owner writes.
communityReadable without signing in. Any signed-in person posts and edits their own.
addressedThe app owner creates records for one person. That person's list returns only their own, like an inbox.
directPeople send to each other. The app owner can read them.
app_onlyNobody using the app reads or writes it. Only the app owner, their server and relays reach it.
Reading respects the ruleJavaScript
// On a "private" collection, this returns only the signed-in person's records.
const { records } = await g.collection("notes").list({ limit: 20 });
04 / COMING FROM SUPABASE RLS

Map a policy to a safety rule

If you write RLS policies today, choose the safety rule that matches the policy's intent.

The policy you would writeThe Gemmein rule
A user can select and update only rows where user_id = auth.uid()private
Everyone reads, without signing in; a signed-in person writes their own rowscommunity
Everyone signed in reads; a signed-in person writes their own rowsshared
Anyone reads; only the app owner writespublic_read
Everyone signed in reads; only the app owner writesadmin_write
Deliver one record to one specific personaddressed
No client role can select or write; only the service role reaches the tableapp_only
You can't write custom SQL policies, so there is no policy to get wrong. The eight rules are fixed and don't support per-field conditions. See the data model.
05 / FOR YOUR CODING AGENT

Prompt for your coding agent

Paste this into Cursor, Claude, Bolt or Lovable so your agent picks the right safety rule and writes no access checks of its own.

Prompt for your coding agentCopy and paste

Read https://docs.gemmein.com/llms.txt. I want row-level security for my app's data without writing SQL policies. Explain the eight safety rules (private, shared, admin_write, public_read, community, addressed, direct, app_only) and, for each collection in my app, pick the rule that keeps each person's data correctly scoped. Show how a list query returns only what the rule allows.

06 / FAQ

Frequently asked questions

Can row-level security be turned off or misconfigured?

It cannot be turned off. Every collection has a safety rule, always on and enforced on the server, with no switch to disable it and no policy to leave open. The choice you make is the rule itself, so pick the one that matches who should read the data: personal data belongs on private, never on public_read.

Add Gemmein to your AI. Then tell it what you want.

Building is free. No card until you go live.