---
title: Rls
description: Rls protocol schemas
---

{/* ⚠️  AUTO-GENERATED — DO NOT EDIT. Run build-docs.ts to regenerate. Hand-written docs go in content/docs/guides/. */}

# Row-Level Security (RLS) Protocol

Implements fine-grained record-level access control inspired by PostgreSQL RLS

and Salesforce Criteria-Based Sharing Rules.

## Overview

Row-Level Security (RLS) allows you to control which rows users can access

in database tables based on their identity and role. Unlike object-level

permissions (CRUD), RLS provides record-level filtering.

## Use Cases

1. **Multi-Tenant Data Isolation**

- Users only see records from their organization

- `using: "organization_id = current_user.organization_id"`

2. **Ownership-Based Access**

- Users only see records they own

- `using: "owner_id = current_user.id"`

3. **Department-Based Access**

- Users only see records from their department

- `using: "department = current_user.department"`

4. **Regional Access Control**

- Sales reps only see accounts in their territory

- `using: "region IN (current_user.assigned_regions)"`

5. **Time-Based Access**

- Users can only access active records

- `using: "status = 'active' AND expiry_date > NOW()"`

## PostgreSQL RLS Comparison

PostgreSQL RLS Example:

```sql

CREATE POLICY tenant_isolation ON accounts

FOR SELECT

USING (tenant_id = current_setting('app.current_tenant_id')::uuid);

CREATE POLICY account_insert ON accounts

FOR INSERT

WITH CHECK (tenant_id = current_setting('app.current_tenant_id')::uuid);

```

ObjectStack RLS Equivalent:

```typescript

\{

name: 'tenant_isolation',

object: 'account',

operation: 'select',

using: 'organization_id = current_user.organization_id'

\}

```

## Salesforce Sharing Rules Comparison

Salesforce uses "Sharing Rules" and "Role Hierarchy" for record-level access.

ObjectStack RLS provides similar functionality with more flexibility.

Salesforce:

- Criteria-Based Sharing: Share records matching criteria with users/roles

- Owner-Based Sharing: Share records based on owner's role

- Manual Sharing: Individual record sharing

ObjectStack RLS:

- More flexible formula-based conditions

- Direct SQL-like syntax

- Supports complex logic with AND/OR/NOT

## Best Practices

1. **Always Define SELECT Policy**: Control what users can view

2. **Define INSERT/UPDATE CHECK Policies**: Prevent data leakage

3. **Use Role-Based Policies**: Apply different rules to different roles

4. **Test Thoroughly**: RLS can have complex interactions

5. **Monitor Performance**: Complex RLS policies can impact query performance

## Security Considerations

1. **Defense in Depth**: RLS is one layer; use with object permissions

2. **Default Deny**: If no policy matches, access is denied

3. **Policy Precedence**: More permissive policy wins (OR logic)

4. **Context Variables**: Ensure current_user context is always set

@see https://www.postgresql.org/docs/current/ddl-rowsecurity.html

@see https://help.salesforce.com/s/articleView?id=sf.security_sharing_rules.htm

<Callout type="info">
**Source:** `packages/spec/src/security/rls.zod.ts`
</Callout>

## TypeScript Usage

```typescript
import { RLSAuditConfig, RLSAuditEvent, RLSConfig, RLSEvaluationResult, RLSOperation, RLSUserContext, RowLevelSecurityPolicy } from '@objectstack/spec/security';
import type { RLSAuditConfig, RLSAuditEvent, RLSConfig, RLSEvaluationResult, RLSOperation, RLSUserContext, RowLevelSecurityPolicy } from '@objectstack/spec/security';

// Validate data
const result = RLSAuditConfig.parse(data);
```

---

