Skip to main content

Top-down role-based access control for Django

Project description

django-topdownrbac

A Django library that implements hierarchical, top-down role-based access control (RBAC) with automatic permission propagation through object trees.

If you manage resources organized in a hierarchy (organizations, teams, projects, ...) and need a user with a role on a parent to automatically have that role on all descendants, this library handles it for you.

Why this exists

Django's built-in permission system is flat: you grant permissions globally or per object, but there is no concept of hierarchy or propagation. No existing third-party package supports scoping permissions to specific object instances within a tree and propagating them downward.

django-topdownrbac fills that gap. Permissions are materialized into a dedicated table (UserPermission) for O(1) lookups at query time — no tree traversal or recursive joins needed. All changes to roles, bindings, group membership, or hierarchy automatically cascade to keep this table in sync.

Trade-off: storage vs. speed. Materialization means every user × permission × object combination is stored as a row. This makes permission checks and queryset filtering very fast, but the UserPermission table grows proportionally to the number of users, roles, and objects in your hierarchy. For small-to-medium projects this is negligible; for large-scale deployments with deep hierarchies, many roles, and thousands of users, monitor table size and plan your database capacity accordingly.

Key concepts

Concept Model Description
Subject UserSubject, UserGroupSubject A user or group of users. UserSubject extends Django's AbstractUser.
Restricted Object RestrictedObject Any object you want to protect. Organized as a tree (parent/children) using django-treebeard's Materialized Path.
Role Role A named collection of Django permissions. Can be marked immutable or externally provisioned (via YAML).
Role Binding RoleBinding Links a subject to a role on a specific restricted object. The propagate flag controls whether permissions apply to all descendants.
User Permission UserPermission A materialized row: one user, one permission, one object. This is the table queried at check time.

Concepts overview

How it works

  1. Create a RoleBinding linking a subject + role + restricted object (optionally with propagate=True).
  2. The library automatically bulk-creates UserPermission rows for every user x permission x object combination (including descendants when propagating).
  3. Permission checks (user.has_perm('view_thing', obj)) hit the UserPermission table via a custom authentication backend -- no tree traversal at query time.
  4. Any change (role update, binding deletion, group membership change, object moved in the tree) automatically cascades to keep UserPermission in sync.

Example usage

from topdownrbac.models import UserSubject, Role, RoleBinding, RestrictedObject
from django.contrib.auth.models import Permission

# Build a hierarchy
parent = RestrictedObject(parent=None); parent.save()
child = RestrictedObject(parent=parent); child.save()

# Create a role with a permission
viewer = Role.objects.create(name="Viewer")
viewer.add_permission(Permission.objects.get(codename="view_restrictedobject"))

# Bind the role to a user on the parent, propagating to all descendants
alice = UserSubject.objects.create_user(username="alice", password="secret")
RoleBinding.objects.create(
    role=viewer, subject=alice, restricted_object=parent, propagate=True
)

# alice can view both parent and child automatically
assert alice.has_perm("view_restrictedobject", parent)   # True
assert alice.has_perm("view_restrictedobject", child)    # True

Installation

uv add django-topdownrbac
# or
pip install django-topdownrbac

For the full setup guide, custom model definitions, and DRF integration, see the walkthrough. You can also build the docs locally: mkdocs serve

Development

Prerequisites

  • uv (Python package manager)
  • Task (task runner)
  • Docker & Docker Compose (for PostgreSQL)

Getting started

Install dependencies:

uv sync

Start Postgres and the dev server:

task dev

Full reset (wipe DB, rebuild, start fresh):

task fresh

Documentation

MkDocs and its plugins (e.g. mkdocs-puml) are installed as dev dependencies by uv sync. To serve the docs locally:

task mkdocs

Running tests

task test                        # run all tests
task test -- -k "not benchmark"  # skip benchmark tests, which can prove to be long
task test -- -v                  # verbose output

Linting

task lint        # check with ruff
task lint:fix    # auto-fix issues

Building Docker images

task build       # builds both CI and production images
task security    # build + Trivy vulnerability scan

Project details


Download files

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

Source Distribution

django_topdownrbac-0.1.0.tar.gz (133.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_topdownrbac-0.1.0-py3-none-any.whl (19.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: django_topdownrbac-0.1.0.tar.gz
  • Upload date:
  • Size: 133.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for django_topdownrbac-0.1.0.tar.gz
Algorithm Hash digest
SHA256 644e80a98989c82e2796ae2a1358d10332343dec7460ac511528f05e2d747fde
MD5 a0eef23e19c5959608020dbbf993a4cb
BLAKE2b-256 d83b9bb3e4f5f084649a41915024eaf2806010fb299b879aca7b2de888066fee

See more details on using hashes here.

Provenance

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

Publisher: release.yml on Gobijacques/django-topdownrbac

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_topdownrbac-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for django_topdownrbac-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 101160697fb2ad91942b4e373e8da2939c594d700c8824354358d0fb3c471006
MD5 c7b17e841f78ac4b74a0fb808a269925
BLAKE2b-256 699ea6e603718a78a543e2f704ee094b7df98c655bd4bfd99d4d7055d79b984b

See more details on using hashes here.

Provenance

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

Publisher: release.yml on Gobijacques/django-topdownrbac

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

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page