I’ve been building django-pbac, a Policy-Based Access Control (PBAC) library for Django — think AWS IAM or Azure RBAC, but native to Django.
This is an early alpha — expect bugs, breaking changes, and missing docs. That’s exactly why I’m posting.
What problem does it solve?
Django’s built-in permissions are role-based: a user either has a permission or they don’t. That breaks down fast when you need rules like:
PBAC handles this with expressive policies:
- name: Finance manager can approve invoices
effect: PERMIT
subjects:
roles: [finance_manager]
attribute_conditions:
tenant_id: {ref: "resource.attributes.tenant_id"}
actions: ["invoices:approve"]
resources:
types: [invoice]
attribute_conditions:
status: {in: [pending, review]}
amount: {lte: 50000}
conditions:
- operator: time_between
attribute: context.timestamp
value: {start: "08:00", end: "18:00"}
What’s included
-
Three policy sources: Database (Django admin), Python code, YAML files
-
DRF integration: drop-in
PBACPermission/PBACObjectPermission -
View decorators: u/require_policy / u/deny_policy
-
Queryset filtering: auto-filter to only permitted resources
-
Template tags:
{% can "documents:read" resource %}/{% cannot %} -
Audit logging: full decision trace to DB or structured JSON
-
Context injectors: JWT claims, tenant info, request metadata
-
Conflict resolution: DENY_OVERRIDE, PERMIT_OVERRIDE, FIRST_APPLICABLE
-
Multi-tenancy: first-class via cross-reference conditions
-
Pure Python evaluation engine (zero Django deps in core — independently testable)
Quick look
# Install (from source for now — not on PyPI yet)
pip install git+https://github.com/Bilal-Dollan/django-pbac.git
# settings.py
INSTALLED_APPS = ["django_pbac", ...]
PBAC = {
"CONFLICT_RESOLUTION": "DENY_OVERRIDE",
"POLICY_LOADERS": ["django_pbac.loaders.db.DatabasePolicyLoader"],
"AUDIT_LOGGERS": ["django_pbac.audit.db.DatabaseAuditLogger"],
"CONTEXT_INJECTORS": ["django_pbac.injectors.user.UserAttributeInjector"],
}
# views.py
from django_pbac.integration.decorators import require_policy
u/require_policy("documents:read", resource_type="document")
def document_detail(request, pk):
...
# DRF
from django_pbac.integration.drf.permissions import PBACPermission
class DocumentViewSet(ModelViewSet):
permission_classes = [PBACPermission]
Where I need help
-
Try installing it — does
pip install git+https://github.com/Bilal-Dollan/django-pbac.gitwork cleanly? -
Run the example project in
example/— does it make sense? -
API feedback — does the
PBACsettings structure feel Pythonic/Django-idiomatic? -
Real-world use cases — does this model fit problems you’ve actually hit?
-
Bugs — anything that crashes, raises unexpected errors, or behaves wrong
Repo
https://github.com/Bilal-Dollan/django-pbac
Issues and PRs welcome. Be brutal — it’s alpha, I’d rather know what’s broken now.
Thanks!