-
Notifications
You must be signed in to change notification settings - Fork 9
docs: define authorization schema discovery #423
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
mariajgrimaldi
wants to merge
8
commits into
MJG/authz-schema/lifecycle
from
MJG/authz-schema/discovery
Open
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
4550ac1
docs: define authorization schema discovery
mariajgrimaldi 9610624
docs: render decision section numbers
mariajgrimaldi c47377d
docs: clarify authorization schema discovery
mariajgrimaldi 61e46f6
docs: clarify schema entry point discovery
mariajgrimaldi 2d5e92c
docs: explain schema entry point discovery
mariajgrimaldi e6d8c9d
docs: add schema entry point example
mariajgrimaldi 0802a83
docs: document application and Tutor schema discovery
mariajgrimaldi b3626aa
docs: clarify schema discovery failures
mariajgrimaldi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,108 @@ | ||
| 0019: Discover and Load Authorization Schemas During Deployment | ||
| ############################################################### | ||
|
|
||
| Status | ||
| ****** | ||
|
|
||
| **Draft** | ||
|
|
||
| Context | ||
| ******* | ||
|
|
||
| Applications, such as Django apps or IDAs, need a standard way to provide their static authz schema files. Because Open edX supports several deployment methods, discovery must work with Tutor, native deployments and local development. | ||
|
|
||
| Decision | ||
| ******** | ||
|
|
||
| 1. Python entry point and package resources | ||
| =========================================== | ||
|
|
||
| Applications can register schema resources through a Python entry point defined by ``openedx-authz``, following the pattern used to register LMS and CMS Django apps. For example, the ``course_authoring`` package can add an ``authz.schema`` entry point in ``setup.py``: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| entry_points={ | ||
| "authz.schema": [ | ||
| "course_authoring = course_authoring.authz:get_schema_resources", | ||
| ], | ||
| } | ||
|
|
||
| The registered function returns the package resources that contain its schema: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| ... | ||
| def get_schema_resources(): | ||
| return ["authz/course_authoring.authz.yaml"] | ||
|
|
||
| The compiler loads the ``authz.schema`` entry-point group, calls each registered function, and uses ``importlib.resources`` or a similar mechanism to find the files. It then validates the schemas, compiles them into Casbin rows, and applies them to the database. | ||
|
|
||
| If a registered function raises an exception, discovery stops and reports which application failed. This prevents deployment from continuing with an incomplete set of static definitions. | ||
|
|
||
| Site operators can contribute a schema through the ``openedx-authz-schema`` Tutor patch: | ||
|
|
||
| .. code-block:: yaml | ||
|
|
||
| name: openedx-authz-overrides | ||
| version: 0.1.0 | ||
|
|
||
| patches: | ||
| openedx-authz-schema: | | ||
| schema_version: "1.0" | ||
| priority: 200 | ||
|
|
||
| role_extensions: | ||
| - role: course_editor | ||
| add_permissions: | ||
| - courses.export_course | ||
|
|
||
| The compiler combines schemas from application entry points and Tutor patches in a defined order because discovery order may vary. | ||
|
|
||
| 2. Static source information | ||
| ============================ | ||
|
|
||
| For every contribution, the compiler records: | ||
|
|
||
| * the installed distribution name and version; | ||
| * the Python module that owns the resource; | ||
| * the resource path inside that module; and | ||
| * the schema version and content digest. | ||
|
|
||
| Together, these values identify the same source across deployment layouts. The loader reads them from the package and uses them as the source record. | ||
|
|
||
| The compiler records this information for each definition and role-permission assignment. For example, ``openedx-authz:openedx_authz/definitions/core.authz.yaml`` may assign ``courses.view_course`` to ``course_admin``, while ``course-authoring:course_authoring/authz/course_authoring.authz.yaml`` assigns ``courses.edit_schedule`` to the same role. Because both resources contributed to the compiled role, it keeps both source records. | ||
|
|
||
| 3. Deployment command | ||
| ===================== | ||
|
|
||
| ``openedx-authz`` exposes one non-interactive command that discovers, validates, compiles, reports, and applies the static schema. For CI and local development, the same command can accept explicit resources or directories. | ||
|
|
||
| Tutor calls the command via for example a plugin initialization task, while other deployment systems call it before their application processes begin serving traffic. Each integration chooses the appropriate hook, but all of them use the same compiler. | ||
|
|
||
| 4. Removed applications | ||
| ======================= | ||
|
|
||
| When an application is disabled or removed, the next deployment removes the static definitions that came only from that application. If users are assigned to one of its roles, deployment stops and reports those assignments so that an operator can remove them or move the users to another role. Shared definitions remain available when another application still provides them. | ||
|
|
||
| Deployment also stops if a remaining schema refers to a role, permission, or category that would be removed with the application. An operator may allow the removal through explicit deployment configuration. Without that configuration, the stored definitions remain unchanged. | ||
|
|
||
| Consequences | ||
| ************ | ||
|
|
||
| * An application can ship authorization definitions with its code. | ||
| * Tutor and other deployment systems use the same mechanism to discover and load the definitions. | ||
| * Source information remains consistent across containers. | ||
| * Authorization changes after the deployment command runs successfully. | ||
| * Packaging checks must verify that schema resources are included in wheels and source distributions. | ||
| * Deployment integrations need to pass database settings and run the command at a point where all contributing packages are installed. | ||
|
|
||
| References | ||
| ********** | ||
|
|
||
| * `ADR 0018`_ | ||
| * `Tutor plugin development`_ | ||
| * `Tutor plugin template`_ | ||
|
|
||
| .. _ADR 0018: 0018-authorization-schema-lifecycle.rst | ||
| .. _Tutor plugin development: https://docs.tutor.edly.io/plugins/v0/gettingstarted.html | ||
| .. _Tutor plugin template: https://github.com/overhangio/cookiecutter-tutor-plugin/blob/master/%7B%7B%20cookiecutter.package_name%20%7D%7D/%7B%7B%20cookiecutter.module_name%20%7D%7D/plugin.py | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing I think we need to define:
What happens if, for example, we add "app-b" and "app-c" to a site, where app-c extends app-b roles. But then at a later time, app-b get's removed. What happens with this dependency?
My first thought is that this should also stop the deployment and error out a missing dependency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for raising this!
Yes! I also think we should offer these alternatives: 1. error by default 2. allow for removal only if configured (as we defined for role_extensions in a previous ADR)