openedx_authz.api package#

Submodules#

openedx_authz.api.data module#

Data classes and enums for representing roles, permissions, and policies.

class openedx_authz.api.data.ActionData(external_key: str = '', namespaced_key: str = '')

Bases: AuthZData

An action represents an operation that can be performed in the authorization system.

NAMESPACE

‘act’ for actions.

Type:

ClassVar[str]

external_key

The action identifier (e.g., ‘content_libraries.view_library’).

Type:

str

namespaced_key

The action identifier with namespace (e.g., ‘act^content_libraries.view_library’).

Type:

str

Examples

>>> action = ActionData(external_key='content_libraries.delete_library')
>>> action.namespaced_key
'act^content_libraries.delete_library'
>>> action.name
'Content Libraries > Delete Library'
NAMESPACE: ClassVar[str] = 'act'
property name: str

The human-readable name of the action (e.g., ‘Content Libraries > Delete Library’).

class openedx_authz.api.data.AuthZData(external_key: str = '', namespaced_key: str = '')

Bases: AuthzBaseClass

Base class for all authz data classes.

external_key: str
namespaced_key: str
class openedx_authz.api.data.AuthzBaseClass

Bases: object

Base class for all authz classes.

NAMESPACE: ClassVar[str] = None
SEPARATOR: ClassVar[str] = '^'
class openedx_authz.api.data.ContentLibraryData(*args, **kwargs)

Bases: ScopeData

A content library scope for authorization in the Open edX platform.

Content libraries use the LibraryLocatorV2 format for identification.

NAMESPACE

‘lib’ for content library scopes.

Type:

str

ID_SEPARATOR

‘:’ for content library scopes.

Type:

str

external_key

The content library identifier (e.g., ‘lib:DemoX:CSPROB’). Must be a valid LibraryLocatorV2 format.

Type:

str

namespaced_key

The library identifier with namespace (e.g., ‘lib^lib:DemoX:CSPROB’).

Type:

str

library_id

Property alias for external_key.

Type:

str

Examples

>>> library = ContentLibraryData(external_key='lib:DemoX:CSPROB')
>>> library.namespaced_key
'lib^lib:DemoX:CSPROB'
>>> library.library_id
'lib:DemoX:CSPROB'

Note

TODO: this class should live alongside library definitions and not here.

ID_SEPARATOR: ClassVar[str] = ':'
NAMESPACE: ClassVar[str] = 'lib'
exists() bool

Check if the content library exists.

Returns:

True if the content library exists, False otherwise.

Return type:

bool

classmethod get_admin_manage_permission() PermissionData

Get the permission required to manage this scope

Returns:

The permission required to manage this scope in the admin console.

Return type:

PermissionData

classmethod get_admin_view_permission() PermissionData

Get the permission required to view this scope

Returns:

The permission required to view this scope in the admin console.

Return type:

PermissionData

get_object() ContentLibrary | None

Retrieve the ContentLibrary instance associated with this scope.

This method converts the library_id to a LibraryLocatorV2 key and queries the database to fetch the corresponding ContentLibrary object.

Returns:

The ContentLibrary instance if found in the database,

or None if the library does not exist or has an invalid key format.

Return type:

ContentLibrary | None

Examples

>>> library_scope = ContentLibraryData(external_key='lib:DemoX:CSPROB')
>>> library_obj = library_scope.get_object() # ContentLibrary object
property library_id: str

CSPROB’).

This is an alias for external_key that represents the library ID without the namespace prefix.

Returns:

The library identifier without namespace.

Return type:

str

Type:

The library identifier as used in Open edX (e.g., ‘lib

Type:

DemoX

library_key: LibraryLocatorV2
property org: str

Get the organization name from the library key.

Returns:

The organization name (e.g., DemoX from lib:DemoX:CSPROB).

Return type:

str

classmethod validate_external_key(external_key: str) bool

Validate the external_key format for ContentLibraryData.

Parameters:

external_key – The external key to validate.

Returns:

True if valid, False otherwise.

Return type:

bool

class openedx_authz.api.data.CourseOverviewData(*args, **kwargs)

Bases: ScopeData

A course scope for authorization in the Open edX platform.

Courses uses the CourseKey format for identification.

NAMESPACE

‘course-v1’ for course scopes.

Type:

str

ID_SEPARATOR

‘+’ for course scopes.

Type:

str

external_key

The course identifier (e.g., ‘course-v1:TestOrg+TestCourse+2024_T1’). Must be a valid CourseKey format.

Type:

str

namespaced_key

The course identifier with namespace (e.g., ‘course-v1^course-v1:TestOrg+TestCourse+2024_T1’).

Type:

str

course_id

Property alias for external_key.

Type:

str

Examples

>>> course = CourseOverviewData(external_key='course-v1:TestOrg+TestCourse+2024_T1')
>>> course.namespaced_key
'course-v1^course-v1:TestOrg+TestCourse+2024_T1'
>>> course.course_id
'course-v1:TestOrg+TestCourse+2024_T1'
ID_SEPARATOR: ClassVar[str] = '+'
NAMESPACE: ClassVar[str] = 'course-v1'
property course_id: str

TestOrg+TestCourse+2024_T1’).

This is an alias for external_key that represents the course ID without the namespace prefix.

Returns:

The course identifier without namespace.

Return type:

str

Type:

