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/*.testare PASSING. - Known Limitations: Currently, only
SELECTstatements 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.