## RLSAuditConfig

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **enabled** | `boolean` | ✅ | Enable RLS audit logging |
| **logLevel** | `Enum<'all' \| 'denied_only' \| 'granted_only' \| 'none'>` | ✅ | Which evaluations to log |
| **destination** | `Enum<'system_log' \| 'audit_trail' \| 'external'>` | ✅ | Audit log destination |
| **sampleRate** | `number` | ✅ | Sampling rate (0-1) for high-traffic environments |
| **retentionDays** | `integer` | ✅ | Audit log retention period in days |
| **includeRowData** | `boolean` | ✅ | Include row data in audit logs (security-sensitive) |
| **alertOnDenied** | `boolean` | ✅ | Send alerts when access is denied |


---

## RLSAuditEvent

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **timestamp** | `string` | ✅ | ISO 8601 timestamp of the evaluation |
| **userId** | `string` | ✅ | User ID whose access was evaluated |
| **operation** | `Enum<'select' \| 'insert' \| 'update' \| 'delete'>` | ✅ | Database operation being performed |
| **object** | `string` | ✅ | Target object name |
| **policyName** | `string` | ✅ | Name of the RLS policy evaluated |
| **granted** | `boolean` | ✅ | Whether access was granted |
| **evaluationDurationMs** | `number` | ✅ | Policy evaluation duration in milliseconds |
| **matchedCondition** | `string` | optional | Which USING/CHECK clause matched |
| **rowCount** | `number` | optional | Number of rows affected |
| **metadata** | `Record<string, any>` | optional | Additional audit event metadata |


---

## RLSConfig

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **enabled** | `boolean` | ✅ | Enable RLS enforcement globally |
| **defaultPolicy** | `Enum<'deny' \| 'allow'>` | ✅ | Default action when no policies match |
| **allowSuperuserBypass** | `boolean` | ✅ | Allow superusers to bypass RLS |
| **bypassRoles** | `string[]` | optional | Roles that bypass RLS (see all data) |
| **logEvaluations** | `boolean` | ✅ | Log RLS policy evaluations for debugging |
| **cacheResults** | `boolean` | ✅ | Cache RLS evaluation results |
| **cacheTtlSeconds** | `integer` | ✅ | Cache TTL in seconds |
| **prefetchUserContext** | `boolean` | ✅ | Pre-fetch user context for performance |
| **audit** | `Object` | optional | RLS audit logging configuration |


---

## RLSEvaluationResult

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **policyName** | `string` | ✅ | Policy name |
| **granted** | `boolean` | ✅ | Whether access was granted |
| **durationMs** | `number` | optional | Evaluation duration in milliseconds |
| **error** | `string` | optional | Error message if evaluation failed |
| **usingResult** | `boolean` | optional | USING clause evaluation result |
| **checkResult** | `boolean` | optional | CHECK clause evaluation result |


---

## RLSOperation

### Allowed Values

* `select`
* `insert`
* `update`
* `delete`
* `all`


---

## RLSUserContext

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **id** | `string` | ✅ | User ID |
| **email** | `string` | optional | User email |
| **tenantId** | `string` | optional | Tenant/Organization ID |
| **role** | `string \| string[]` | optional | User role(s) |
| **department** | `string` | optional | User department |
| **attributes** | `Record<string, any>` | optional | Additional custom user attributes |


---

## RowLevelSecurityPolicy

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **name** | `string` | ✅ | Policy unique identifier (snake_case) |
| **label** | `string` | optional | Human-readable policy label |
| **description** | `string` | optional | Policy description and business justification |
| **object** | `string` | ✅ | Target object name |
| **operation** | `Enum<'select' \| 'insert' \| 'update' \| 'delete' \| 'all'>` | ✅ | Database operation this policy applies to |
| **using** | `string` | optional | Filter condition for SELECT/UPDATE/DELETE (PostgreSQL SQL WHERE clause syntax with parameterized context variables). Optional for INSERT-only policies. |
| **check** | `string` | optional | Validation condition for INSERT/UPDATE (defaults to USING clause if not specified - enforced at application level) |
| **roles** | `string[]` | optional | Roles this policy applies to (omit for all roles) |
| **enabled** | `boolean` | ✅ | Whether this policy is active |
| **priority** | `integer` | ✅ | Policy evaluation priority (higher = evaluated first) |
| **tags** | `string[]` | optional | Policy categorization tags |


---

