CtrlK
BlogDocsLog inGet started
Tessl Logo

testland/rls-reference

Pure-reference catalog of row-level security for tenant isolation, Postgres-first. Covers enabling RLS (ALTER TABLE ... ENABLE ROW LEVEL SECURITY, default-deny semantics), CREATE POLICY syntax (USING vs WITH CHECK clauses, FOR SELECT/INSERT/UPDATE/DELETE/ALL, permissive vs restrictive, TO role_name), bypassing RLS (superuser / BYPASSRLS / table owner / FORCE ROW LEVEL SECURITY), tenant context patterns (current_user, current_setting, JWT claims via Supabase auth.uid() / auth.jwt()), and performance discipline (wrapping auth functions in SELECT, index on policy-referenced columns). Row/tenant isolation on the non-Postgres engines - MySQL / MariaDB invoker views, CockroachDB native RLS, Vitess vindex sharding, SQL Server security policies - lives in references/other-engines.md. Use as the RLS-pattern reference for tenant isolation on any of these engines. Consumed by cross-tenant-data-leak-tests.

75

Quality

94%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Passed

No findings from the security scan

Overview
Quality
Evals
Security
Files

cockroachdb.mdreferences/

CockroachDB - native RLS

CockroachDB supports native row-level security that closely mirrors Postgres RLS.

Enabling RLS

ALTER TABLE documents ENABLE ROW LEVEL SECURITY;
-- Force table owners to obey policies too:
ALTER TABLE documents FORCE ROW LEVEL SECURITY;

CREATE POLICY

CREATE POLICY policy_name ON table AS [PERMISSIVE | RESTRICTIVE] FOR [SELECT | INSERT | UPDATE | DELETE | ALL] TO role USING (condition) [WITH CHECK (condition)]. Per the CockroachDB RLS docs: USING filters rows on reads and updates; WITH CHECK validates writes and defaults to USING when omitted; permissive policies combine with OR, restrictive with AND; access is denied by default once RLS is enabled and no policy applies.

Tenant context via application_name

CockroachDB has no Postgres-style SET LOCAL + current_setting transaction variable. The canonical pattern reads the tenant from application_name, a session variable every client sets at connection open:

SET application_name = 'tenant:<uuid>';

CREATE POLICY tenant_isolation ON documents
    FOR ALL
    TO app_role
    USING (
        tenant_id = split_part(current_setting('application_name'), ':', 2)::uuid
    )
    WITH CHECK (
        tenant_id = split_part(current_setting('application_name'), ':', 2)::uuid
    );

Bypass risks

Per the CockroachDB RLS docs, these paths bypass RLS and need separate controls:

BypassBehaviour
Foreign key constraints and cascadesNot subject to RLS
Primary / unique key constraintsNot subject to RLS
TRUNCATENot subject to RLS
Change Data Capture (CDC)Queries fail with error when RLS is enabled
Backup and restoreIgnore RLS policies
Logical and physical cluster replicationIgnore RLS policies

Source: CockroachDB RLS cockroachlabs.com/docs/stable/row-level-security.html.

SKILL.md

tile.json