glossary · Human decisions

Row-level security (multi-tenant)

definition

Row-level security is a database feature that filters which rows a query can see or change based on a policy, so in a multi-tenant system each tenant's data is isolated by the database itself rather than only by application code.

in one line: The database itself keeps each tenant's rows apart.

in context

Where does row-level security fit?

The wall is in the database. No tenant context, no rows. Even the table owner cannot step around it.

Policy per tablekeyed on the tenant
With FORCEowner included
No contextreads nothing
Isolation that does not depend on every query being right.
two ways to say it

What is row-level security, in plain words?

Same idea at two depths: the plain version, then what the engine actually does.

Filtering in app code works until one query forgets. A database policy filters every query.

Each workspace stays walled off, whatever the AI asks for.

for engineers

USING (org_id = current_setting('app.current_tenant_id', TRUE) OR org_id IS NULL), applied with FORCE.

Only global catalog rows are shared. App scoping and tenant middleware sit on top.

the longer answer

Why does row-level security matter?

Multi-tenant software stores many customers' data in the same tables. The common way to keep them apart is application code that adds a tenant filter to every query. That works until one query forgets the filter, and then one customer can read another's data. Row-level security moves the rule into the database: a policy on the table decides which rows are visible, and every query passes through it whether or not the application remembered.

In PostgreSQL, a table with row-level security enabled applies its policies to normal queries, typically comparing a tenant column with a value set for the current connection or transaction. Two details decide how strong it is. By default the table's owner bypasses the policies, which matters because applications often connect as the owner; FORCE ROW LEVEL SECURITY makes the policies apply to the owner too. And the policy should fail closed: if the tenant setting is missing, the query should return nothing rather than everything.

For AI agents, the stakes are higher than for a typical app. An agent issues many varied calls, often composed by a model, and the system has to hold its boundaries no matter what the model asks for. Isolation enforced in the database does not depend on every code path being right.

in convops

How does row-level security work in ConvOps?

In ConvOps, every tenant-scoped table carries a Postgres row-level security policy keyed on the request's tenant context, applied with FORCE, so even the table owner cannot step around it. A request with no tenant context reads nothing. The only shared rows are the global catalog. Application-level scoping and tenant middleware add layers on top of that guarantee, not in place of it. Each workspace is isolated this way, and a person's search reaches only the workspaces they are a member of.

questions

What do people ask about row-level security?

What is row-level security in PostgreSQL?

A table feature where policies decide which rows each query can see or change. Once enabled on a table, it filters every normal query, typically by comparing a tenant column with a value set for the current connection or transaction.

Does the table owner bypass row-level security?

By default, yes. FORCE ROW LEVEL SECURITY makes the policies apply to the owner too, which matters when the application connects as the owner. ConvOps applies its policies with FORCE.

Why does row-level security matter for AI agents?

Agents issue many varied calls composed by a model. Isolation enforced in the database holds whatever the model asks for, instead of depending on every code path adding a tenant filter.