Skip to main content

django-opa-permissions

Object-level Django permissions backed by OPA (Rego) policies stored in the database, evaluated in-process via opa-golib-python-bindings — no OPA server needed.

Features

  • Policies as DB objectsPolicy (UUID pk, Rego source) grouped into a PolicySet via FK; a PolicySetBinding maps a Django model (ContentType) to the policyset governing it. Unbound models deny everything (superusers excepted).
  • Auth backendOpaPermissionBackend implements user.has_perm("app.view_book", obj) so Django and DRF (DjangoObjectPermissions) work out of the box. Designed for subclassing: many small hook methods (extend_input, get_builtins, is_bypass, filter_result, …).
  • Minimal input document — policies receive only the user pk, app label, model name, action, and (except for browse/create) the object pk. Data is fetched from inside the policy via custom builtins (django_opa_fetch, django_opa_fetch_old, django_opa_query) — ORM-backed, no SQL.
  • Browse partial evaluationModel.objects.for_user(user) compiles the policy's filter rule with the object left unknown (OPA partial evaluation → UCAST → Django Q/Exists), filtering listings in SQL; relation traversal and $some/$all/$none quantifiers are supported. The authoritative full check (with the object pk) runs in allowed_for_user / has_perm.
  • Admin policy debugger — evaluate a policyset as any (visible) user against any bound model/object: print() output inline next to the policy line, per-line coverage highlighting, the full output document as a tree, and the residual browse prefilter. No trace logs.

Install

pip install django-opa-permissions
INSTALLED_APPS = [..., "django_opa_permissions"]
AUTHENTICATION_BACKENDS = [
    "django.contrib.auth.backends.ModelBackend",
    "django_opa_permissions.backends.OpaPermissionBackend",
]

Quick start

from django_opa_permissions.managers import OpaPermissionedModel

class Book(OpaPermissionedModel):
    title = models.CharField(max_length=300)
    owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    published = models.BooleanField(default=False)

Create a PolicySet, add a Policy, and bind it to the Book content type (all in the admin). Every policy must declare package policies; the entry points are allow (full evaluation) and filter (browse partial evaluation):

package policies

import rego.v1

# Owners may do anything with their own books.
allow if {
    obj := django_opa_fetch(input.app_label, input.model, input.object.id)
    obj.owner_id == input.user.id
}

# Anyone may view or browse published books.
allow if {
    input.action in {"view", "browse"}
    obj := django_opa_fetch(input.app_label, input.model, input.object.id)
    obj.published == true
}

# Browse prefilter: the object is UNKNOWN here — reference its columns via
# input.object; this compiles to SQL through the ORM.
filter if {
    input.object.published == true
}

filter if {
    input.object.owner_id == to_number(input.user.id)
}
Book.objects.for_user(user)          # SQL prefilter (partial evaluation)
Book.objects.allowed_for_user(user)  # prefilter + authoritative per-object pass
user.has_perm("library.view_book", book)
book.user_can(user, "change")        # or "delete", custom actions, ...
modified.user_can(user, "change", old=snapshot)  # policies may fetch both states

See docs/ for the input schema, builtins, filter-rule grammar (relation paths and quantifiers), and subclassing the backend; example_project/ is a runnable sqlite demo (python manage.py migrate && python manage.py load_example_policies && python manage.py runserver).

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_opa_permissions-0.1.0.tar.gz (42.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_opa_permissions-0.1.0-py3-none-any.whl (29.4 kB view details)

Uploaded Python 3

File details

Details for the file django_opa_permissions-0.1.0.tar.gz.

File metadata

  • Download URL: django_opa_permissions-0.1.0.tar.gz
  • Upload date:
  • Size: 42.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for django_opa_permissions-0.1.0.tar.gz
Algorithm Hash digest
SHA256 9f61ed937c46fcc8917373e6e11b9dec961040503f568d39fb33c12bc763f0b1
MD5 5490998e3ea45edbacba33d84d2bd865
BLAKE2b-256 8b2a974b180c5babd0861a25d7e31eee2be66a6364c96d12f3bdf5f93c785230

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_opa_permissions-0.1.0.tar.gz:

Publisher: publish.yml on phi1010/django-opa-permissions

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file django_opa_permissions-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for django_opa_permissions-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dcf04cc3584d226311280d0ce777f5c99ed0ba5b76a5e0e1b7c56873de0e6a7b
MD5 59594ef3fb48953f7efcc5d683cfa86c
BLAKE2b-256 c1521527c0e1d47d17b192da6303f0a250e19c242291bddd1f3a4f8cb37145c9

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_opa_permissions-0.1.0-py3-none-any.whl:

Publisher: publish.yml on phi1010/django-opa-permissions

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.3.0

2 files

0.2.0

2 files

This release

0.1.0 This release

2 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