Skip to main content

Flask RLS

PostgreSQL Row-Level Security for Flask and SQLAlchemy

Flask RLS enforces tenant isolation for multi-tenant Flask applications inside PostgreSQL itself: row-level security policies filter every query, so application code cannot leak another tenant's data.

PyPI version Supported Python versions CI status License: BSD-3-Clause

Why Flask RLS for multi-tenant applications?

Database-level security

RLS is enforced by PostgreSQL itself — even raw SQL or a forgotten filter cannot leak another tenant’s rows.

Tenant & user policies

TenantPolicy, UserPolicy, CustomPolicy, and the Pythonic ExpressionPolicy, mirroring django-rls.

Pool-safe context

Context is set per transaction via set_config(..., is_local=true), so it can never leak across pooled connections.

ORM-agnostic

Binds at the SQLAlchemy engine layer — works with bare SQLAlchemy Core or Flask-SQLAlchemy.

Alembic migrations

First-class migration operations: op.enable_rls, op.force_rls, op.create_policy, and more.

Proven against PostgreSQL

Isolation, fail-closed behavior, and the FORCE/owner-bypass gotcha are verified against a live database.