Skip to content

Python policies. SQL enforcement.

Authorization that speaks SQLAlchemy.

Keep tenant data scoped and row permissions close to your models. Write a policy in Python, then use it for filtered ORM reads and explicit permission checks.

Python 3.11+   /   SQLAlchemy 2   /   FastAPI ready   /   MIT licensed

One policy definition

SQLAlchemy predicates power both collection filtering and explicit object checks. The database evaluates your rules.

A tenant per session

Bind an actor to a fresh session. Purview adds tenant criteria to ORM reads and checks tenant IDs during object writes.

Fits your Python stack

Use familiar models, queries, and tools. Add FastAPI dependencies when you need them. No separate policy service.

Start with a rule

This policy lets authors read their own posts. The session's tenant filter applies alongside it.

from purview import READ, Context, Policy
from purview.sqlalchemy import install

policy = Policy()


@policy.rule(Post, READ)
def read_posts(ctx: Context):
    return [Post.author_id == ctx.user_id] if ctx.has_role("author") else []


pv = install(Base, policy, strict=True)

Bind the authenticated actor, then use an ordinary SQLAlchemy query:

async with sessions() as session:
    pv.bind(session, Context(user_id=42, tenant_id=1, roles={"author"}))
    posts = (await session.scalars(select(Post))).all()

Run the complete SQLite example →

Small API. Explicit boundaries.

Reads filter automatically on bound sessions. For writes, your application calls authorize() before update or delete and validate_create() for create rules. The normal ORM flush guard handles tenant stamping and cross-tenant checks.

The examples use strict=True to deny reads when a scoped model has no rule. The default mode allows tenant-wide reads for such models. Raw SQL, bulk DML, unbound sessions, and bypass blocks are outside automatic enforcement.

Understand the security boundary →

Find your next step

You want to… Read
Install the right database driver Installation
See a working example end to end Quickstart
Add roles, create rules, or custom tenant fields Writing policies
Bind an actor to every API request FastAPI integration
Understand a denied request or an open model Debugging policies
Bring an existing Polar policy Migrating from Oso
Check signatures and available methods API reference