Row-Level Security (RLS) Extension for DuckDB

February 24, 2026 ยท View on GitHub

This extension implements Row-Level Security (RLS) in DuckDB by providing an optimizer that automatically injects filters into query plans based on defined policies.

Features

  • Policy-based Filtering: Define RLS policies on tables to restrict access based on user-defined conditions.
  • Robust Subquery Support: Correctly handles RLS filters within complex subqueries, joins, and views.
  • Seamless Integration: Automatically applies filters during the optimization phase.

Building

To build the extension, run:

make

This will build the rls extension and a DuckDB shell with the extension pre-loaded.

Usage

The extension is named rls. It is automatically loaded when starting the duckdb shell from the build directory.

Example

Defining an RLS policy (currently simulated in tests by injecting filters based on table catalog):

-- Policies are currently defined internally for testing
-- Example of what the optimizer does:
-- If a policy "department_id = 10" exists for table "employees"
SELECT * FROM employees;
-- Is automatically transformed to:
SELECT * FROM (SELECT * FROM employees WHERE department_id = 10);

Current Status & Limitations

  • Testing: Comprehensive tests cover basic selects, subqueries, aggregates, joins, and views.
  • Verified: All tests in test/sql/*.test are PASSING.
  • Known Limitations: Currently, only SELECT statements are rigorously tested. Write operations (INSERT/UPDATE/DELETE) may require additional verification.

Running Tests

To run the full suite of RLS tests:

make test

The following test suites are included:

  • basic.test: Basic RLS policy application.
  • subqueries.test: RLS in nested subqueries.
  • joins.test: RLS across table joins.
  • views.test: RLS applied through views.
  • aggregations.test: RLS with GROUP BY and aggregate functions.