---
title: "Row-Level Security (RLS)"
---

# Row-Level Security (RLS)

Implement fine-grained access control at the row level for multi-tenant applications.

## Enabling RLS

```sql
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
```

## Creating Policies

### Basic Tenant Isolation

```sql
CREATE POLICY tenant_isolation ON orders
FOR ALL
USING (tenant_id = current_tenant());
```

### Read-Only Public Access

```sql
CREATE POLICY public_read ON products
FOR SELECT
TO PUBLIC
USING (published = true);
```

### Insert Validation

```sql
CREATE POLICY insert_own_data ON documents
FOR INSERT
WITH CHECK (owner_id = current_user);
```

## Policy Types

| Type | Description |
|------|-------------|
| `PERMISSIVE` | Multiple policies are OR'd together |
| `RESTRICTIVE` | Multiple policies are AND'd together |

## For All Operations

```sql
CREATE POLICY full_access ON accounts
FOR ALL
USING (owner_id = current_user)
WITH CHECK (owner_id = current_user);
```

## System Functions

| Function | Description |
|----------|-------------|
| `current_user` | Connected user: the PostgreSQL login, or the REST token's `sub` |
| `current_tenant()` | Current tenant ID, bound by `\tenant use` in the REPL; NULL when no tenant context is bound (PostgreSQL port, REST API), and a policy comparing against it then denies the row |

Superusers, including the built-in `postgres` and `helios` accounts, bypass RLS: connect
applications as non-superuser roles.

## View Policies

```sql
SELECT * FROM pg_rls_policies();
```

## REPL Commands

```bash
\tenant rls create orders policy_name "tenant_id = current_tenant()"
\tenant rls list orders
\tenant rls delete orders policy_name
```

## Disabling RLS

```sql
ALTER TABLE orders DISABLE ROW LEVEL SECURITY;
DROP POLICY policy_name ON orders;
```

## Related

- [Multi-Tenancy](https://www.heliosdb.com/docs/lite/features/multi-tenancy/) - Tenant management
- [SQL Reference](https://www.heliosdb.com/docs/lite/user-guide/sql-reference/) - Complete RLS syntax
