AuthZ Technologies Comparison
Overview
Authorization is a common challenge across software platforms, and many open source communities have already built frameworks to address it. To understand what could work for Open edX, we reviewed a range of existing technologies and compared them against a consistent set of evaluation criteria. Depending on their relevance, some of these may warrant deeper exploration in dedicated documents.
Framework for Evaluation
To assess these technologies consistently, we defined a set of criteria that capture the most important aspects for Open edX: integration, functionality, scalability, extensibility, and sustainability.
Criteria | Description |
|---|---|
Feature Completeness | Covers the functional building blocks needed:
|
Integration Fit | How well the technology integrates with existing systems (Django, Tutor, etc.), and how easy it is to manage and maintain over time. |
Performance & Scalability | How well the system performs under heavy load and scales with large numbers of users, roles, and resources. |
Extensibility & Customization | Ability to extend the system with custom roles, permissions, and plugin-defined logic. |
Standards Compliance | Use of widely adopted standards to ease maintenance and avoid unnecessary complexity or lock-in. |
Maturity | Stability of the technology, support for audit logs and queries, and proven reliability. |
Community & Support | Size and activity of the community, availability of documentation, and responsiveness for troubleshooting. |
Security & Compliance | Strength of security features (least privilege, defense in depth) and ability to support auditing/regulatory compliance. |
Learning Curve | Ease of adoption by developers and operators, including clarity of APIs and documentation. |
Total Cost of Ownership (TCO) | Overall operational overhead, including hosting, scaling, upgrades, and long-term maintenance. |
Authorization Technologies Reviewed
⚠️ These notes aim to provide a brief overview of the primary libraries and frameworks we examined for authorization. They're based on documents and research, and this will remain a living document as we continue to test things in practice (tests are tracked in the evaluation spreadsheet).
In the spreadsheet, each shortlisted technology has its own sheet and is evaluated according to the defined Evaluation Framework. For every evaluation item, the following scoring criteria are applied:
Full (2 points) → Meets all stated requirements out of the box.
Partial (1 point) → Meets some requirements; others require custom work.
None (0 points) → Not supported, or only achievable with heavy workarounds.
Based on the total sum(points_for_each_criteria), the goal is to build a ranking table that shows which technology comes closest to meeting our requirements for integration with Open edX.
The idea isn't to do the same work twice: the summaries here give context and help people follow along, while the hands-on tests will confirm what really works and what doesn't. That way we can drop options early if they don't fit.
Right now, the ones that look most promising to us are Django-PRBAC, Casbin, and OpenFGA. The rest are listed for completeness, but based on what we've seen so far, they don’t look like a good fit for our needs.
Libraries and Frameworks
This document covers: Django permissions, django-guardian, django-prbac, bridgekeeper, edx-rbac.
https://openedx.atlassian.net/wiki/spaces/OEPM/pages/5187043381
Model: Built around
RoleandGrant, it creates a graph of roles connected by privileges. Role definitions can be parameterized (e.g., by organization or course), enabling scoped RBAC and a limited form of ABAC.Strengths: Native to Django, intuitive for developers familiar with Django patterns, and simple to use.
Limitations:
No out-of-the-box support for bridgekeeper like filtering.
Centralization remains inside each service.
(Need to confirm): Whether we can extend it with a querying layer like Bridgekeeper, or if we must include Bridgekeeper itself for list-level queries.
Overall: Strong candidate for scoped RBAC if we stay Django-centric, but incomplete without a query/filtering layer.
https://openedx.atlassian.net/wiki/spaces/OEPM/pages/5178064909
Model: Uses a
.conf(model) file plus policies (CSV or DB) to separate authorization logic from code. Supports RBAC, ABAC, and ReBAC depending on the configuration.Strengths: Very flexible; supports multiple paradigms; adapters for many datastores.
Limitations:
Policy store must still be managed, and there's no native UI for stakeholder visibility.
We would need to build or adopt a presentation layer for visibility (same issue as Django-PRBAC).
(Need to confirm): Whether Casbin's filtering and querying APIs are strong enough to replace Bridgekeeper-style queryset integration, or if we still need an additional querying layer.
Overall: Flexible and powerful, but we must verify if its querying APIs meet our needs.
Total: 29 Points (12 Full = 24p, 5 Partial = 5p, 0 Null)
See Technology Comparison - Casbin for the complete evaluation summary.
https://openedx.atlassian.net/wiki/spaces/OEPM/pages/5178097713
Model: A centralized, Zanzibar-inspired ReBAC (relationship-based access control) database. Permissions are determined by graph traversal of relationships.
Strengths: Powerful, expressive, and battle-tested with strong open-source support.
Limitations: Likely overkill for our needs. Operational complexity is high. MySQL as datastore but not recommended as Postgres is.
Overall: Very strong technology, but risks being underutilized in our context.
https://openedx.atlassian.net/wiki/spaces/OEPM/pages/5177802865
Model: Lightweight, developer-friendly ReBAC service inspired by Zanzibar.
Strengths: Supports MySQL, Postgres, SQLite, and in-memory; easier to operate than SpiceDB.
Limitations: Same ReBAC complexity and overkill risk as SpiceDB.
Overall: More approachable than SpiceDB, but the same question remains: do we actually need ReBAC or these kind of graph-like structures?
https://openedx.atlassian.net/wiki/spaces/OEPM/pages/5178064957
Model: Stateless Policy Decision Points (PDPs). Evaluate requests against policies (YAML/JSON) and return allow/deny.
Strengths: Clean separation of logic; ABAC-friendly; flexible deployment modes (service, sidecar, embedded).
Limitations: Do not manage users or roles; must be combined with another system.
Overall: A good complement in a larger architecture, but not standalone.
https://openedx.atlassian.net/wiki/spaces/OEPM/pages/5187174402
Model: Identity and Access Management (IAM) system that primarily provides authentication (IdP, SSO) but also supports authorization with RBAC and ABAC. Roles are typically stored in JWT tokens and enforced in downstream services.
Strengths:
Centralized identity and role store.
Roles and attributes travel with the token (clean for services to consume).
Supports both RBAC (role-based) and ABAC (attribute-based) models.
Limitations:
Authorization features are tied to its identity management. It's difficult to use Keycloak only for authorization without migrating authentication to it as well.
To integrate with Open edX, we'd need synchronization between Keycloak and platform services (e.g., user roles, attributes).
Operators may find it too transversal (affecting multiple systems) and heavy for our use cases.
Overall: Strong for unified identity + access, but adopting only its authorization features would be complex. Better fit if we consider migrating authentication too or using LMS (user-store) as IdP.
AuthZ From Scratch
Not recommended. Authorization is a well-established domain with mature solutions. Reinventing it introduces unnecessary risk and ongoing maintenance burden.
Comparison Table
Analysis taken from Technology Comparison - AuthZ:
Criterion | Casbin (29 pts) | django-prbac (24 pts) | OpenFGA (25 pts) |
|---|---|---|---|
Integration Fit (Integration, Manageability, Maintainability) | Full (2) – Multi-language library (incl. Python), integrates with existing apps; model and policy are decoupled. | Full (2) – Django-based, open source; supports ABAC through parameters. | Full (2) – Deployable via Tutor plugin, official Docker image; Python SDK and HTTP/gRPC APIs available. |
Role Management (CRUD roles) | Full (2) – Management API for add/remove/list roles and relations ( | Full (2) – Roles stored in DB with CRUD support. | Partial (1) – Models are immutable; new version required for changes → could be supported by using groups |
Permission Management (CRUD perms) | Full (2) – Policies ( | Full (2) – Permissions stored in DB; CRUD supported. | Partial (1) – Same as roles: immutable models, only new versions allowed → but could be supported by using groups and members. |
Assignment Management (users ↔ roles ↔ scopes) | Full (2) – User/role associations managed via grouping API ( | Full (2) – Scopes managed as strings in parameters. | Full (2) – Assignments handled with Python SDK client. |
Implied Permissions (e.g., edit ⇒ read) | Partial (1) – Achieved via role hierarchy (inheritance) or custom functions (e.g., | Null (0) – Must be handled explicitly; no inheritance mechanism. | Partial (1) – Must be explicitly specified in the model. |
Object-Level Permissions (per resource, e.g., course A) | Full (2) – Native | Full (2) – Managed via scope strings as parameters. | Full (2) – Roles/permissions tied directly to resources (objects). |
Multi-Resource Permissions (e.g., view course A & B) | Full (2) – | Full (2) – Lists can be passed as parameters. | Partial (1) – Not supported out-of-the-box; must duplicate permissions. |
Resource Grouping (e.g., all courses in Org A) | Full (2) – Use RBAC roles or ABAC attributes ( | Null (0) – No resource inheritance; regex workaround needed. | Full (2) – Supports parent-child resource grouping natively. |
Plugin-Defined Permissions | Partial (1) – Plugins register policies via API/adapter; no central registry required. | Full (2) – Roles and permissions are DB records, can be modified or added directly. | Partial (1) – Would require schema updates/patches; limited by immutability. |
Performance & Scalability | Partial (1) – Strong in-memory performance for small/medium sets, but large policy sets can degrade performance; optimizations needed for scale. | Partial (1) – Works but string-based scope queries can be expensive at scale. | Full (2) – Designed for high scalability; optimized for large policy graphs. |
Extensibility & Customization | Full (2) – Highly extensible with adapters and plugins; flexible modeling. | Partial (1) – Extendable via API/DB, but uninstalling plugins may cause inconsistencies. | Partial (1) – Limited; immutable schema constrains customization. |
Standards Compliance | Full (2) – Supports multiple industry models (ACL, RBAC, ABAC, ReBAC, BLP, Biba, LBAC). | Partial (1) – Easy to use but risks DB growth without monitoring. | Partial (1) – Implements ReBAC well, but adds complexity; requires separate service. |
Maturity | Full (2) – Established, widely adopted, multi-ecosystem project; strong documentation. | Partial (1) – Small library with limited adoption; often paired with Bridgekeeper for queries. | Full (2) – Actively developed, strong query and audit support. |
Community & Support | Full (2) – Active community; many maintained adapters and watchers. | Partial (1) – Small community; not much ongoing support. | Full (2) – Strong backing and active open source community. |
Security & Compliance | Full (2) – Strong enforcement, logging; compliance requires app/DB-level audit. | Partial (1) – Only checks privileges; limited features. | Full (2) – Strong enforcement and audit capabilities. |
Learning Curve | Partial (1) – Basics easy (ACL/RBAC), advanced policies and ABAC harder; requires training. | Full (2) – Very easy for Django developers. | Partial (1) – ReBAC concepts harder to learn; steeper than RBAC/ABAC. |
Total Cost of Ownership (TCO) | Partial (1) – No extra service; open source; but no UI, so extra development overhead. | Full (2) – Lightweight, low operational cost; DB optimization may be needed. | Partial (1) – Requires running/maintaining a separate service. |
Total Points | 29/36 | 24/36 | 25/36 |