Skip to main content

Purview

Authorization that speaks SQLAlchemy.

CI PyPI Python Documentation License: MIT

Row-level authorization and tenant isolation for SQLAlchemy 2.0, with a lightweight FastAPI adapter. Write policies as Python functions returning SQLAlchemy predicates. Purview uses those predicates to filter ORM reads and answer explicit permission checks in the database. No policy server or separate language required.

Documentation · Quickstart · API reference · Security boundary

Install

Requires Python 3.11+ and SQLAlchemy 2.0. The distribution is purview-authz, and the Python import is purview.

# A new or existing uv project
uv add "purview-authz[sqlite]"

# Or use pip in a virtual environment
python -m pip install "purview-authz[sqlite]"

Choose extras for your application:

Install Includes
purview-authz Purview and SQLAlchemy's asyncio support
purview-authz[sqlite] Also includes the aiosqlite driver
purview-authz[postgres] Also includes the asyncpg driver
purview-authz[fastapi,postgres] FastAPI adapter and PostgreSQL driver

One policy, filtered reads

from sqlalchemy import select
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)

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

Here, Base, Post, and sessions are your application's SQLAlchemy models and async session factory. The tenant predicate and read policy apply together, so this query returns only posts by author 42 in tenant 1.

Run the complete SQLite quickstart or inspect the runnable script. It creates its own models, database, and sample data.

A registered rule returning [] denies access. The example enables strict=True, which also denies access to scoped models with no read rule. Without strict mode, those models are readable throughout the bound tenant.

What Purview handles

  • ORM read filtering: selects, database loads through session.get(), and supported eager or awaitable relationship loads on a bound session.
  • Tenant checks on object writes: stamp tenant IDs on new objects and reject cross-tenant attachments and tenant changes during normal ORM flushes.
  • Explicit authorization: await pv.authorize(...), batch await pv.authorized_ids(...), and pv.validate_create(...).
  • Policy tools: role hierarchies, per-model tenant fields, predicate explanations, and audits for models left readable tenant-wide.

Use a fresh session per actor/request, and bind it before loading application data. Your app authenticates the actor and resolves trusted tenant membership and roles. Call authorization helpers before modifying or deleting an object, and call validate_create() before adding it when you use create rules.

Raw SQL, Core statements, bulk DML, unbound sessions, and explicit bypass blocks are outside automatic enforcement. Global models are exempt from automatic filtering. Purview is an application-layer control, not database row-level security. Read the security boundary before integrating it into request handlers.

Build with Purview

Guide Start here for
Installation Drivers, extras, and a clean environment
Quickstart A runnable SQLite example and how it works
Writing policies Grants, defaults, create rules, and tenant configuration
FastAPI integration Request dependencies, explicit checks, and HTTP errors
Debugging policies Explain SQL and audit visibility
Migrating from Oso Map existing policy concepts to Purview
Tracker example FastAPI, Alembic, and PostgreSQL together

Contribute

git clone https://github.com/jestatsio/purview.git
cd purview
uv sync --locked --all-extras
uv run --locked --all-extras pytest
uv run --locked --all-extras mypy
uv run --locked --all-extras ruff check .
uv run --locked --all-extras mkdocs serve

See Contributing for the development workflow and PostgreSQL tests, Releasing for the release process, and Security for private vulnerability reporting.

MIT licensed. See LICENSE.

Metadata

Release files for purview-authz 0.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for purview-authz 0.3.1
File Size Uploaded
purview_authz-0.3.1.tar.gz 194.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for purview-authz 0.3.1
File Interpreter ABI Platform
purview_authz-0.3.1-py3-none-any.whl Python 3 none any Details

Total release size: 228.4 kB

Release files / purview_authz-0.3.1.tar.gz

Download URL purview_authz-0.3.1.tar.gz
Size 194.0 kB
Tags Source
SHA-256 checksum
How to use checksums
0dab8859f1e4c1f3daf05671ba2097465f8d70d909c844636a9dadc0351b71d8
BLAKE2b-256 checksum
How to use checksums
7762f253d33e206bad5ddfd4cc92df1a5702a06678c7094ce5beed892b18f882
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release files / purview_authz-0.3.1-py3-none-any.whl

Download URL purview_authz-0.3.1-py3-none-any.whl
Size 34.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
594f700f97ff76ea422a2cca2640cde638a9e2101d29489e0f2493abcbe6b6c9
BLAKE2b-256 checksum
How to use checksums
d46fe9e8bc7574f97b27686a587ec4f8577bea19c688914d2aba423279bdd840
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.1 This release

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page