The course identifier as used in Open edX (e.g., ‘course-v1

course_key: CourseKey
exists() bool

Check if the course overview exists.

Returns:

True if the course overview exists, False otherwise.

Return type:

bool

classmethod get_admin_manage_permission() PermissionData

Get the permission required to manage this scope

Returns:

The permission required to manage this scope in the admin console.

Return type:

PermissionData

classmethod get_admin_view_permission() PermissionData

Get the permission required to view this scope

Returns:

The permission required to view this scope in the admin console.

Return type:

PermissionData

get_object() CourseOverview | None

Retrieve the CourseOverview instance associated with this scope.

This method converts the course_id to a CourseKey and queries the database to fetch the corresponding CourseOverview object.

Returns:

The CourseOverview instance if found in the database,

or None if the course does not exist or has an invalid key format.

Return type:

CourseOverview | None

Examples

>>> course_scope = CourseOverviewData(external_key='course-v1:TestOrg+TestCourse+2024_T1')
>>> course_obj = course_scope.get_object() # CourseOverview object
property org: str

Get the organization name from the course key.

Returns:

The organization name (e.g., DemoX from course-v1:DemoX+TestCourse+2024_T1).

Return type:

str

classmethod validate_external_key(external_key: str) bool

Validate the external_key format for CourseOverviewData.

Parameters:

external_key – The external key to validate.

Returns:

True if valid, False otherwise.

Return type:

bool

class openedx_authz.api.data.GroupingPolicyIndex(*values)

Bases: Enum

Index positions for fields in a Casbin grouping policy (g or g2).

Grouping policies represent role assignments that link subjects to roles within scopes. Format: [subject, role, scope, …]

SUBJECT

Position 0 - The subject identifier (e.g., ‘user^john_doe’).

ROLE

Position 1 - The role identifier (e.g., ‘role^instructor’).

SCOPE

Position 2 - The scope identifier (e.g., ‘lib^lib:DemoX:CSPROB’).

Note

Additional fields beyond position 2 are optional and currently ignored.

ROLE = 1
SCOPE = 2
SUBJECT = 0
class openedx_authz.api.data.OrgContentLibraryGlobData(*args, **kwargs)

Bases: OrgGlobData

Organization-level glob pattern for content libraries.

This class represents glob patterns that match multiple libraries within an organization. Format: lib:ORG:* where ORG is a valid organization identifier.

The glob pattern allows granting permissions to all libraries within a specific organization without needing to specify each library individually.

NAMESPACE

‘lib’ for content library scopes.

Type:

str

ID_SEPARATOR

‘:’ for content library scopes.

Type:

str

IS_GLOB

True for scope data that represents a glob pattern.

Type:

bool

external_key

The glob pattern (e.g., lib:DemoX:*).

Type:

str

namespaced_key

The pattern with namespace (e.g., lib^lib:DemoX:*).

Type:

str

Validation Rules:
  • Must end with GLOBAL_SCOPE_WILDCARD (*)

  • Must have format lib:ORG:* (exactly one organization identifier)

  • The organization must exist

  • Wildcard can only appear at the end after org identifier

  • Cannot have wildcards at slug level (lib:ORG:SLUG* is invalid)

Examples

>>> glob = OrgContentLibraryGlobData(external_key='lib:DemoX:*')
>>> glob.org
'DemoX'
>>> glob.get_object()
<Organization: DemoX>

Note

This class is automatically instantiated by the ScopeMeta metaclass when a library scope with a wildcard is created.

ID_SEPARATOR: ClassVar[str] = ':'
NAMESPACE: ClassVar[str] = 'lib'
classmethod get_admin_manage_permission() PermissionData

Get the permission required to manage this scope

Returns:

The permission required to manage this scope in the admin console.

Return type:

PermissionData

classmethod get_admin_view_permission() PermissionData

Get the permission required to view this scope

Returns:

The permission required to view this scope in the admin console.

Return type:

PermissionData

class openedx_authz.api.data.OrgCourseOverviewGlobData(*args, **kwargs)

Bases: OrgGlobData

Organization-level glob pattern for courses.

This class represents glob patterns that match multiple courses within an organization. Format: ‘course-v1:ORG+*’ where ORG is a valid organization identifier.

The glob pattern allows granting permissions to all courses within a specific organization without needing to specify each course individually.

NAMESPACE

‘course-v1’ for course scopes.

Type:

str

ID_SEPARATOR

‘+’ for course scopes.

Type:

str

IS_GLOB

True for scope data that represents a glob pattern.

Type:

bool

external_key

The glob pattern (e.g., ‘course-v1:OpenedX+*’).

Type:

str

namespaced_key

The pattern with namespace (e.g., ‘course-v1^course-v1:OpenedX+*’).

Type:

str

Validation Rules:
  • Must end with GLOBAL_SCOPE_WILDCARD (*)

  • Must have format ‘course-v1:ORG+*’ (exactly one organization identifier)

  • The organization must exist

  • Wildcard can only appear at the end after org identifier

  • Cannot have wildcards at course or run level (course-v1:ORG+COURSE* is invalid)

Examples

>>> glob = OrgCourseOverviewGlobData(external_key='course-v1:OpenedX+*')
>>> glob.org
'OpenedX'
>>> glob.get_object()
<Organization: OpenedX>

Note

This class is automatically instantiated by the ScopeMeta metaclass when a course scope with a wildcard is created.

ID_SEPARATOR: ClassVar[str] = '+'
NAMESPACE: ClassVar[str] = 'course-v1'
classmethod get_admin_manage_permission() PermissionData

Get the permission required to manage this scope

Returns:

The permission required to manage this scope in the admin console.

Return type:

PermissionData

classmethod get_admin_view_permission() PermissionData

Get the permission required to view this scope

Returns:

The permission required to view this scope in the admin console.

Return type:

PermissionData

class openedx_authz.api.data.OrgGlobData(*args, **kwargs)

Bases: ScopeData

Base class for organization-scoped glob scope keys.

This represents an organization-wide pattern: it matches “all resources within an organization” for a given namespace, rather than a single concrete object. The pattern is stored in external_key and must end with the global wildcard (*).

The expected shape is:

{NAMESPACE}{EXTERNAL_KEY_SEPARATOR}{org}{ID_SEPARATOR}*

where {org} is the organization identifier (e.g., DemoX) and ID_SEPARATOR is namespace-specific (subclasses must define it to match their key format).

IS_GLOB

Always True for organization-level glob patterns.

Type:

bool

ID_SEPARATOR

Separator used right before the wildcard (e.g., : or +).

Type:

str

ORG_NAME_VALID_PATTERN

Regex used to validate the organization identifier extracted from external_key.

Type:

re.Pattern | str

Examples

  • lib:DemoX:* (all libraries in org DemoX)

  • course-v1:DemoX+* (all courses in org DemoX)

ID_SEPARATOR: ClassVar[str]
IS_GLOB: ClassVar[bool] = True
ORG_NAME_VALID_PATTERN: ClassVar[Pattern] = '^[a-zA-Z0-9._-]*$'
classmethod build_external_key(org: str) str

Build the external key for all resources within the given organization.

Parameters:

org (str) – The organization identifier (e.g., DemoX).

Returns:

The external key for the org-level glob (e.g., course-v1:DemoX+*).

Return type:

str

Examples

>>> OrgCourseOverviewGlobData.build_external_key('DemoX')
'course-v1:DemoX+*'
>>> OrgContentLibraryGlobData.build_external_key('DemoX')
'lib:DemoX:*'
exists() bool

Check if the organization exists.

Returns:

True if the organization exists, False otherwise.

Return type:

bool

classmethod get_admin_manage_permission() PermissionData

Get the permission required to manage this scope

Returns:

The permission required to manage this scope in the admin console.

Return type:

PermissionData

classmethod get_admin_view_permission() PermissionData

Get the permission required to view this scope

Returns:

The permission required to view this scope in the admin console.

Return type:

PermissionData

get_object() Organization | None

Retrieve the Organization instance associated with this scope.

Returns:

The Organization instance if found,

or None if the organization does not exist.

Return type:

Organization | None

classmethod get_org(external_key: str) str | None

Extract the organization identifier from the glob pattern.

Parameters:

external_key (str) – The external key to extract the organization identifier from.

Returns:

The organization identifier (e.g., DemoX from lib:DemoX:*), None otherwise.

Return type:

str

property org: str | None

Get the organization identifier from the glob pattern.

Returns:

The organization identifier (e.g., DemoX from lib:DemoX:*), None otherwise.

Return type:

str

classmethod validate_external_key(external_key: str) bool

Validate the external_key format for organization-level glob patterns.

Parameters:

external_key (str) – The external key to validate (e.g., lib:DemoX:* or course-v1:DemoX+*).

Returns:

True if the format is valid, False otherwise.

Return type:

bool

class openedx_authz.api.data.PermissionData(action: ActionData = None, effect: Literal['allow', 'deny'] = 'allow')

Bases: object

A permission combines an action with an effect (allow or deny).

action

The action being permitted or denied (ActionData instance).

Type:

openedx_authz.data.ActionData

effect

The effect of the permission, either ‘allow’ or ‘deny’ (default: ‘allow’).

Type:

Literal[‘allow’, ‘deny’]

Examples

>>> read_action = ActionData(external_key='read')
>>> permission = PermissionData(action=read_action, effect='allow')
>>> str(permission)
'Read - allow'
action: ActionData
effect: Literal['allow', 'deny']
property identifier: str

Get the permission identifier.

class openedx_authz.api.data.PolicyIndex(*values)

Bases: Enum

Index positions for fields in a Casbin policy (p).

Policies define permissions by linking roles to actions within scopes with an effect. Format: [role, action, scope, effect, …]

ROLE

Position 0 - The role identifier (e.g., ‘role^instructor’).

ACT

Position 1 - The action identifier (e.g., ‘act^read’).

SCOPE

Position 2 - The scope identifier (e.g., ‘lib^lib:DemoX:CSPROB’).

EFFECT

Position 3 - The effect, either ‘allow’ or ‘deny’.

Note

Additional fields beyond position 3 are optional and currently ignored.

ACT = 1
EFFECT = 3
ROLE = 0
SCOPE = 2
class openedx_authz.api.data.RoleAssignmentData(subject: SubjectData = None, roles: list[RoleData] = [], scope: ScopeData = None)

Bases: object

A role assignment links a subject, roles, and a scope together.

Role assignments represent the authorization grants in the system. They specify that a particular subject (e.g., a user) has certain roles within a specific scope (e.g., a content library).

subject

The subject (e.g., UserData) to whom roles are assigned.

Type:

openedx_authz.api.data.SubjectData

roles

A list of RoleData instances being assigned to the subject.

Type:

list[openedx_authz.api.data.RoleData]

scope

The scope (e.g., ContentLibraryData) in which the roles apply.

Type:

openedx_authz.api.data.ScopeData

Examples

>>> user = UserData(external_key='john_doe')
>>> role = RoleData(external_key='instructor')
>>> library = ContentLibraryData(external_key='lib:DemoX:CSPROB')
>>> assignment = RoleAssignmentData(subject=user, roles=[role], scope=library)
>>> str(assignment)
'john_doe => Instructor @ lib:DemoX:CSPROB'
>>> repr(assignment)
'user^john_doe => [role^instructor] @ lib^lib:DemoX:CSPROB'
roles: list[RoleData]
scope: ScopeData
subject: SubjectData
class openedx_authz.api.data.RoleData(external_key: str = '', namespaced_key: str = '', permissions: list[PermissionData] = [])

Bases: AuthZData

A role is a named collection of permissions that can be assigned to subjects.

Roles group related permissions together for easier authorization management.

NAMESPACE

‘role’ for roles.

Type:

ClassVar[str]

external_key

The role identifier (e.g., ‘instructor’, ‘library_admin’).

Type:

str

namespaced_key

The role identifier with namespace (e.g., ‘role^instructor’).

Type:

str

permissions

A list of PermissionData instances associated with this role.

Type:

list[openedx_authz.data.PermissionData]

name

Property that returns a human-readable role name (e.g., ‘Instructor’, ‘Library Admin’).

Examples

>>> role = RoleData(external_key='instructor')
>>> role.namespaced_key
'role^instructor'
>>> role.name
'Instructor'
>>> action = ActionData(external_key='read')
>>> perm = PermissionData(action=action, effect='allow')
>>> role_with_perms = RoleData(external_key='instructor', permissions=[perm])
>>> str(role_with_perms)
'Instructor: Read - allow'
NAMESPACE: ClassVar[str] = 'role'
get_permission_identifiers() list[str]

Get the technical identifiers for all permissions in this role.

Returns:

Permission identifiers

(e.g., [‘content_libraries.delete_library’, ‘content_libraries.edit_library_content’]).

Return type:

list[str]

property name: str

The human-readable name of the role (e.g., ‘Library Admin’, ‘Course Instructor’).

This property transforms the external_key into a human-readable display name by replacing underscores with spaces and capitalizing each word.

Returns:

The human-readable role name (e.g., ‘Library Admin’).

Return type:

str

permissions: list[PermissionData]
class openedx_authz.api.data.ScopeData(*args, **kwargs)

Bases: AuthZData

A scope is a context in which roles and permissions are assigned.

This is the base class for scope types. Specific scope types (like ContentLibraryData) are subclasses with their own namespace prefixes. This class is supposed to be generic and not tied to any specific scope type, holding attributes common to all scopes.

NAMESPACE

‘global’ for generic scopes.

Type:

ClassVar[str]

external_key

The scope identifier without namespace (e.g., ‘generic_scope’).

Type:

str

namespaced_key

The scope identifier with namespace (e.g., ‘global^generic_scope’).

Type:

str

Examples

>>> scope = ScopeData(external_key='generic_scope')
>>> scope.namespaced_key
'global^generic_scope'
IS_GLOB: ClassVar[bool] = False
NAMESPACE: ClassVar[str] = 'global'
abstractmethod exists() bool

Check if the scope exists.

Returns:

True if the scope exists, False otherwise.

Return type:

bool

abstractmethod classmethod get_admin_manage_permission() PermissionData

Get the permission required to manage this scope

This method should be implemented on every ScopeData subclass to define which permission to check against when a user tries to manage assignations related to this scope in the Admin Console.

Returns:

The permission required to manage this scope in the admin console.

Return type:

PermissionData

abstractmethod classmethod get_admin_view_permission() PermissionData

Get the permission required to view this scope

This method should be implemented on every ScopeData subclass to define which permission to check against when a user tries to see assignations related to this scope in the Admin Console.

Returns:

The permission required to view this scope in the admin console.

Return type:

PermissionData

abstractmethod get_object() Any | None

Retrieve the underlying domain object that this scope represents.

This method fetches the actual Open edX object (e.g., ContentLibrary, Organization) associated with this scope’s external_key. Subclasses should implement this to return their specific object types.

Returns:

The domain object associated with this scope, or None if the object

does not exist or cannot be retrieved.

Return type:

Any | None

classmethod validate_external_key(_: str) bool

Validate the external_key format for ScopeData.

For the base ScopeData class, we accept any external_key works. This is only implemented for the sake of completeness. Subclasses should implement their own validation logic.

Parameters:

external_key – The external key to validate.

Returns:

True if valid, False otherwise.

Return type:

bool

class openedx_authz.api.data.SubjectData(*args, **kwargs)

Bases: AuthZData

A subject is an entity that can be assigned roles and permissions.

This is the base class for subject types. Specific subject types (like UserData) are subclasses with their own namespace prefixes.

NAMESPACE

‘sub’ for generic subjects.

Type:

ClassVar[str]

external_key

The subject identifier without namespace (e.g., ‘generic’).

Type:

str

namespaced_key

The subject identifier with namespace (e.g., ‘sub^generic’).

Type:

str

Examples

>>> subject = SubjectData(external_key='generic')
>>> subject.namespaced_key
'sub^generic'
NAMESPACE: ClassVar[str] = 'sub'
class openedx_authz.api.data.SuperAdminAssignmentData(user: 'User' | None = None, is_staff: bool = False, is_superuser: bool = False)

Bases: object

Represents a superadmin entry in a team member assignment list.

Used alongside RoleAssignmentData in serializer contexts where a user is a staff/superuser and their access is not derived from a specific role assignment.

is_staff: bool
is_superuser: bool
user: 'User' | None
class openedx_authz.api.data.UserAssignmentData(subject: SubjectData = None, roles: list[RoleData] = [], scope: ScopeData = None, user: 'User' | None = None)

Bases: RoleAssignmentData

Represents a user entry in a team member assignment list.

Used alongside SuperAdminAssignmentData in serializer contexts where individual assignment along with its assigned user information is needed.

user: 'User' | None
class openedx_authz.api.data.UserData(*args, **kwargs)

Bases: SubjectData

A user subject for authorization in the Open edX platform.

This class represents individual users who can be assigned roles and permissions. Can be initialized with either external_key or namespaced_key parameter.

NAMESPACE

‘user’ for user subjects.

Type:

ClassVar[str]

external_key

The username (e.g., ‘john_doe’).

Type:

str

namespaced_key

The username with namespace prefix (e.g., ‘user^john_doe’).

Type:

str

username

Property alias for external_key.

Examples

>>> user = UserData(external_key='john_doe')
>>> user.namespaced_key
'user^john_doe'
>>> user.username
'john_doe'
>>> user2 = UserData(namespaced_key='user^jane_smith')
>>> user2.username
'jane_smith'
NAMESPACE: ClassVar[str] = 'user'
property username: str

The username for the user (e.g., ‘john_doe’).

This is an alias for external_key that represents the username without the namespace prefix.

Returns:

The username without namespace.

Return type:

str

openedx_authz.api.permissions module#

Public API for permissions management.

A permission is the authorization granted by a policy. It represents the allowed actions(s) a subject can perform on an object. In Casbin, permissions are not explicitly defined, but are inferred from the policy rules.

openedx_authz.api.permissions.get_all_permissions_in_scope(scope: ScopeData) list[PermissionData]

Retrieve all permissions associated with a specific scope.

Parameters:

scope – The scope to filter permissions by.

Returns:

A list of PermissionData objects associated with the given scope.

Return type:

list of PermissionData

openedx_authz.api.permissions.get_permission_from_policy(policy: list[str]) PermissionData

Convert a Casbin policy list to a PermissionData object.

Parameters:

policy – A list representing a Casbin policy.

Returns:

The corresponding PermissionData object or an empty PermissionData if the policy is invalid.

Return type:

PermissionData

openedx_authz.api.permissions.is_subject_allowed(subject: SubjectData, action: ActionData, scope: ScopeData) bool

Check if a subject has a specific permission in a given scope.

Parameters:
  • subject – The subject to check (e.g., user or service).

  • action – The action to check (e.g., ‘view_course’).

  • scope – The scope in which to check the permission (e.g., ‘course-v1:edX+DemoX+2021_T1’).

Returns:

True if the subject has the specified permission in the scope, False otherwise.

Return type:

bool

openedx_authz.api.roles module#

Public API for roles management.

A role is named group of permissions (actions). Instead of assigning permissions to each subject, permissions can be assigned to a role, and subjects inherit the role’s permissions.

We’ll interact with roles through this API, which will use the enforcer internally to manage the underlying policies and role assignments.

openedx_authz.api.roles.assign_role_to_subject_in_scope(subject: SubjectData, role: RoleData, scope: ScopeData) bool

Assign a role to a subject within a specific scope.

This function creates a role assignment by adding a grouping policy to the enforcer and creating an ExtendedCasbinRule for auditing purposes. It also sends a ROLE_ASSIGNMENT_CREATED event after the transaction commits.

Parameters:
  • subject – The ID of the subject.

  • role – The role to assign.

  • scope – The scope to assign the role to.

Returns:

True if the role was assigned successfully, False otherwise.

Return type:

bool

openedx_authz.api.roles.batch_assign_role_to_subjects_in_scope(subjects: list[SubjectData], role: RoleData, scope: ScopeData) None

Assign a role to a list of subjects.

Parameters:
  • subjects – A list of subject IDs.

  • role – The role to assign.

openedx_authz.api.roles.batch_unassign_role_from_subjects_in_scope(subjects: list[SubjectData], role: RoleData, scope: ScopeData) None

Unassign a role from a list of subjects.

Parameters:
  • subjects – A list of subject IDs.

  • role_name – The external_key of the role.

  • scope – The scope from which to unassign the role.

openedx_authz.api.roles.get_all_role_assignments_per_scope_type(scope_types: tuple[type[ScopeData], ...]) list[RoleAssignmentData]

Get all role assignments matching any of the given scope types.

Loads all grouping policies from the enforcer and filters in Python. Casbin policies store full scope keys (e.g., ‘course-v1^course-v1:Org+Course+Run’), so there is no way to query by scope type directly so the filtering must happen here.

Parameters:

scope_types – A list of ScopeData subclasses (not instances). Assignments matching any of the given types are returned.

Returns:

All assignments whose scope is an instance of any of the given scope types.

Return type:

list[RoleAssignmentData]

openedx_authz.api.roles.get_all_roles_in_scope(scope: ScopeData) list[list[str]]

Get all the available role grouping policies in a specific scope.

Parameters:

scope – The scope to filter roles (e.g., ‘lib^*’ or ‘*’ for global).

Returns:

A list of policies in the specified scope.

Return type:

list[list[str]]

openedx_authz.api.roles.get_all_roles_names() list[str]

Get all the available roles names in the current environment.

Returns:

A list of role names.

Return type:

list[str]

openedx_authz.api.roles.get_all_subject_role_assignments() list[RoleAssignmentData]

Get all the roles for every subject across all scopes.

Returns:

A list of role assignments for the subject.

Return type:

list[RoleAssignmentData]

openedx_authz.api.roles.get_all_subject_role_assignments_in_scope(scope: ScopeData) list[RoleAssignmentData]

Get all the subjects assigned to any role in a specific scope.

Parameters:

scope – The ScopeData object representing the scope (e.g., ScopeData(external_key=’lib:DemoX:CSPROB’)).

Returns:

A list of role assignments for all subjects in the specified scope.

Return type:

list[RoleAssignmentData]

openedx_authz.api.roles.get_permissions_for_active_roles_in_scope(scope: ScopeData, role: RoleData | None = None) dict[str, dict[str, list[PermissionData | str]]]

Retrieve all permissions granted by the specified roles within the given scope.

This function operates on the principle that roles defined in policies are templates that become active only when assigned to subjects with specific scopes.

Role Definition vs Role Assignment:

  • Policy roles define potential permissions with namespace patterns (e.g., ‘lib^*’)

  • Actual permissions are granted only when roles are assigned to subjects with concrete scopes (e.g., ‘lib^lib:DemoX:CSPROB’)

  • The namespace pattern in the policy (‘lib^*’) indicates the role is designed for resources in that namespace, but doesn’t grant blanket access

  • The specific scope at assignment time (‘lib^lib:DemoX:CSPROB’) determines the exact resource the permissions apply to

Behavior:

  • Returns permissions only for roles that have been assigned to subjects

  • Unassigned roles (those defined in policy but not given to any subject) contribute no permissions to the result

  • Scope filtering ensures permissions are returned only for the specified resource scope, not for the broader namespace pattern

Returns:

A dictionary mapping the role external_key to its permissions and scopes.

Return type:

dict[str, list[PermissionData]]

openedx_authz.api.roles.get_permissions_for_roles(roles: list[RoleData]) dict[str, dict[str, list[PermissionData | str]]]

Get the permissions (actions) for a list of roles.

Parameters:

role_names – A list of role names or a single role name.

Returns:

A dictionary mapping role names to their permissions and scopes.

Return type:

dict[str, list[PermissionData]]

openedx_authz.api.roles.get_permissions_for_single_role(role: RoleData) list[PermissionData]

Get the permissions (actions) for a single role.

Parameters:

role – A RoleData object representing the role.

Returns:

A list of PermissionData objects associated with the given role.

Return type:

list[PermissionData]

openedx_authz.api.roles.get_role_assignments(*, subject: SubjectData | None = None, role: RoleData | None = None, scope: ScopeData | None = None) list[RoleAssignmentData]

Get all the roles for a subject across all scopes filtered by the given filters.

Parameters:
  • subject – Optional SubjectData object to filter by.

  • role – Optional RoleData object to filter by.

  • scope – Optional ScopeData object to filter by.

Returns:

A list of RoleAssignmentData objects filtered by the given filters.

Return type:

list[RoleAssignmentData]

openedx_authz.api.roles.get_role_definitions_in_scope(scope: ScopeData) list[RoleData]

Get all role definitions available in a specific scope.

See get_permissions_for_active_roles_in_scope for explanation of role definitions vs assignments.

Parameters:

scope – The scope to filter roles (e.g., ‘lib^*’ or ‘*’ for global).

Returns:

A list of roles.

Return type:

list[Role]

openedx_authz.api.roles.get_scopes_for_subject_and_permission(subject: SubjectData, permission: PermissionData) list[ScopeData]

Get all scopes where a specific subject has been assigned a specific permission via roles.

Parameters:
  • permission (PermissionData) – The permission to filter scopes.

  • subject (SubjectData) – The subject to filter scopes.

Returns:

A list of scopes where the subject is assigned the specified permission.

Return type:

list[ScopeData]

openedx_authz.api.roles.get_subject_role_assignments(subject: SubjectData) list[RoleAssignmentData]

Get all the roles for a subject across all scopes.

Parameters:

subject – The SubjectData object representing the subject (e.g., SubjectData(external_key=’john_doe’)).

Returns:

A list of role assignments for the subject.

Return type:

list[RoleAssignmentData]

openedx_authz.api.roles.get_subject_role_assignments_for_role_in_scope(role: RoleData, scope: ScopeData) list[RoleAssignmentData]

Get the subjects assigned to a specific role in a specific scope.

Parameters:
  • role – The RoleData object representing the role (e.g., RoleData(external_key=’library_admin’)).

  • scope – The ScopeData object representing the scope (e.g., ScopeData(external_key=’lib:DemoX:CSPROB’)).

Returns:

A list of subjects assigned to the specified role in the specified scope.

Return type:

list[RoleAssignmentData]

openedx_authz.api.roles.get_subject_role_assignments_in_scope(subject: SubjectData, scope: ScopeData) list[RoleAssignmentData]

Get the roles for a subject in a specific scope.

Parameters:
  • subject – The SubjectData object representing the subject (e.g., SubjectData(external_key=’john_doe’)).

  • scope – The ScopeData object representing the scope (e.g., ScopeData(external_key=’lib:DemoX:CSPROB’)).

Returns:

A list of role assignments for the subject in the scope.

Return type:

list[RoleAssignmentData]

openedx_authz.api.roles.unassign_role_from_subject_in_scope(subject: SubjectData, role: RoleData, scope: ScopeData) bool

Unassign a role from a subject within a specific scope.

This function removes a role assignment by deleting the corresponding grouping policy from the enforcer and deleting the associated ExtendedCasbinRule for auditing purposes. It also sends a ROLE_ASSIGNMENT_DELETED event after the transaction commits.

Parameters:
  • subject – The ID of the subject.

  • role – The role to unassign.

  • scope – The scope from which to unassign the role.

Returns:

True if the role was unassigned successfully, False otherwise.

Return type:

bool

openedx_authz.api.roles.unassign_subject_from_all_roles(subject: SubjectData) bool

Unassign a subject from all roles across all scopes.

Parameters:

subject – The SubjectData object representing the subject to unassign.

Returns:

True if any roles were removed, False otherwise.

Return type:

bool

openedx_authz.api.users module#

User-related API methods for role assignments and retrievals.

This module provides user-related API methods for assigning roles to users, unassigning roles from users, and retrieving roles assigned to users within the Open edX AuthZ framework.

These methods internally namespace user identifiers to ensure consistency with the role management system, which uses namespaced subjects (e.g., ‘user^john_doe’).

openedx_authz.api.users.assign_role_to_user_in_scope(user_external_key: str, role_external_key: str, scope_external_key: str) bool

Assign a role to a user in a specific scope.

Parameters:
  • user (str) – ID of the user (e.g., ‘john_doe’).

  • role_external_key (str) – Name of the role to assign.

  • scope (str) – Scope in which to assign the role.

Returns:

True if the role was assigned successfully, False otherwise.

Return type:

bool

openedx_authz.api.users.batch_assign_role_to_users_in_scope(users: list[str], role_external_key: str, scope_external_key: str)

Assign a role to multiple users in a specific scope.

Parameters:
  • users (list of str) – List of user IDs (e.g., [‘john_doe’, ‘jane_smith’]).

  • role_external_key (str) – Name of the role to assign.

  • scope (str) – Scope in which to assign the role.

openedx_authz.api.users.batch_unassign_role_from_users(users: list[str], role_external_key: str, scope_external_key: str)

Unassign a role from multiple users in a specific scope.

Parameters:
  • users (list of str) – List of user IDs (e.g., [‘john_doe’, ‘jane_smith’]).

  • role_external_key (str) – Name of the role to unassign.

  • scope (str) – Scope in which to unassign the role.

openedx_authz.api.users.get_all_user_role_assignments_in_scope(scope_external_key: str) list[RoleAssignmentData]

Get all user role assignments in a specific scope.

Parameters:

scope (str) – Scope in which to retrieve the user role assignments.

Returns:

A list of user role assignments and all their metadata in the specified scope.

Return type:

list[RoleAssignmentData]

openedx_authz.api.users.get_scopes_for_user_and_permission(user_external_key: str, action_external_key: str) list[ScopeData]

Get all scopes where a specific user is assigned a specific permission.

Parameters:
  • user_external_key (str) – ID of the user (e.g., ‘john_doe’).

  • action_external_key (str) – The action to filter scopes (e.g., ‘view’, ‘edit’).

Returns:

A list of scopes where the user is assigned the specified permission.

Return type:

list[ScopeData]

openedx_authz.api.users.get_superadmin_assignments(user_external_keys: list[str] | None = None) list[SuperAdminAssignmentData]

Returns all superadmins as SuperAdminAssignmentData.

A superadmin is a User with a Django staff or superuser role. Superadmins automatically are allowed to do any action.

Parameters:

user_external_keys (list[str] or None) – To filter by usernames

Returns:

The superadmin data

Return type:

list[SuperAdminAssignmentData]

openedx_authz.api.users.get_user_role_assignments(user_external_key: str) list[RoleAssignmentData]

Get all roles for a user across all scopes.

Parameters:

user_external_key (str) – ID of the user (e.g., ‘john_doe’).

Returns:

A list of role assignments and all their metadata assigned to the user.

Return type:

list[RoleAssignmentData]

openedx_authz.api.users.get_user_role_assignments_filtered(*, user_external_key: str | None = None, role_external_key: str | None = None, scope_external_key: str | None = None) list[RoleAssignmentData]

Get role assignments filtered by user, role, and/or scope.

This function provides flexible filtering of role assignments by any combination of user, role, and scope. At least one filter parameter should be provided for meaningful results.

Parameters:
  • user_external_key – Optional user ID to filter by (e.g., ‘john_doe’).

  • role_external_key – Optional role name to filter by (e.g., ‘library_admin’).

  • scope_external_key – Optional scope to filter by (e.g., ‘lib:DemoX:CSPROB’).

Returns:

Filtered role assignments.

Return type:

list[RoleAssignmentData]

openedx_authz.api.users.get_user_role_assignments_for_role_in_scope(role_external_key: str, scope_external_key: str) list[RoleAssignmentData]

Get all users assigned to a specific role across all scopes.

Parameters:
  • role_external_key (str) – Name of the role (e.g., ‘instructor’).

  • scope (str) – Scope in which to retrieve the role assignments.

Returns:

List of users assigned to the specified role in the given scope.

Return type:

list[RoleAssignmentData]

openedx_authz.api.users.get_user_role_assignments_in_scope(user_external_key: str, scope_external_key: str) list[RoleAssignmentData]

Get the roles assigned to a user in a specific scope.

Parameters:
  • user (str) – ID of the user (e.g., ‘john_doe’).

  • scope (str) – Scope in which to retrieve the roles.

Returns:

A list of role assignments assigned to the user in the specified scope.

Return type:

list[RoleAssignmentData]

openedx_authz.api.users.get_users_for_role_in_scope(role_external_key: str, scope_external_key: str) list[UserData]

Get all the users assigned to a specific role in a specific scope.

Parameters:
  • role_external_key (str) – The role to filter users (e.g., ‘library_admin’).

  • scope_external_key (str) – The scope to filter users (e.g., ‘lib:DemoX:CSPROB’).

Returns:

A list of users assigned to the specified role in the specified scope.

Return type:

list[UserData]

openedx_authz.api.users.get_visible_role_assignments_for_user(orgs: list[str] = None, scopes: list[str] = None, roles: list[str] = None, allowed_for_user_external_key: str = None) list[UserAssignments]

Get all user role assignments filtered by orgs and/or scopes, and only include assignments that the specified user has permission to view.

Parameters:
  • orgs – Optional list of orgs to filter by (e.g., [‘edX’, ‘MITx’]).

  • scopes – Optional list of scopes to filter by (e.g., [‘lib:DemoX:CSPROB’]).

  • allowed_for_user_external_key – The username to check permissions against (e.g., ‘john_doe’).

Returns:

A list of users with their role assignments, filtered by orgs/scopes and permissions.

Return type:

list[UserAssignments]

openedx_authz.api.users.get_visible_user_role_assignments_filtered_by_current_user(user_external_key: str, orgs: list[str] = None, roles: list[str] = None, allowed_for_user_external_key: str = None) list[RoleAssignmentData]

Get role assignments for a specific user, filtered by orgs and/or roles, and only include assignments that the specified user has permission to view.

Parameters:
  • user_external_key – The user to get assignments for (e.g., ‘john_doe’).

  • orgs – Optional list of orgs to filter by (e.g., [‘edX’, ‘MITx’]).

  • roles – Optional list of roles to filter by (e.g., [‘library_admin’]).

  • allowed_for_user_external_key – The username to check permissions against (e.g., ‘john_doe’).

Returns:

A list of role assignments for the user, filtered by orgs/roles and permissions.

Return type:

list[RoleAssignmentData]

openedx_authz.api.users.is_user_allowed(user_external_key: str, action_external_key: str, scope_external_key: str) bool

Check if a user has a specific permission in a given scope.

Parameters:
  • user_external_key (str) – ID of the user (e.g., ‘john_doe’).

  • action_external_key (str) – The action to check (e.g., ‘view_course’).

  • scope_external_key (str) – The scope in which to check the permission (e.g., ‘course-v1:edX+DemoX+2021_T1’).

Returns:

True if the user has the specified permission in the scope, False otherwise.

Return type:

bool

openedx_authz.api.users.unassign_all_roles_from_user(user_external_key: str) bool

Unassign all roles from a user across all scopes.

Parameters:

user_external_key (str) – ID of the user (e.g., ‘john_doe’).

Returns:

True if any roles were removed, False otherwise.

Return type:

bool

openedx_authz.api.users.unassign_role_from_user(user_external_key: str, role_external_key: str, scope_external_key: str)

Unassign a role from a user in a specific scope.

Parameters:
  • user_external_key (str) – ID of the user (e.g., ‘john_doe’).

  • role_external_key (str) – Name of the role to unassign.

  • scope_external_key (str) – Scope in which to unassign the role.

Returns:

True if the role was unassigned successfully, False otherwise.

Return type:

bool

openedx_authz.api.users.validate_users(user_identifiers: list[str]) tuple[list[str], list[str]]

Validate a list of user identifiers.

Parameters:

user_identifiers (list[str]) – List of usernames or emails to validate

Returns:

(valid_users, invalid_users) lists

Return type:

tuple

openedx_authz.api.utils module#

Utility functions used on api

openedx_authz.api.utils.filter_user_assignments(users_with_assignments: list[UserAssignments], by: UserAssignmentsFilter, values: list[str]) list[UserAssignments]

Filter user assignments by orgs or scopes.

Returns a list of users that have at least one assignment matching the filters, with only the matching assignments for each matching user.

Parameters:
  • users_with_assignments (list[UserAssignments]) – The list of users with their role assignments.

  • by (UserAssignmentsFilter) – The filter type (by orgs or scopes).

  • values (list[str]) – The list of orgs or scopes to filter by.

Returns:

The filtered list of users with their role assignments.

Return type:

list[UserAssignments]

openedx_authz.api.utils.get_user_assignment_map(role_assignments: list[RoleAssignmentData]) list[UserAssignments]

Group role assignments by user

openedx_authz.api.utils.get_user_map(usernames: list[str]) dict[str, User]

Retrieve a dictionary mapping usernames to User objects for efficient batch lookups.

This function performs a single optimized database query to fetch multiple users, making it ideal for scenarios where we need to look up several users at once (e.g., when serializing multiple user role assignments).

Parameters:

usernames (list[str]) – List of usernames to retrieve. Duplicates are automatically handled by the database query.

Returns:

Dictionary mapping each username to its corresponding User object.

Only users that exist in the database are included in the returned dictionary.

Return type:

dict[str, User]

Module contents#

Public API for the Open edX AuthZ framework.

This module provides a public API as part of the Open edX AuthZ framework. This is part of the Open edX Layer used to abstract the authorization engine and provide a simpler interface for other services in the Open edX ecosystem.