Alembic migrations
If you manage schema with Alembic, fastapi-rls adds operation directives so RLS becomes part of your normal migration history — reviewable, reversible, and ordered against your table changes.
Register the directives
Import the module once (anywhere Alembic loads, e.g. your migration env.py or
the migration itself). The import has the side effect of registering the op.*
directives:
import fastapi_rls.alembic_ops # noqa: F401 — registers op.enable_rls / op.create_policy / …
Available operations
| Directive | Emits |
|---|---|
op.enable_rls(table) | ALTER TABLE … ENABLE ROW LEVEL SECURITY |
op.disable_rls(table) | ALTER TABLE … DISABLE ROW LEVEL SECURITY |
op.force_rls(table) | ALTER TABLE … FORCE ROW LEVEL SECURITY |
op.no_force_rls(table) | ALTER TABLE … NO FORCE ROW LEVEL SECURITY |
op.create_policy(policy) | CREATE POLICY … for a bound policy |
op.drop_policy(table, name) | DROP POLICY IF EXISTS … ON … |
A migration
Policies passed to op.create_policy must be bound — pass table=
explicitly, since there's no model mixin in a migration:
from alembic import op
from fastapi_rls import TenantPolicy
import fastapi_rls.alembic_ops # noqa: F401
def upgrade():
op.enable_rls("documents")
op.force_rls("documents")
op.create_policy(
TenantPolicy("tenant_isolation", column="tenant_id", table="documents")
)
def downgrade():
op.drop_policy("documents", "tenant_isolation")
op.no_force_rls("documents")
op.disable_rls("documents")
ENABLE ROW LEVEL SECURITY alone leaves the table owner unconstrained.
Follow it with op.force_rls(table) so migrations and owner connections are
constrained too. See the security model.
Alembic vs the CLI vs the facade
All three drive the same DDL builders; pick the one that fits your workflow:
- Alembic — RLS changes ride your existing migration history.
- CLI (
fastapi-rls sync) — reconcile a registry against the live database without a migration tool. - Facade (
rls.sync()) — reconcile from application code at startup.
Alembic gives you explicit, ordered, reversible steps; the CLI/facade give you
declarative reconciliation from your policy registry. Many projects use Alembic
for the enable/force and the CLI audit in CI to catch drift.