You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Verify platform-level glob scope in AuthZ and openedx-platform #366
The authorization architecture utilizes platform-level glob scopes restricted to specific resource types—specifically, course and library (e.g., course-v1:* and lib:*). This allows designated actors to have platform-wide access to all courses or all libraries without granting overarching administrative access to the entire system. We need to conduct an audit to ensure that these resource-specific platform scopes are correctly applied, respected, and enforced across AuthZ and openedx-platform.
Objective
Audit and verify that the course and library glob scopes are correctly enforced, ensuring they grant the expected platform-wide access to their respective resources without leaking permissions into other scopes or compromising granular access controls.
Scope of Work
Identification:
Identify the zones and endpoints within openedx-authz and openedx-platform (e.g., LMS, Studio) that interact with course and library resources and should support these platform-level glob scopes.
Audit & Verification:
Verify that the AuthZ configuration correctly parses and evaluates course-v1:* and lib:* scopes.
Inspect the authorization decorators/middleware in openedx-platform to confirm they accurately respect these scopes for platform-wide resource access.
Acceptance Criteria
The endpoints and zones requiring course and library platform-level access are identified and documented.
AuthZ and openedx-platform are confirmed to correctly enforce the course-v1:* and lib:* scopes.
Any missing authorization checks or misconfigured discovered during the audit are documented for resolution.
The necessary corrections are applied to the repositories.
The AuthZ → legacy compatibility layer currently has two gaps for platform-wide glob scopes:
authz_get_all_course_assignments_for_user() does not request PlatformCourseOverviewGlobData.
_get_org_and_course_id_from_authz_scope() does not know how to represent a platform-wide scope in the legacy (org, course_id) model.
As a result, platform-wide role assignments are invisible to RoleCache and can cause legacy access checks to incorrectly deny access.
While auditing #38660 for platform-wide glob (course-v1:*) coverage, I found a related gap in the AuthZ → legacy compatibility layer in common/djangoapps/student/roles.py.
Root Cause
authz_get_all_course_assignments_for_user() (roles.py:184) only requests two scope types:
PlatformCourseOverviewGlobData is therefore never included in the assignments fetched for RoleCache / BulkRoleCache.
Even if PlatformCourseOverviewGlobData were included, _get_org_and_course_id_from_authz_scope() (roles.py:163) currently has no branch to handle it. The method only supports:
CourseOverviewData → (org, course_id)
OrgCourseOverviewGlobData → (org, None)
A platform-wide glob does not map cleanly to this (org, course_id) representation because it applies to all organizations and courses.
Impact
This means a user whose only role assignment is a platform-wide glob, such as:
course-v1:*
will not have that role represented in the legacy RoleCache.
Consequently, legacy access checks such as:
RoleCache.has_role(role, course_id, org)
has_access()
CourseRole.has_user()
can report that the user does not have the required role, even though the corresponding AuthZ assignment exists.
This is inconsistent with newer AuthZ-native checks, which correctly recognize platform-wide assignments through IS_PLATFORM_GLOB.
This assumption is not valid for platform-wide glob scopes.
Unlike organization-scoped globs, platform-wide scopes do not contain an organization because they apply to every organization.
Fix
Handle platform-wide grants explicitly before accessing assignment.scope.org:
def_authz_get_orgs_for_user(self, user) ->list[str]:
""" Returns a list of org short names for the user with given role. AuthZ compatibility layer """role=get_authz_role_from_legacy_role(self._role_name)
assignments=authz_api.get_user_role_assignments_filtered(
user_external_key=user.username,
role_external_key=role,
)
# A platform-wide grant (course-v1:*, lib:*) covers every org, not just# the ones with a concrete assignment. Platform-glob scopes have no .org# attribute at all (unlike org-glob/course/library scopes, where it's a# real field that can be None).ifany(assignment.scope.IS_PLATFORM_GLOBforassignmentinassignments):
return [org["short_name"] fororginget_organizations()]
orgs= {
assignment.scope.orgforassignmentinassignmentsifassignment.scope.orgisnotNone
}
returnlist(orgs)
This prevents get_orgs_for_user() / has_org_for_user() from crashing when a user has a platform-wide role while preserving the existing behavior for organization-scoped assignments.
We definitely have these two gaps related to the platform-global scope that need to be addressed. I agree with your suggestion regarding the second gap: a user with a platform-level assignment should have access to all organizations.
Regarding the first gap, do you have any proposals on how we could solve it? Also, please create an issue to address both of these gaps.
Activity
efortish commentedon Aug 3, 2026
Gap:
RoleCachelegacy compatibility layer ignores platform-wide glob scopesSummary
The AuthZ → legacy compatibility layer currently has two gaps for platform-wide glob scopes:
authz_get_all_course_assignments_for_user()does not requestPlatformCourseOverviewGlobData._get_org_and_course_id_from_authz_scope()does not know how to represent a platform-wide scope in the legacy(org, course_id)model.As a result, platform-wide role assignments are invisible to
RoleCacheand can cause legacy access checks to incorrectly deny access.While auditing #38660 for platform-wide glob (
course-v1:*) coverage, I found a related gap in the AuthZ → legacy compatibility layer incommon/djangoapps/student/roles.py.Root Cause
authz_get_all_course_assignments_for_user()(roles.py:184) only requests two scope types:PlatformCourseOverviewGlobDatais therefore never included in the assignments fetched forRoleCache/BulkRoleCache.Even if
PlatformCourseOverviewGlobDatawere included,_get_org_and_course_id_from_authz_scope()(roles.py:163) currently has no branch to handle it. The method only supports:CourseOverviewData→(org, course_id)OrgCourseOverviewGlobData→(org, None)A platform-wide glob does not map cleanly to this
(org, course_id)representation because it applies to all organizations and courses.Impact
This means a user whose only role assignment is a platform-wide glob, such as:
will not have that role represented in the legacy
RoleCache.Consequently, legacy access checks such as:
RoleCache.has_role(role, course_id, org)has_access()CourseRole.has_user()can report that the user does not have the required role, even though the corresponding AuthZ assignment exists.
This is inconsistent with newer AuthZ-native checks, which correctly recognize platform-wide assignments through
IS_PLATFORM_GLOB.What do you think @BryanttV
efortish commentedon Aug 3, 2026
I also found this gap:
RoleBase._authz_get_orgs_for_user()(roles.py:641) readsassignment.scope.orgfor every assignment.However,
PlatformGlobData/PlatformCourseOverviewGlobData(thecourse-v1:*/lib:*platform-wide scopes) do not have an.orgattribute at all.As a result, any user with a platform-wide role causes
get_orgs_for_user()/has_org_for_user()to fail with anAttributeError.The compatibility layer assumes that every AuthZ scope has an
orgattribute:This assumption is not valid for platform-wide glob scopes.
Unlike organization-scoped globs, platform-wide scopes do not contain an organization because they apply to every organization.
Fix
Handle platform-wide grants explicitly before accessing
assignment.scope.org:This prevents
get_orgs_for_user()/has_org_for_user()from crashing when a user has a platform-wide role while preserving the existing behavior for organization-scoped assignments.What do you think @BryanttV ?
BryanttV commentedon Aug 3, 2026
Hi @efortish, thanks for the validation!
We definitely have these two gaps related to the platform-global scope that need to be addressed. I agree with your suggestion regarding the second gap: a user with a platform-level assignment should have access to all organizations.
Regarding the first gap, do you have any proposals on how we could solve it? Also, please create an issue to address both of these gaps.
efortish commentedon Aug 4, 2026
Hello @BryanttV
I created these two issues:
IMO both issues could be attached in one single issue due the relation between them but I decided to split it as you requested.
Please let me know if the issues are correctly flagged out.
BryanttV commentedon Aug 4, 2026
@efortish Let's treat these as separate issues. Thanks for creating them. Could you start working on them?
I'll mark this issue as closed since the platform-level glob scope verification has been completed and the corresponding tasks have been created.