Skip to main content

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​

DirectiveEmits
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 and force

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.

Written and maintained by · source on GitHub