diff --git a/README.rst b/README.rst index 0eadf6910..ebab83314 100644 --- a/README.rst +++ b/README.rst @@ -1,20 +1,38 @@ -edX Credentials Service |Codecov|_ -==================================== +============================ +Open edX Credentials Service +============================ -.. |Codecov| image:: http://codecov.io/github/edx/credentials/coverage.svg?branch=master -.. _Codecov: http://codecov.io/github/edx/credentials?branch=master +| |status-badge| |license-badge| |CI| |Codecov| -This repository contains the edX Credentials Service, which supports course and program certificates. This service is a -replacement for the ``certificates`` app in ``edx-platform``. +.. |CI| image:: https://github.com/openedx/credentials/actions/workflows/ci.yml/badge.svg + :target: https://github.com/openedx/credentials/actions?query=workflow%3ACI + :alt: Test suite status -Credentials can be run as part of devstack_ or Tutor_ (using the tutor_credentials_ plugin). +.. |Codecov| image:: https://codecov.io/github/openedx/credentials/coverage.svg?branch=master + :target: https://codecov.io/github/openedx/credentials?branch=master + :alt: Code coverage -.. _devstack: https://github.com/openedx/devstack +.. |status-badge| image:: https://img.shields.io/badge/Status-Maintained-brightgreen + :alt: Maintained + +.. |license-badge| image:: https://img.shields.io/github/license/openedx/credentials.svg + :target: https://github.com/openedx/credentials/blob/master/LICENSE + :alt: License + +Purpose +======= + +This repository contains the Open edX Credentials Service, which supports course and program certificates. +This service is an extension to `openedx-platform`_ providing a set of unique features in the credentials domain such as Badges, Verifiable Credentials, Learning Records, and Program Certificates. + +The easiest way to run Credentials service is by using Tutor_, the community-supported, Docker-based Open edX distribution, by installing the tutor_credentials_ plugin. + +.. _openedx-platform: https://github.com/openedx/openedx-platform/tree/master .. _tutor: https://docs.tutor.edly.io/ .. _tutor_credentials: https://github.com/overhangio/tutor-credentials Where to run `make` commands --------------------------- +---------------------------- Due to the nature of developing in containers, some commands must be ran inside the container. Currently most commands can be ran either inside the container or inside a local virtual environement, once developer requirements have been @@ -102,3 +120,4 @@ Our real-time conversations are on Slack_. .. _`discussion forums`: https://discuss.openedx.org .. _Slack: http://openedx.slack.com/ + diff --git a/docs/_diagrams/sharing/badges_processing.mmd b/docs/_diagrams/sharing/badges_processing.mmd new file mode 100644 index 000000000..4ab6c103a --- /dev/null +++ b/docs/_diagrams/sharing/badges_processing.mmd @@ -0,0 +1,27 @@ +flowchart TD + A[Incoming event] --> B{Event type configured for badges?} + B -- No --> Z1[Ignore event] + B -- Yes --> C{UserData present?} + C -- No --> Z2[Drop event] + C -- Yes --> D[Find or create learner in Credentials] + + D --> E[Find active badge requirements for this event type] + E --> F{Requirement rules match event payload?} + F -- No --> Z3[Skip requirement] + F -- Yes --> G[Create or update Badge Progress] + G --> H[Mark requirement fulfilled] + + H --> I{Are all requirements fulfilled?} + I -- No --> Z4[Wait for more matching events] + I -- Yes --> J[Create internal badge record] + J --> K[Emit badge awarded signal] + K --> L[Issue badge through provider API] + L --> M[Update external badge identifier and state] + + D --> P[Find active penalties for this event type] + P --> Q{Penalty rules match event payload?} + Q -- No --> Z5[No penalty action] + Q -- Yes --> R[Reset linked requirement progress] + R --> S[Update internal badge state] + S --> T[Update provider badge state] + T --> U[Credly: revoked
Accredible: expired] diff --git a/docs/_diagrams/sharing/credential_sharing.dsl b/docs/_diagrams/sharing/credential_sharing.dsl new file mode 100644 index 000000000..dff19f534 --- /dev/null +++ b/docs/_diagrams/sharing/credential_sharing.dsl @@ -0,0 +1,117 @@ +/* + * C4 model for the Credential Sharing feature in Open edX. + * Covers Digital Badges and Verifiable Credentials. + * + * Written in Structurizr DSL (https://structurizr.org/). + */ +workspace "Credential Sharing" { + + model { + siteAdmin = person "Site Admin" "Configures badge templates and VC issuing" + learner = person "Learner" "Earns credentials through learning activities" + verifier = person "Verifier" "Employer or institution that verifies learner credentials" + + digitalWallet = softwareSystem "Digital Wallet" "Learner Credential Wallet or compatible storage" + digitalBadgePlatform = softwareSystem "Digital Badge Platform" "Credly, Accredible" "Existing System" + + openedX = softwareSystem "Open edX" { + openedxPlatform = container "Open edX Platform" "LMS and course management" "Python/Django" + eventBus = container "Event Bus" "Redis Streams or Kafka" "" "Queue" + credentialsService = container "Open edX Credentials" "Stores learner achievements, issues credentials" "Python/Django" { + credentialsCore = component "Credentials Core" "Manages course and program certificates" "Django" + digitalBadgesIssuer = component "Digital Badges Issuer" "Processes badge requirements, issues badges to external platforms" "Django" + verifiableCredentialsIssuer = component "Verifiable Credentials Issuer" "Issues W3C Verifiable Credentials, signs with didkit (Ed25519)" "Django" + vcIssuerMFE = component "Learner Record MFE" "UI for learners to request verifiable credentials" "React" + } + credentialsDB = container "MySQL" "Credentials database" "" "Database" + } + + # --- Actors --- + + siteAdmin -> credentialsCore "Configures badge templates and VC settings" "Admin panel" + learner -> openedxPlatform "Completes courses and assignments" + learner -> vcIssuerMFE "Requests verifiable credential" + + # --- Event Bus flows --- + + # LMS produces events consumed by Credentials + openedxPlatform -> eventBus "Publishes certificate and course passing status events" "openedx-events" + eventBus -> credentialsCore "Delivers certificate and course grades events" "openedx-events" + eventBus -> digitalBadgesIssuer "Delivers badge-related events" "learning-badges-lifecycle topic" + + # Credentials produces events back to the bus + digitalBadgesIssuer -> eventBus "Publishes badges lifecycle events" "openedx-events" + + # --- Internal flows --- + + credentialsCore -> credentialsDB "Uses" "Django ORM" + digitalBadgesIssuer -> credentialsDB "Uses" "Django ORM" + verifiableCredentialsIssuer -> credentialsDB "Uses" "Django ORM" + + # --- External integrations --- + + # Badges + digitalBadgesIssuer -> digitalBadgePlatform "Issues and revokes badges" "REST API" + + # Verifiable Credentials + vcIssuerMFE -> verifiableCredentialsIssuer "Initiates VC issuance" + verifiableCredentialsIssuer -> digitalWallet "Sends signed verifiable credential" + digitalWallet -> verifiableCredentialsIssuer "Sends issuance request" "HTTP" + + # Verification + verifier -> verifiableCredentialsIssuer "Checks credential revocation status" "StatusList2021 API" + verifier -> digitalBadgePlatform "Checks badge revocation status" "" + + } + + views { + systemContext openedX "SystemContext" "High-level view of Credential Sharing" { + include * + autoLayout lr + } + + container openedX "Containers" "Open edX containers involved in credential sharing" { + include * + autoLayout lr + } + + component credentialsService "Components" "Credentials service internal components" { + include * + autoLayout lr + } + + styles { + element "Person" { + color "#ffffff" + background "#0b3d91" + fontSize 22 + shape Person + } + element "Software System" { + background "#005a9c" + color "#ffffff" + } + element "Existing System" { + background "#4a4a4a" + color "#ffffff" + } + element "Container" { + background "#2b7bbb" + color "#ffffff" + } + element "Component" { + background "#dbeafe" + color "#111111" + } + element "Database" { + shape Cylinder + } + element "Queue" { + shape Pipe + } + } + } + configuration { + scope softwaresystem + } +} diff --git a/docs/_static/images/badges/badges-admin-accredible-api-config.png b/docs/_static/images/badges/badges-admin-accredible-api-config.png new file mode 100644 index 000000000..765a5b241 Binary files /dev/null and b/docs/_static/images/badges/badges-admin-accredible-api-config.png differ diff --git a/docs/_static/images/badges/badges-admin-activation.png b/docs/_static/images/badges/badges-admin-activation.png new file mode 100644 index 000000000..f14863d35 Binary files /dev/null and b/docs/_static/images/badges/badges-admin-activation.png differ diff --git a/docs/_static/images/badges/badges-admin-credly-organization.png b/docs/_static/images/badges/badges-admin-credly-organization.png new file mode 100644 index 000000000..25f5ddf98 Binary files /dev/null and b/docs/_static/images/badges/badges-admin-credly-organization.png differ diff --git a/docs/_static/images/badges/badges-admin-template-details.png b/docs/_static/images/badges/badges-admin-template-details.png index ff222b48d..0a004bfd3 100644 Binary files a/docs/_static/images/badges/badges-admin-template-details.png and b/docs/_static/images/badges/badges-admin-template-details.png differ diff --git a/docs/_static/images/badges/badges-processing-flow.png b/docs/_static/images/badges/badges-processing-flow.png new file mode 100644 index 000000000..399d68c9b Binary files /dev/null and b/docs/_static/images/badges/badges-processing-flow.png differ diff --git a/docs/_static/images/sharing/credential_sharing_components.png b/docs/_static/images/sharing/credential_sharing_components.png new file mode 100644 index 000000000..b776de912 Binary files /dev/null and b/docs/_static/images/sharing/credential_sharing_components.png differ diff --git a/docs/_static/images/sharing/credential_sharing_containers.png b/docs/_static/images/sharing/credential_sharing_containers.png new file mode 100644 index 000000000..0011b3ed0 Binary files /dev/null and b/docs/_static/images/sharing/credential_sharing_containers.png differ diff --git a/docs/_static/images/sharing/credential_sharing_system_context.png b/docs/_static/images/sharing/credential_sharing_system_context.png new file mode 100644 index 000000000..f612d3ad0 Binary files /dev/null and b/docs/_static/images/sharing/credential_sharing_system_context.png differ diff --git a/docs/_static/images/sharing/vc_lifecycle.png b/docs/_static/images/sharing/vc_lifecycle.png new file mode 100644 index 000000000..85059f473 Binary files /dev/null and b/docs/_static/images/sharing/vc_lifecycle.png differ diff --git a/docs/_static/images/verifiable_credentials-issuance-lines.png b/docs/_static/images/verifiable_credentials-issuance-lines.png index 6b71c0b70..96c506bd8 100644 Binary files a/docs/_static/images/verifiable_credentials-issuance-lines.png and b/docs/_static/images/verifiable_credentials-issuance-lines.png differ diff --git a/docs/badges/configuration/accredible.rst b/docs/badges/configuration/accredible.rst deleted file mode 100644 index 3efbdbe62..000000000 --- a/docs/badges/configuration/accredible.rst +++ /dev/null @@ -1,172 +0,0 @@ -Accredible Configuration -======================== - -.. note:: - - This section provides information on how and where to set up accredible badge groups and configuration. - -The Badges feature is configured in the Credentials admin panel. - -.. image:: ../../_static/images/badges/badges-admin.png - :alt: Badges administration - -Accredible API Configurations ------------------------------ - -Multiple Accredible API Configurations can be configured. - -**All communication between Open edX Credentials and Accredible service happens on behalf of a Accredible API config.** - -Go to the Accredible API Configs section in the admin panel and create a new item: - -1. to set the name for config; -2. to set the api key, used to sync the Accredible account. - -In case of errors, check the credentials used for the API Config - -Groups ---------------- - -*Accredible groups* (badge templates for short) are created in the Accredible dashboard and then, they are retrieved by the Credentials via API. - -Synchronization -~~~~~~~~~~~~~~~ - -To synchronize Accredible groups for the API Configuration one should: - -- navigate "Accredible API Configs" list page; -- select the API Config; -- use ``Sync groups`` action; - -.. image:: ../../_static/images/badges/badges-admin-groups-sync.png - :alt: Accredible groups synchronization - -On success, the system will update the list of Accredible groups: - -- Accredible group records are created inactive (disabled); - -For a group to be considered during the processing it must be configured (to have at least 1 requirement) and activated (enabled) first. - -Badge Requirements ------------------- - - Requirements describe **what** and **how** must happen on the system to earn a badge. - -Badge Requirement(s) specification is a crucial part of group configuration. -At least one badge requirement must be associated with a group. - -Badge Requirements are listed inline on a group detail page. - -.. image:: ../../_static/images/badges/badges-admin-template-requirements.png - :alt: Credly badge template requirements - -A badge template can have multiple requirements. All badge requirements must be *fulfilled* before the system will issue a badge to a learner. - -Event type -~~~~~~~~~~ - - Describes **what is expected to happen**. - -Available event type subset is pre-configured in the application settings. - -.. note:: - - Technically, any public signal from the `openedx-events`_ library can be used for badge template requirements setup, if it includes user PII (UserData), so users can be identified. - -Rules -~~~~~ - -A list of configured data rules (if any), see "Data Rules". - -Description -~~~~~~~~~~~ - -**Description** is an optional human-readable reminder that describes what the requirement is about. - - Badge Requirement can be **deeper specified** via its Data Rules. - -Group -~~~~~ - -Optional configuration (by default each badge requirement is assigned a separate Group). - -Allows putting 2 or more badge requirements as a Group. -Requirements group is fulfilled if any of its requirements is fulfilled. - - "OR" logic is applied inside a Group. - -.. image:: ../../_static/images/badges/badges-admin-rules-group.png - :alt: Badge requirement rules group - -See :ref:`Configuration examples for Badging`. - -Data Rules ----------- - - Describes **how it is expected to happen** - -Data Rules detail their parent Badge Requirement based on the expected event payload. - -To edit/update a Data Rule: - -- navigate to the Badge Requirement detail page (use ``Change`` inline link); -- find the "Data Rules" section and add a new item; - -.. image:: ../../_static/images/badges/badges-admin-requirement-rules.png - :alt: Badge requirement rules edit - -**Each data rule describes a single expected payload value:** - -All key paths are generated based on the event type specified for the parent Badge Requirement. - -.. image:: ../../_static/images/badges/badges-admin-data-rules.png - :alt: Badge requirement data rules - -1. **Key path** - payload path to the target attribute - - dot-separated string; - - each event type has its unique pre-defined set of key paths; -2. **Operator** - comparison operation to apply between expected and actual values; - - available operators: (payload) - - ``"="`` (equals); - - ``"!="`` (not equals); -3. **Expected value** - an expected value for the target attribute - - payload boolean positive values allowed: ``"true", "True", "yes", "Yes", "+"``; - - payload boolean negative values allowed: ``"false", "False", "no", "No", "-"``; - - -Please, see :ref:`Configuration examples for Badging` for clarity. - -Badge Penalties ---------------- - - Penalties allow badge progress resetting based on user activity. - -Badge penalties are optional. -There could be 0 or more badge penalties configured for a badge template. - -Each badge penalty is *targeted* to 1 or more badge requirements. -A penalty setup is similar to a badge requirement, but has different effect: it decreases badge progress for a user. - -When all penalty rules have been applied, a learner's progress towards a badge is reset. - -.. image:: ../../_static/images/badges/badges-admin-penalty-rules.png - :alt: Badge penalty rules edit - -Activation ----------- - -Configured group can be activated: - -- navigate to the group detail page; -- check ``Is active`` checkbox; - - Activated groups starts "working" immediately. - -Accredible group record includes: - -1. Core credential attributes; -2. Badge template credential attributes; -3. Accredible service attributes (dashboard link); -4. Configured requirements; - -.. _openedx-events: https://github.com/openedx/openedx-events \ No newline at end of file diff --git a/docs/badges/configuration/credly.rst b/docs/badges/configuration/credly.rst deleted file mode 100644 index 15aaeb82f..000000000 --- a/docs/badges/configuration/credly.rst +++ /dev/null @@ -1,194 +0,0 @@ -Credly Configuration -==================== - -.. note:: - - This section provides information on how and where to set up badge templates and organizations. - -The Badges feature is configured in the Credentials admin panel. - -.. image:: ../../_static/images/badges/badges-admin.png - :alt: Badges administration - -Credly Organizations --------------------- - -Multiple Credly Organizations can be configured. - -**All communication between Open edX Credentials and Credly service happens on behalf of a Credly Organization.** - -Go to the Credly Organization section in the admin panel and create a new item: - -1. to set the UUID use your Credly Organization identifier; -2. to set the authorization token, used to sync the Credly Organization. - -Check: the system pulls the Organization's details and updates its name. - -In case of errors, check the credentials used for the Organization - -Badge templates ---------------- - -*Credly badge templates* (badge templates for short) are created in the Credly Organization's dashboard and then, if published, they are retrieved by the Credentials via API. - -Webhooks -~~~~~~~~~~~~~~~ - -.. note:: - - Webhooks is a connection with Credly and external platform that allows your server to be notified about events occuring within Credly. - -Webhooks are set up on Credly management dashboard as Credly is a main initiator of the syncronization. - -You should be able to select an action from the list so that whenever the specified action occurs internally, the external system is alerted. - -Without this synchronization, the external system will not be notified of any significant changes (e.g. a badge template update, or a badge template has been archived) and may incorrectly issue erroneous or outdated badges. - -Synchronization -~~~~~~~~~~~~~~~ - -To synchronize Credly badge templates for the Organization one should: - -- navigate "Credly badge templates" list page; -- select the Organization; -- use ``Sync organization badge templates`` action; - -.. image:: ../../_static/images/badges/badges-admin-credly-templates-sync.png - :alt: Credly badge templates synchronization - -On success, the system will update the list of Credly badge templates for the Organization: - -- only badge templates with ``active`` state are pulled; -- Credly badge template records are created inactive (disabled); - -.. image:: ../../_static/images/badges/badges-admin-credly-templates-list.png - :alt: Credly badge templates list - -For a badge template to be considered during the processing it must be configured (to have at least 1 requirement) and activated (enabled) first. - -Badge Requirements ------------------- - - Requirements describe **what** and **how** must happen on the system to earn a badge. - -Badge Requirement(s) specification is a crucial part of badge template configuration. -At least one badge requirement must be associated with a badge template. - -Badge Requirements are listed inline on a badge template detail page. - -.. image:: ../../_static/images/badges/badges-admin-template-requirements.png - :alt: Credly badge template requirements - -A badge template can have multiple requirements. All badge requirements must be *fulfilled* before the system will issue a badge to a learner. - -Event type -~~~~~~~~~~ - - Describes **what is expected to happen**. - -Available event type subset is pre-configured in the application settings. - -.. note:: - - Technically, any public signal from the `openedx-events`_ library can be used for badge template requirements setup, if it includes user PII (UserData), so users can be identified. - -Rules -~~~~~ - -A list of configured data rules (if any), see "Data Rules". - -Description -~~~~~~~~~~~ - -**Description** is an optional human-readable reminder that describes what the requirement is about. - - Badge Requirement can be **deeper specified** via its Data Rules. - -Group -~~~~~ - -Optional configuration (by default each badge requirement is assigned a separate Group). - -Allows putting 2 or more badge requirements as a Group. -Requirements group is fulfilled if any of its requirements is fulfilled. - - "OR" logic is applied inside a Group. - -.. image:: ../../_static/images/badges/badges-admin-rules-group.png - :alt: Badge requirement rules group - -See :ref:`Configuration examples for Badging`. - -Data Rules ----------- - - Describes **how it is expected to happen** - -Data Rules detail their parent Badge Requirement based on the expected event payload. - -To edit/update a Data Rule: - -- navigate to the Badge Requirement detail page (use ``Change`` inline link); -- find the "Data Rules" section and add a new item; - -.. image:: ../../_static/images/badges/badges-admin-requirement-rules.png - :alt: Badge requirement rules edit - -**Each data rule describes a single expected payload value:** - -All key paths are generated based on the event type specified for the parent Badge Requirement. - -.. image:: ../../_static/images/badges/badges-admin-data-rules.png - :alt: Badge requirement data rules - -1. **Key path** - payload path to the target attribute - - dot-separated string; - - each event type has its unique pre-defined set of key paths; -2. **Operator** - comparison operation to apply between expected and actual values; - - available operators: (payload) - - ``"="`` (equals); - - ``"!="`` (not equals); -3. **Expected value** - an expected value for the target attribute - - payload boolean positive values allowed: ``"true", "True", "yes", "Yes", "+"``; - - payload boolean negative values allowed: ``"false", "False", "no", "No", "-"``; - - -Please, see :ref:`Configuration examples for Badging` for clarity. - -Badge Penalties ---------------- - - Penalties allow badge progress resetting based on user activity. - -Badge penalties are optional. -There could be 0 or more badge penalties configured for a badge template. - -Each badge penalty is *targeted* to 1 or more badge requirements. -A penalty setup is similar to a badge requirement, but has different effect: it decreases badge progress for a user. - -When all penalty rules have been applied, a learner's progress towards a badge is reset. - -.. image:: ../../_static/images/badges/badges-admin-penalty-rules.png - :alt: Badge penalty rules edit - -Activation ----------- - -Configured badge template can be activated: - -- navigate to the badge template detail page; -- check ``Is active`` checkbox; - - Activated badge template starts "working" immediately. - -.. image:: ../../_static/images/badges/badges-admin-template-details.png - :alt: Badge template data structure - -Credly badge template record includes: - -1. Core credential attributes; -2. Badge template credential attributes; -3. Credly service attributes (state, dashboard link); -4. Configured requirements; - -.. _openedx-events: https://github.com/openedx/openedx-events \ No newline at end of file diff --git a/docs/badges/configuration/index.rst b/docs/badges/configuration/index.rst deleted file mode 100644 index 6fed4f3ec..000000000 --- a/docs/badges/configuration/index.rst +++ /dev/null @@ -1,10 +0,0 @@ -Badging Configuration -====================== - -.. toctree:: - :maxdepth: 1 - - credly - accredible - -.. _Credly (by Pearson): https://info.credly.com/ \ No newline at end of file diff --git a/docs/badges/examples.rst b/docs/badges/examples.rst deleted file mode 100644 index 9be07a535..000000000 --- a/docs/badges/examples.rst +++ /dev/null @@ -1,259 +0,0 @@ -.. _Configuration examples for Badging: - -Configuration examples for Badging -=================================== - -These examples will show how to configure requirements and ``data rules`` for necessary use cases. - -.. note:: - - Any of the following examples can be combined for more specific use cases. - - -Implemented use cases ----------------------- - - -1. ANY COURSE GRADE update -~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Not that useful. Any interaction (e.g. submit button click) with gradable block in any course leads to a badge. - -1. **Requirement 1**: - a. event type: ``org.openedx.learning.course.passing.status.updated.v1`` - b. description: ``On any grade update.`` - - -2. ANY COURSE completion -~~~~~~~~~~~~~~~~~~~~~~~~ - - Requires **passing grade** for any course. Once course'd grade becomes "passing" after gradable problem submission, - a badge is awarded. - -1. **Requirement 1**: - a. event type: ``org.openedx.learning.course.passing.status.updated.v1`` - b. description: ``On any (not CCX) course completion.`` - c. **Data rule 1**: - i. key path: ``is_passing`` - ii. operator: ``equals`` - iii. value: ``true`` - - -3. ANY CCX course completion -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Requires **passing grade** for any CCX course. - -1. **Requirement 1**: - a. event type: ``org.openedx.learning.ccx.course.passing.status.updated.v1`` - b. description: ``On any CCX course completion.`` - c. **Data rule 1**: - i. key path: ``is_passing`` - ii. operator: ``equals`` - iii. value: ``true`` - - -4. ANY COURSE completion EXCEPT a specific course -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Requires **passing grade** for any course **excluding** the "Demo" course. - -1. **Requirement 1**: - a. event type: ``org.openedx.learning.course.passing.status.updated.v1`` - b. description: ``On any course completion, but not the "Demo" course.`` - c. **Data rule 1**: - i. key path: ``is_passing`` - ii. operator: ``equals`` - iii. value: ``true`` - d. **Data rule 2**: - i. key path: ``course.course_key`` - ii. operator: ``not equals`` - iii. value: ``course-v1:edX+DemoX+Demo_Course`` - - -5. SPECIFIC COURSE completion -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Requires **passing grade** for exact course ("Demo" course). - -1. **Requirement 1**: - a. event type: ``org.openedx.learning.course.passing.status.updated.v1`` - b. description: ``On the Demo course completion.`` - c. **Data rule 1**: - i. key path: ``is_passing`` - ii. operator: ``equals`` - iii. value: ``true`` - d. **Data rule 2**: - i. key path: ``course.course_key`` - ii. operator: ``equals`` - iii. value: ``course-v1:edX+DemoX+Demo_Course`` - - -6. MULTIPLE SPECIFIC COURSES completion -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - **All** specified courses must be completed. - Different requirement groups force each requirement to be fulfilled. - -1. **Requirement 1**: - a. event type: ``org.openedx.learning.course.passing.status.updated.v1`` - b. description: ``On the "Demo" course completion.`` - c. group: ``A`` - d. **Data rule 1**: - i. key path: ``is_passing`` - ii. operator: ``equals`` - iii. value: ``true`` - e. **Data rule 2**: - i. key path: ``course.course_key`` - ii. operator: ``equals`` - iii. value: ``course-v1:edX+DemoX+Demo_Course`` - -2. **Requirement 2**: - a. event type: ``org.openedx.learning.course.passing.status.updated.v1`` - b. description: ``On the "Other" course completion.`` - c. group: ``B`` - d. **Data rule 1**: - i. key path: ``is_passing`` - ii. operator: ``equals`` - iii. value: ``true`` - e. **Data rule 2**: - i. key path: ``course.course_key`` - ii. operator: ``equals`` - iii. value: ``course-v1:edX+DemoX+OTHER_Course`` - - -7. SPECIFIC CCX course completion -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Requires **passing grade** for exact CCX course ("Demo CCX1" course). - -1. **Requirement 1**: - a. event type: ``org.openedx.learning.ccx.course.passing.status.updated.v1`` - b. description: ``On the Demo CCX1 course completion.`` - c. **Data rule 1**: - i. key path: ``is_passing`` - ii. operator: ``equals`` - iii. value: ``true`` - d. **Data rule 2**: - i. key path: ``course.ccx_course_key`` - ii. operator: ``equals`` - iii. value: ``ccx-v1:edX+DemoX+Demo_Course+ccx@1`` - -8. ANY CCX course completion ON a SPECIFIC MASTER course -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Requires **passing grade** for any "child" CCX course that based on the master "Demo" course. - -1. **Requirement 1**: - a. event type: ``org.openedx.learning.ccx.course.passing.status.updated.v1`` - b. description: ``On any Demo CCX course completion.`` - c. **Data rule 1**: - i. key path: ``is_passing`` - ii. operator: ``equals`` - iii. value: ``true`` - d. **Data rule 2**: - i. key path: ``course.master_course_key`` - ii. operator: ``equals`` - iii. value: ``course-v1:edX+DemoX+Demo_Course`` - -9. ANY CCX course completion ON a SPECIFIC MASTER course EXCEPT a SPECIFIC CCX course -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Complicated. - Requires **passing grade** for **any "child" CCX course** that based on the master "Demo" course, **excluding** the "Demo CCX2" course. - -1. **Requirement 1**: - a. event type: ``org.openedx.learning.ccx.course.passing.status.updated.v1`` - b. description: ``On any Demo CCX course completion.`` - c. **Data rule 1**: - i. key path: ``is_passing`` - ii. operator: ``equals`` - iii. value: ``true`` - d. **Data rule 2**: - i. key path: ``course.master_course_key`` - ii. operator: ``equals`` - iii. value: ``course-v1:edX+DemoX+Demo_Course`` - e. **Data rule 3**: - i. key path: ``course.ccx_course_key`` - ii. operator: ``not equals`` - iii. value: ``ccx-v1:edX+DemoX+Demo_Course+ccx@2`` - -10. ONE OF MULTIPLE SPECIFIC COURSES completion -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - At least a single from the specified courses must be completed. - Grouped requirements are processed as **"ANY FROM A GROUP"**. - -1. **Requirement 1**: - a. event type: ``org.openedx.learning.course.passing.status.updated.v1`` - b. description: ``On the "Demo" course completion.`` - c. group: ``A`` - d. **Data rule 1**: - i. key path: ``is_passing`` - ii. operator: ``equals`` - iii. value: ``true`` - e. **Data rule 2**: - i. key path: ``course.course_key`` - ii. operator: ``equals`` - iii. value: ``course-v1:edX+DemoX+Demo_Course`` - -2. **Requirement 2**: - a. event type: ``org.openedx.learning.course.passing.status.updated.v1`` - b. description: ``On the "Other" course completion.`` - c. group: ``A`` - d. **Data rule 1**: - i. key path: ``is_passing`` - ii. operator: ``equals`` - iii. value: ``true`` - e. **Data rule 2**: - i. key path: ``course.course_key`` - ii. operator: ``equals`` - iii. value: ``course-v1:edX+DemoX+OTHER_Course`` - - -11. SPECIFIC MASTER course OR ANY of its CCX courses EXCEPT a SPECIFIC CCX course completion -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Here requirements 1 and 2 are grouped, so any of them lead to a badge. - -1. **Requirement 1**: - a. event type: ``org.openedx.learning.course.passing.status.updated.v1`` - b. description: ``On the "Demo" course completion OR...`` - c. group: ``A`` - d. **Data rule 1**: - i. key path: ``is_passing`` - ii. operator: ``equals`` - iii. value: ``true`` - e. **Data rule 2**: - i. key path: ``course.course_key`` - ii. operator: ``equals`` - iii. value: ``course-v1:edX+DemoX+Demo_Course`` - -2. **Requirement 2**: - a. event type: ``org.openedx.learning.ccx.course.passing.status.updated.v1`` - b. description: ``...OR any Demo CCX courses completion EXCLUDING CCX3.`` - c. group: ``A`` - d. **Data rule 1**: - i. key path: ``is_passing`` - ii. operator: ``equals`` - iii. value: ``true`` - e. **Data rule 2**: - i. key path: ``course.master_course_key`` - ii. operator: ``equals`` - iii. value: ``course-v1:edX+DemoX+Demo_Course`` - f. **Data rule 3**: - i. key path: ``course.ccx_course_key`` - ii. operator: ``not equals`` - iii. value: ``ccx-v1:edX+DemoX+Demo_Course+ccx@3`` - ------ - -Future work ------------ - -1. Events set extension (e.g. "Email activation", "Profile data completion", "Course section completion", ...); -2. Repetitive events (e.g. "5 arbitrary courses completion"); -3. Prerequisite events (e.g. "5 specific courses completion in a specified order"); -4. Time-ranged event (e.g. "Arbitrary course completion during the February 2022"); -5. Badge dependencies (e.g. "Badge A + Badge B = Badge C"); -6. Multiple times same badge earning (e.g. "3 arbitrary course completions make badge earned x3"); diff --git a/docs/badges/index.rst b/docs/badges/index.rst deleted file mode 100644 index 0885241d6..000000000 --- a/docs/badges/index.rst +++ /dev/null @@ -1,56 +0,0 @@ -Badges Information -======================= - - The Badges feature allows learners to earn achievements (badges) for their learning activities. - -- **Badge Template** is another kind of **credential**. -- **Badge** is another kind of **user credential**. - -Current Badges version is highly integrated with the `Credly (by Pearson)`_ and `Accredible`_ services, but it is fully prepared to be used separately. - -What is Credly? ---------------- - -**Credly** is a end-to-end solution for creating, issuing, and managing digital Credentials. Organizations use **Credly** to recognize their learners' achievements. -Learners can store badges in their Credly profile to visualize their professional success - which courses were completed and when. - -Badges provide employers and peers concrete evidence of what learners have -accomplished in order to earn their credential and what they are now capable of. -Digital badges are a great way to motivate learning and display a learner's -subsequent achievements. - -Badges are typically finer-grained than a traditional course certificate. They -are meant to introduce game mechanics to have more frequent sources of -motivation than one would get from a cumulative certificate. - -What is Accredible? --------------------- - -**Accredible** allows for the design and issuance of verifiable digital badges and -certificates that showcase acquired skills, earning criteria, and evidence of -learning. Learn more about Accredible on the `Accredible features page`_. - - -Glossary --------- - -1. **Badge template** – a template of a badge (with design, name, and description) that will be used in settings to set up special rules to create a badge for users to receive on the platform. - -2. **Authorization token** – It's a temporary key that verifies identity and authorizes resource access. A token can be computer-generated or hardware-based. A valid token allows a user to retain access to an online service or web application until the token expires. - -3. **UUID** – Universally Unique Identifier – is a value used to identify an object or entity on the internet uniquely. Depending on the specific mechanisms used, a UUID is either guaranteed to be different or is, at least, extremely likely to be different from any other UUID generated. - ----- - -.. toctree:: - :maxdepth: 2 - - quickstart - settings - configuration/index - examples - processing - -.. _Credly (by Pearson): https://info.credly.com/ -.. _Accredible: https://www.accredible.com/ -.. _Accredible features page: https://www.accredible.com/features \ No newline at end of file diff --git a/docs/badges/processing.rst b/docs/badges/processing.rst deleted file mode 100644 index e80dce16c..000000000 --- a/docs/badges/processing.rst +++ /dev/null @@ -1,104 +0,0 @@ -Badges Processing -================== - -Incoming events async processing happens in a separate event bus consumer process(es). -See the Event Bus documentation for details. - - -Events subscription -------------------- - -.. note:: - - Only explicitly configured `event types`_ take part in the processing. - -See Badges `default settings`_ for the default set of supported events. -Though, it is expected that any public signal from the `openedx-events`_ library can extend this set with a single requirement: its payload includes a learner PII (UserData object). - - -Learner identification ----------------------- - -.. note:: - - Each incoming event must be associated with a specific learner. - -The system tries to identify a learner by the `UserData` object in the event payload. -If the learner is not found, the event is ignored. - -The system also ensures that such learner exists in the Credentials (creates if needed). - - -Requirements analysis ---------------------- - -Since any requirement is associated with a single event type, all relevant requirements are collected for the incoming signal: - -1. appropriate event type; -2. active badge templates; - -Each requirement's rules are checked against the event payload. -Requirement processing is dropped as soon as the system recognizes not applying rules. - - -Progress update ---------------- - -Current learners' badge progress is stored in the ``Badge Progress`` record. - -.. note:: - - Since badge templates can have more than one requirement, the system should track intermediate progresses as well. - -Once all rules of the processed requirement apply, the system: - -1. ensures there is the badge progress record for the learner; -2. marks the requirement as fulfilled for the learner; - -.. image:: ../_static/images/badges/badges-admin-progress-records.png - :alt: Badge progress records - -If a Badge Progress is recognized as completed (all requirements for the badge template are fulfilled), the system initiates the awarding process. - - -Badge awarding --------------- - -.. note:: - - Once all requirements for the badge template are fulfilled, the system should award the badge. - -On badge progress completion, the system: - -1. creates an *internal* user credential record for the learner; -2. notifies (public signal) about new badge awarded; -3. tries to issue an *external* Credly badge for the learner; - -.. note:: - - The Badges application implements its extended ``UserCredential`` version (the CredlyBadge) to track external issuing state. Once the Credly badge is successfully issued the **CredlyBadge is updated with its UUID and state**. - -.. _event types: https://docs.openedx.org/projects/openedx-events/en/latest/ -.. _openedx-events: https://github.com/openedx/openedx-events -.. _default settings: settings.html#default-settings - -Badge revocation ----------------- - -Badges can also be revoked. Its a separete set of rules that need to be set up. - -1. Go to Badge Penalties section in admin panel (admin/badges/badge_pentalties). - -.. image:: ../_static/images/badges/badges-admin-penalty-rules.png - :alt: Badge penalties - -2. Select a certain requirement that was previously set up to link penalty - a. To know how to set up badge template requirements, go to the `Configuration`_ section. - -3. Note that all penalties have to be linked to a certain requirement, so that when that requirement is not fulfilled, system would know when to revoke the badge. - -.. _Configuration: configuration.html - -When a learner's badge is revoked by Credly, the Credentials IDA will be notified and will update it's internal records. The status of the badge will change from `awarded` to `revoked` upon successful revocation. - -The badge cannot be reissued once it has been revoked. diff --git a/docs/badges/quickstart.rst b/docs/badges/quickstart.rst deleted file mode 100644 index 011acd0f2..000000000 --- a/docs/badges/quickstart.rst +++ /dev/null @@ -1,183 +0,0 @@ -Badges Operator Quick Start -============================ - -.. note:: - - This section includes brief information about the feature – what to start with; where to set up credentials, etc. - -Currently Open edX supports two badge services: Credly and Accredible. - -0. Prerequisites – service account ----------------------------------- - -To start using this feature a Credly or Accredible account is necessary. - -For Credly: - -1. Register on Credly and create your account. -2. Create Organization in Credly. -3. Create at least 1 badge template and activate it. - - -For Accredible: - -1. Register on Accredible and create your account. -2. Create at least 1 group. - -1. Enable feature ------------------ - -Badges feature is optional and it is disabled by default. So, it must be enabled to be accessible. - -.. code-block:: - - # LMS service: - FEATURES["BADGES_ENABLED"] = True - - # Credentials service: - BADGES_ENABLED = True - -2. Configure integration -------------------------------- - -.. note:: - - For detailed information, go to the `Configuration`_ section. - -Go to the Credentials service admin panel and configure the integration with the service: - -Credly ------- - -1. In the admin panel go to /admin/badges/credly_organization to add Credly Organization. - a. Add UUID (unique identifier) for the Credly organization - b. Add the authorization token of the Credly organization. - -Please note that UUID and authorization token will be given to you during the creation of the Credly Organization on the Credly side - -Check: the system pulls the Organization's data and updates its name. - -Accredible ------------ - -1. Retrieve API Key from Accredible account settings. Go to the Accredible account settings -> Manage API Keys and create a new API Key. -2. In the admin panel go to ``/admin/badges/accredibleapiconfig`` to add Accredible Group. - a. Add API Key - b. Add name for configuration - -.. _Configuration: configuration.html - - -3. Synchronize badge templates ------------------------------- - Note: For detailed information, go to the `Configuration`_ section. - -Credly ------- - -From the “Credly Organizations” list, select the Organization(s) you want to use and select ``Sync organization badge templates`` action. - -The system pulls the list of badge templates from the Credly Organization. Navigate to the “Credly badge templates” list and check newly created templates. - -Accredible ----------- -From the Accredible API Configurations list, select the Configuration(s) you want to use and select ``Sync groups`` action. - -The system pulls the list of groups from the Accredible account. Navigate to the “Accredible groups” list and check newly created groups. - -.. _Configuration: configuration.html - -4. Setup badge requirements ---------------------------- - -.. note:: - - Requirements describe **what** and **how** must happen on the system to earn a badge. - -The crucial part of the badge template configuration is the requirements specification. At least one requirement must be associated with a badge template. - -Go to the first badge template details page (admin/badges/credly_badge_templates or admin/badges/accrediblegroup) and add requirements for it: - -1. find the “Badge Requirements” section; -2. add a new item and select an event type (what is expected to happen); - a. optionally, put a description; -3. save and navigate to the Requirement details (Change link); - a. optionally, specify data rules in the “Data Rules” section (how exactly it is expected to happen); -4. add a new item and describe the rule; -5. select a key path - specific data element; -6. select an operator - how to compare the value; -7. enter a value - expected parameter’s value. - -.. note:: - - A configuration for the badge template that must be issued on a specific course completion looks as following: - - - Requirement 1: - - event type: ``org.openedx.learning.course.passing.status.updated.v1`` - - description: ``On the Demo course completion.`` - - Data rule 1: - - key path: ``course.course_key`` - - operator: ``equals`` - - value: ``course-v1:edX+DemoX+Demo_Course`` - - Data rule 2: - - key path: ``is_passing`` - - operator: ``equals`` - - value: ``true`` - -It is possible to put more than one requirement in a badge template. - -5. Activate configured badge templates --------------------------------------- - - To active a badge template check the ``is active`` checkbox on its edit page. - -Once badge requirements are set up, it should be “enabled” to start “working”. - -Once enabled, the badge template will be active and ready. - -.. warning:: - - Configuration updates for active badge templates are discouraged since they may cause learners’ inconsistent experience. - -6. See users Badge Progress ---------------------------- - -Current badge progress can be seen in the “Badge progress records” section in the Credentials admin panel. - -Since badge templates can have more than one requirement, there can be partially completed badges. - -7. See awarded user credentials -------------------------------- - -Already earned badges are listed in the "Credly badges" or "Accredible badges" section of the admin panel. - -.. note:: - - This badge is an extended version of a user credential record. - -Once badge progress is complete (all requirements were *fulfilled*), the system: - -1. creates internal user credentials (CredlyBadge or AccredibleBadge); -2. notifies about the badge awarding (public signal); -3. requests Credly or Accredible service to issue the badge (API request). - -8. See issued badges ---------------------------- - -Earned internal badges (user credentials) spread to the badge service. - -On a successful badge issuing, the CredlyBadge or AccredibleBadge user credential is updated with its requisites: - -1. external UUID; -2. external state; - -The Credly badge is visible in the Credly service. -The Accredible badge is visible in the Accredible service. - - -9. Badge template withdrawal ----------------------------- - -Badge template can be deactivated by putting it in the inactive state (``is active`` checkbox). - -Inactive badge templates are ignored during the processing. diff --git a/docs/badges/settings.rst b/docs/badges/settings.rst deleted file mode 100644 index 4168279c5..000000000 --- a/docs/badges/settings.rst +++ /dev/null @@ -1,200 +0,0 @@ -Badging Settings -================= - -.. note:: - - You can find technical details on how to set up proper configurations for badges to be active in this section. - -Badges feature settings allow configuration: - -1. feature availability; -2. event bus public signals subset for badges; -3. the Credly service integration details (URLs, sandbox usage, etc.); -4. the Accredible service integration details (URLs, sandbox usage, etc.); - -You can use tutor plugin to setup all needed configurations: - -https://github.com/raccoongang/tutor-contrib-badges - - -Feature switch --------------- - -The Badges feature is under a feature switch (disabled by default). - -To enable the feature, update these settings as follows: - -.. code-block:: python - - # Platform services settings: - FEATURES["BADGES_ENABLED"] = True - - # Credentials service settings: - BADGES_ENABLED = True - - -Default settings ----------------- - -The feature has its configuration: - -.. code-block:: python - - # Credentials settings: - BADGES_CONFIG = { - # these events become available in requirements/penalties setup: - "events": [ - "org.openedx.learning.course.passing.status.updated.v1", - "org.openedx.learning.ccx.course.passing.status.updated.v1", - ], - # Credly integration: - "credly": { - "CREDLY_BASE_URL": "https://credly.com/", - "CREDLY_API_BASE_URL": "https://api.credly.com/v1/", - "CREDLY_SANDBOX_BASE_URL": "https://sandbox.credly.com/", - "CREDLY_SANDBOX_API_BASE_URL": "https://sandbox-api.credly.com/v1/", - "USE_SANDBOX": False, - }, - # Accredible integration: - "accredible": { - "ACCREDIBLE_BASE_URL": "https://dashboard.accredible.com/", - "ACCREDIBLE_API_BASE_URL": "https://api.accredible.com/v1/", - "ACCREDIBLE_SANDBOX_BASE_URL": "https://sandbox.dashboard.accredible.com/", - "ACCREDIBLE_SANDBOX_API_BASE_URL": "https://sandbox.api.accredible.com/v1/", - "USE_SANDBOX": False, - }, - - # requirements data rules: - "rules": { - "ignored_keypaths": [ - "user.id", - "user.is_active", - "user.pii.username", - "user.pii.email", - "user.pii.name", - ], - }, - } - -- ``events`` - explicit event bus signals list (only events with PII user data in payload are applicable). -- ``credly`` - Credly integration details. -- ``accredible`` - Accredible integration details. -- ``rules.ignored_keypaths`` - event payload paths to exclude from data rule options (see: Configuration_). - -Credly integration -~~~~~~~~~~~~~~~~~~ - -- USE_SANDBOX - enables Credly sandbox usage (development, testing); -- CREDLY_BASE_URL - Credly service host URL; -- CREDLY_API_BASE_URL - Credly API host URL; -- CREDLY_SANDBOX_BASE_URL - Credly sandbox host URL; -- CREDLY_SANDBOX_API_BASE_URL - Credly sandbox API host URL; - -Accredible integration -~~~~~~~~~~~~~~~~~~~~~~ -- USE_SANDBOX - enables Accredible sandbox usage (development, testing); -- ACCREDIBLE_BASE_URL - Accredible service host URL; -- ACCREDIBLE_API_BASE_URL - Accredible API host URL; -- ACCREDIBLE_SANDBOX_BASE_URL - Accredible sandbox host URL; - -Event bus settings ------------------- - - ``learning-badges-lifecycle`` is the event bus topic for all Badges related events. - -The Badges feature has updated event bus producer configurations for the Platform and the Credentials services. - -Source public signals -~~~~~~~~~~~~~~~~~~~~~ - -Platform's event bus producer configuration was extended with 2 public signals: - -1. information about the fact someone’s course grade was updated (allows course completion recognition); -2. information about the fact someone’s CCX course grade was updated (allows CCX course completion recognition). - -.. code-block:: python - - # Platform services settings: - EVENT_BUS_PRODUCER_CONFIG = { - ... - - "org.openedx.learning.course.passing.status.updated.v1": { - "learning-badges-lifecycle": { - "event_key_field": "course_passing_status.course.course_key", - "enabled": _should_send_learning_badge_events, - }, - }, - "org.openedx.learning.ccx.course.passing.status.updated.v1": { - "learning-badges-lifecycle": { - "event_key_field": "course_passing_status.course.course_key", - "enabled": _should_send_learning_badge_events, - }, - }, - } - -Emitted public signals -~~~~~~~~~~~~~~~~~~~~~~ - -The Badges feature introduced 2 own event types: - -1. information about the fact someone has earned a badge; -2. information about the fact someone's badge was revoked; - -.. code-block:: python - - # Credentials service settings: - EVENT_BUS_PRODUCER_CONFIG = { - ... - - "org.openedx.learning.badge.awarded.v1": { - "learning-badges-lifecycle": {"event_key_field": "badge.uuid", "enabled": True }, - }, - "org.openedx.learning.badge.revoked.v1": { - "learning-badges-lifecycle": {"event_key_field": "badge.uuid", "enabled": True }, - }, - } - -Consuming workers -~~~~~~~~~~~~~~~~~ - -.. note:: - - Consumers implementation depends on the used event bus. - -Event bus options: - -- Redis Streams -- Kafka -- ... - -The Credentials and the Platform services **produce** (push) their public signals as messages to the stream. - -To **consume** (pull) those messages a consumer process is required. - -Redis Streams -############# - -When the Redis Streams event bus is used, the ``-learning-badges-lifecycle`` stream is used for messages transport. - -For producing and consuming a single package (broker) is used - event-bus-redis_. - -"Event Bus Redis" is implemented as a Django application and provides a Django management command for consuming messages -(see all details in the package's README). - -.. code-block:: bash - - # Credentials service consumer example: - /edx/app/credentials/credentials/manage.py consume_events -t learning-badges-lifecycle -g credentials_dev --extra={"consumer_name":"credentials_dev.consumer1"} - - # LMS service consumer example: - /edx/app/edxapp/edx-platform/manage.py lms consume_events -t learning-badges-lifecycle -g lms_dev --extra={"consumer_name":"lms_dev.consumer1"} - -.. note:: - - **Credentials event bus consumer** is crucial for the Badges feature, since it is responsible for all incoming events processing. - - **LMS event bus consumer** is only required if LMS wants to receive information about badges processing results (awarding/revocation). - - -.. _Configuration: configuration.html -.. _event-bus-redis: https://github.com/openedx/event-bus-redis \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index 9f16300dc..58fd2865c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -12,20 +12,19 @@ This repository contains the Open edX Credentials Service, used as the backend t overview getting_started - asset_pipeline - testing - internationalization - theming credentials_admin learner_records configuring_certificates - verifiable_credentials/overview + sharing/index + asset_pipeline + theming pathways analytics + testing + internationalization credentials_api event_bus edx_extensions lms_user_id program_completion_emails decisions - badges/index diff --git a/docs/sharing/badges/configuration/accredible.rst b/docs/sharing/badges/configuration/accredible.rst new file mode 100644 index 000000000..1d5c77c73 --- /dev/null +++ b/docs/sharing/badges/configuration/accredible.rst @@ -0,0 +1,55 @@ +.. _badges-accredible-configuration: + +Accredible Configuration +======================== + +.. _badges-accredible-api-configs: + +Accredible API Configurations +----------------------------- + +Multiple Accredible API Configurations can be configured in the Open edX platform. +Each API configuration stores the credentials that the Open edX Credentials service uses to sync groups and issue badges for an Accredible account. + +To configure an Accredible account in Open edX Credentials, navigate to ``https:///admin/badges/accredibleapiconfig/`` and add a new configuration: + +#. Set the **name** for the config. +#. Set the **API key** used to sync the Accredible account. + +If errors occur, verify the credentials used for the API Config. + +Groups +------ + +Accredible groups are the provider-side equivalent of badge templates. +After you create them in the Accredible dashboard, Open edX Credentials imports them through manual synchronization. + +.. note:: + + Accredible does not support webhooks. You should run synchronization manually whenever you create, rename, or remove groups in the Accredible dashboard. + +Synchronization +~~~~~~~~~~~~~~~ + +Synchronization imports current groups from your Accredible account into Open edX Credentials so you can configure requirements, penalties, and activation state locally. +Run it after you create, rename, or remove groups in the Accredible dashboard, and before you start configuring those groups in Open edX Credentials. + +#. Navigate to ``https:///admin/badges/accredibleapiconfig/`` and check the checkbox for the Accredible API configuration you want to synchronize. +#. Run the ``Sync groups`` action. + +.. figure:: ../../../_static/images/badges/badges-admin-groups-sync.png + :alt: Accredible API Configs admin list showing the action used to sync groups from Accredible into Credentials. + +On success, the system updates the list of Accredible groups from the provider and creates new group records in Open edX Credentials as inactive (disabled). + +.. warning:: + + Synchronization removes local group records that are no longer present on the Accredible side. This cascading deletion also removes associated requirements and data rules. Back up your configuration before syncing if you have made local changes. + +Configure requirements (see :ref:`badges-configuration-requirements`) and activate the group (see :ref:`badges-configuration-activation`) before it takes effect. + +.. seealso:: + + `How Do I Find My Integration API Key? `_ + Finding your Accredible API key for integration setup. + diff --git a/docs/sharing/badges/configuration/credly.rst b/docs/sharing/badges/configuration/credly.rst new file mode 100644 index 000000000..be30a503a --- /dev/null +++ b/docs/sharing/badges/configuration/credly.rst @@ -0,0 +1,78 @@ +.. _badges-credly-configuration: + +Credly Configuration +==================== + +.. _badges-credly-organizations: + +Credly Organizations +-------------------- + +Multiple Credly Organizations can be configured. +Each Credly Organization record stores the credentials and organization identifier that Open edX Credentials uses to sync badge templates and issue badges for that Credly organization. + +To configure a Credly organization in Open edX Credentials, navigate to ``https:///admin/badges/credlyorganization/`` and add a new organization: + +#. Set the **UUID** to your Credly Organization identifier. +#. Set the **API key** used to authenticate with the Credly Organization. + +.. note:: + + Credly API keys have a limited lifetime of 180 days. Rotate them before expiry. See `Auth Tokens for Authorization `_. + +The system pulls the Organization's details and updates its name. +If errors occur, verify the API key and UUID for the Organization. + +Badge Templates +--------------- + +Credly badge templates are created in the `Credly Organization dashboard `_. +After a template is published, Open edX Credentials can import it either through manual synchronization or through Credly webhook events. + +Webhooks +~~~~~~~~ + +Webhooks keep Open edX Credentials in sync with changes made in your Credly organization. Configure them if you want badge template changes in Credly, such as creating, updating, publishing, or archiving templates, to be reflected in Open edX Credentials automatically instead of waiting for a manual synchronization. + +Configure a webhook in the Credly management dashboard to point to your Credentials service: + +``https:///badges/credly/webhook/`` + +For Credly-side webhook setup details, see `Create a webhook callback URL `_. + +Open edX Credentials handles the following Credly webhook event types: + +- ``badge_template.created`` - a new badge template is published. +- ``badge_template.changed`` - a badge template is updated or archived. If the template state is no longer ``active``, Credentials automatically deactivates it. +- ``badge_template.deleted`` - a badge template is removed. + +Synchronization +~~~~~~~~~~~~~~~ + +To synchronize Credly badge templates for an Organization: + +#. Navigate to ``https:///admin/badges/credlyorganization/`` and select the Organization. +#. Run the ``Sync organization badge templates`` action. + +.. figure:: ../../../_static/images/badges/badges-admin-credly-templates-sync.png + :alt: Credly Organizations admin list showing the action used to sync badge templates from Credly into Credentials. + +On success, the system fetches all badge templates whose state is ``active`` on the Credly side. Pagination is handled automatically. + +New badge template records in Open edX Credentials are created inactive (disabled). + +.. figure:: ../../../_static/images/badges/badges-admin-credly-templates-list.png + :alt: Credly badge templates admin list showing the template records available after a successful sync. + +Use the badge templates list at ``https:///admin/badges/credlybadgetemplate/`` to confirm the expected active templates were imported before you configure requirements. + +Configure requirements (see :ref:`badges-configuration-requirements`) and activate the template (see :ref:`badges-configuration-activation`) before it takes effect. + +.. seealso:: + + `Credly Authentication Methods `_ + How to authenticate with the Credly API. + + `Auth Tokens for Authorization `_ + How to generate and manage Credly auth tokens. + diff --git a/docs/sharing/badges/configuration/examples.rst b/docs/sharing/badges/configuration/examples.rst new file mode 100644 index 000000000..56102f9b3 --- /dev/null +++ b/docs/sharing/badges/configuration/examples.rst @@ -0,0 +1,282 @@ +.. _Configuration examples for Badging: + +Configuration Examples +====================== + +These examples show how to configure badge :ref:`requirements ` and :ref:`data rules ` for common use cases. +Each example lists the fields as they appear on the requirement and data rule forms in the Credentials admin. + +The screenshots below show the Django admin forms where you configure the requirements, groups, and data rules used in the examples on this page. + +.. figure:: ../../../_static/images/badges/badges-admin-template-requirements.png + :alt: Badge template detail page showing the inline list of badge requirements. + + Use this form to add or review requirement records for a badge template. For field descriptions and requirement behavior, see :ref:`badges-configuration-requirements`. + +.. figure:: ../../../_static/images/badges/badges-admin-rules-group.png + :alt: Badge requirement form showing the Group field. + + Use the Group field when a requirement should be evaluated together with other requirements by OR logic. For grouping rules and examples, see :ref:`badges-configuration-groups`. + +.. figure:: ../../../_static/images/badges/badges-admin-data-rules.png + :alt: Badge requirement form showing the Data Rules section. + + Use this form to configure event fields, group assignment, and data rules for a requirement. For data rule fields and matching behavior, see :ref:`badges-configuration-data-rules`. + + +Course Completion +----------------- + +The examples below show common ways to configure badge requirements for course-completion and CCX-completion events. +Use them as starting points when you want to issue badges based on passing status, specific course keys, or combinations of course and CCX requirements. + +ANY COURSE GRADE Update +~~~~~~~~~~~~~~~~~~~~~~~ + + Triggers on any gradable interaction (e.g. submit button click) in any course. Rarely useful on its own. + +- **Requirement 1**: + a. event type: ``org.openedx.learning.course.passing.status.updated.v1`` + b. description: ``On any grade update.`` + + +ANY COURSE Completion +~~~~~~~~~~~~~~~~~~~~~ + + Requires **passing grade** for any course. Once a course grade becomes "passing" after a gradable problem submission, + a badge is awarded. + +- **Requirement 1**: + a. event type: ``org.openedx.learning.course.passing.status.updated.v1`` + b. description: ``On any (not CCX) course completion.`` + c. **Data rule 1**: + i. key path: ``is_passing`` + ii. operator: ``"=" (equals)`` + iii. value: ``true`` + + +ANY COURSE Completion EXCEPT a Specific Course +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Requires **passing grade** for any course **excluding** the "Demo" course. + +- **Requirement 1**: + a. event type: ``org.openedx.learning.course.passing.status.updated.v1`` + b. description: ``On any course completion, but not the "Demo" course.`` + c. **Data rule 1**: + i. key path: ``is_passing`` + ii. operator: ``"=" (equals)`` + iii. value: ``true`` + d. **Data rule 2**: + i. key path: ``course.course_key`` + ii. operator: ``"!=" (not equals)`` + iii. value: ``course-v1:OpenedX+DemoX+Demo_Course`` + + +SPECIFIC COURSE Completion +~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Requires **passing grade** for exact course ("Demo" course). + +- **Requirement 1**: + a. event type: ``org.openedx.learning.course.passing.status.updated.v1`` + b. description: ``On the Demo course completion.`` + c. **Data rule 1**: + i. key path: ``is_passing`` + ii. operator: ``"=" (equals)`` + iii. value: ``true`` + d. **Data rule 2**: + i. key path: ``course.course_key`` + ii. operator: ``"=" (equals)`` + iii. value: ``course-v1:OpenedX+DemoX+Demo_Course`` + +MULTIPLE SPECIFIC COURSES Completion +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + **All** specified courses must be completed. + Different requirement groups force each requirement to be fulfilled. + +- **Requirement 1**: + a. event type: ``org.openedx.learning.course.passing.status.updated.v1`` + b. description: ``On the "Demo" course completion.`` + c. group: ``A`` + d. **Data rule 1**: + i. key path: ``is_passing`` + ii. operator: ``"=" (equals)`` + iii. value: ``true`` + e. **Data rule 2**: + i. key path: ``course.course_key`` + ii. operator: ``"=" (equals)`` + iii. value: ``course-v1:OpenedX+DemoX+Demo_Course`` + +- **Requirement 2**: + a. event type: ``org.openedx.learning.course.passing.status.updated.v1`` + b. description: ``On the "Other" course completion.`` + c. group: ``B`` + d. **Data rule 1**: + i. key path: ``is_passing`` + ii. operator: ``"=" (equals)`` + iii. value: ``true`` + e. **Data rule 2**: + i. key path: ``course.course_key`` + ii. operator: ``"=" (equals)`` + iii. value: ``course-v1:OpenedX+DemoX+OTHER_Course`` + + +ONE OF MULTIPLE SPECIFIC COURSES Completion +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + At least a single from the specified courses must be completed. + Grouped requirements are processed as **"ANY FROM A GROUP"**. + +- **Requirement 1**: + a. event type: ``org.openedx.learning.course.passing.status.updated.v1`` + b. description: ``On the "Demo" course completion.`` + c. group: ``A`` + d. **Data rule 1**: + i. key path: ``is_passing`` + ii. operator: ``"=" (equals)`` + iii. value: ``true`` + e. **Data rule 2**: + i. key path: ``course.course_key`` + ii. operator: ``"=" (equals)`` + iii. value: ``course-v1:OpenedX+DemoX+Demo_Course`` + +- **Requirement 2**: + a. event type: ``org.openedx.learning.course.passing.status.updated.v1`` + b. description: ``On the "Other" course completion.`` + c. group: ``A`` + d. **Data rule 1**: + i. key path: ``is_passing`` + ii. operator: ``"=" (equals)`` + iii. value: ``true`` + e. **Data rule 2**: + i. key path: ``course.course_key`` + ii. operator: ``"=" (equals)`` + iii. value: ``course-v1:OpenedX+DemoX+OTHER_Course`` + + +CCX Course Completion +--------------------- + + +ANY CCX Course Completion +~~~~~~~~~~~~~~~~~~~~~~~~~ + + Requires **passing grade** for any CCX course. + +- **Requirement 1**: + a. event type: ``org.openedx.learning.ccx.course.passing.status.updated.v1`` + b. description: ``On any CCX course completion.`` + c. **Data rule 1**: + i. key path: ``is_passing`` + ii. operator: ``"=" (equals)`` + iii. value: ``true`` + + +SPECIFIC CCX Course Completion +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Requires **passing grade** for exact CCX course ("Demo CCX1" course). + +- **Requirement 1**: + a. event type: ``org.openedx.learning.ccx.course.passing.status.updated.v1`` + b. description: ``On the Demo CCX1 course completion.`` + c. **Data rule 1**: + i. key path: ``is_passing`` + ii. operator: ``"=" (equals)`` + iii. value: ``true`` + d. **Data rule 2**: + i. key path: ``course.ccx_course_key`` + ii. operator: ``"=" (equals)`` + iii. value: ``ccx-v1:OpenedX+DemoX+Demo_Course+ccx@1`` + +ANY CCX Course Completion on a Specific Master Course +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Requires **passing grade** for any "child" CCX course that based on the master "Demo" course. + +- **Requirement 1**: + a. event type: ``org.openedx.learning.ccx.course.passing.status.updated.v1`` + b. description: ``On any Demo CCX course completion.`` + c. **Data rule 1**: + i. key path: ``is_passing`` + ii. operator: ``"=" (equals)`` + iii. value: ``true`` + d. **Data rule 2**: + i. key path: ``course.master_course_key`` + ii. operator: ``"=" (equals)`` + iii. value: ``course-v1:OpenedX+DemoX+Demo_Course`` + +ANY CCX Course Completion on a Specific Master Course Except a Specific CCX Course +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Requires **passing grade** for **any "child" CCX course** that based on the master "Demo" course, **excluding** the "Demo CCX2" course. + +- **Requirement 1**: + a. event type: ``org.openedx.learning.ccx.course.passing.status.updated.v1`` + b. description: ``On any Demo CCX course completion.`` + c. **Data rule 1**: + i. key path: ``is_passing`` + ii. operator: ``"=" (equals)`` + iii. value: ``true`` + d. **Data rule 2**: + i. key path: ``course.master_course_key`` + ii. operator: ``"=" (equals)`` + iii. value: ``course-v1:OpenedX+DemoX+Demo_Course`` + e. **Data rule 3**: + i. key path: ``course.ccx_course_key`` + ii. operator: ``"!=" (not equals)`` + iii. value: ``ccx-v1:OpenedX+DemoX+Demo_Course+ccx@2`` + + +Specific Master Course OR Any of Its CCX Courses Except a Specific CCX Course +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Here requirements 1 and 2 are grouped, so any of them lead to a badge. + +- **Requirement 1**: + a. event type: ``org.openedx.learning.course.passing.status.updated.v1`` + b. description: ``On the "Demo" course completion OR...`` + c. group: ``A`` + d. **Data rule 1**: + i. key path: ``is_passing`` + ii. operator: ``"=" (equals)`` + iii. value: ``true`` + e. **Data rule 2**: + i. key path: ``course.course_key`` + ii. operator: ``"=" (equals)`` + iii. value: ``course-v1:OpenedX+DemoX+Demo_Course`` + +- **Requirement 2**: + a. event type: ``org.openedx.learning.ccx.course.passing.status.updated.v1`` + b. description: ``...OR any Demo CCX courses completion EXCLUDING CCX3.`` + c. group: ``A`` + d. **Data rule 1**: + i. key path: ``is_passing`` + ii. operator: ``"=" (equals)`` + iii. value: ``true`` + e. **Data rule 2**: + i. key path: ``course.master_course_key`` + ii. operator: ``"=" (equals)`` + iii. value: ``course-v1:OpenedX+DemoX+Demo_Course`` + f. **Data rule 3**: + i. key path: ``course.ccx_course_key`` + ii. operator: ``"!=" (not equals)`` + iii. value: ``ccx-v1:OpenedX+DemoX+Demo_Course+ccx@3`` + +----- + +Potential Use Cases +------------------- + +The following ideas are not yet implemented. If you have a use case for any of them, start a conversation on the `Open edX discussion forum`_. + +- Events set extension (e.g. "Email activation", "Profile data completion", "Course section completion") +- Repetitive events (e.g. "5 arbitrary courses completion") +- Prerequisite events (e.g. "5 specific courses completion in a specified order") +- Time-ranged events (e.g. "Arbitrary course completion during February 2022") +- Badge dependencies (e.g. "Badge A + Badge B = Badge C") +- Multiple same badge earning (e.g. "3 arbitrary course completions make badge earned x3") + +.. _Open edX discussion forum: https://discuss.openedx.org/ diff --git a/docs/sharing/badges/configuration/index.rst b/docs/sharing/badges/configuration/index.rst new file mode 100644 index 000000000..57dcc2787 --- /dev/null +++ b/docs/sharing/badges/configuration/index.rst @@ -0,0 +1,239 @@ +.. _badges-configuration: + +Badging Configuration +===================== + +Badge templates, requirements, data rules, and penalties are configured in the Badges section of the Credentials administration panel of your Open edX instance. +Each badge template needs at least one requirement and must be activated before it takes effect. + +The screenshot below shows the main admin entry point where you access provider records, badge templates, requirements, penalties, and issued badge data. + +.. figure:: ../../../_static/images/badges/badges-admin.png + :alt: Credentials Django admin index showing the Badges section where badge templates, requirements, and provider records are managed. + +Provider Setup +-------------- + +Use the provider-specific pages in this section when you need to configure provider credentials, synchronize badge templates or groups, or understand provider-specific behavior such as webhooks and synchronization rules. + +.. toctree:: + :maxdepth: 1 + + credly + accredible + examples + +.. _badges-configuration-templates: + +Badge Templates +--------------- + +Credentials stores provider-side badge definitions as badge templates. +Credly exposes them as badge templates at ``https:///admin/badges/credlybadgetemplate/``. +Accredible exposes the equivalent records as groups at ``https:///admin/badges/accrediblegroup/``. + +Badge templates and groups cannot be created manually in the Open edX Credentials administration panel. You must first synchronize them from the external provider. See :ref:`badges-credly-configuration` or :ref:`badges-accredible-configuration`. + +Open the template or group record to review and update badge configuration. +This detail page is where you manage provider-specific attributes, requirements, penalties, and activation state. + +The screenshot below shows the badge template detail page used to review badge-specific configuration. + +.. figure:: ../../../_static/images/badges/badges-admin-template-details.png + :alt: Badge template detail page showing the sections used to review badge-specific configuration. + +The badge template detail page contains the following sections: + +.. list-table:: Badge template detail page sections + :widths: 30 70 + :header-rows: 1 + + * - Section + - Description + * - Generic + - Shared settings such as site assignment and activation state. + * - Badge template + - Badge-specific fields such as name, description, image, and origin. These values are populated from the remote provider during synchronization. + * - Credly or Accredible + - Provider-managed fields such as state, dashboard link, and organization or API configuration. The section label depends on the provider. See :ref:`badges-credly-configuration` or :ref:`badges-accredible-configuration`. + * - Configured requirements + - Inline requirement records for this badge template. See :ref:`badges-configuration-requirements`. + * - Configured penalties + - Inline penalty records for this badge template. See :ref:`badges-configuration-penalties`. + +.. _badges-configuration-requirements: + +Badge Requirements +------------------ + +Requirements describe what must happen for a learner to earn a badge. +At least one requirement must be associated with a :ref:`Badge Template `. +A :ref:`Badge Template ` detail page includes the inline requirements section where you add and edit requirements. +A badge template can have multiple requirements, and **all requirements** must be fulfilled before the system issues a badge. +The badge template must be activated before it takes effect. + +The screenshot below shows the inline badge requirements section on the badge template detail page. + +.. figure:: ../../../_static/images/badges/badges-admin-template-requirements.png + :alt: Badge template detail page showing the inline list of badge requirements beneath the template record. + +Each requirement has the following fields. + +- **Event type** - the Open edX platform event that must occur. The default supported events are: + + - ``org.openedx.learning.course.passing.status.updated.v1`` - course grade updated. + - ``org.openedx.learning.ccx.course.passing.status.updated.v1`` - CCX course grade updated. + + Any public signal from the `openedx-events`_ library can extend this set (see :ref:`badges-settings`). +- **Rules** - a list of configured data rules (if any). See :ref:`badges-configuration-data-rules`. +- **Description** - an optional human-readable reminder about the requirement's purpose. +- **Group** - controls OR/AND behavior across requirements. See :ref:`badges-configuration-groups`. + +.. figure:: ../../../_static/images/badges/badges-admin-template-requirements.png + :alt: Badge template detail page showing the inline list of badge requirements beneath the template record. + +.. note:: + + You can use any public signal from the `openedx-events`_ library if its payload includes learner-identifying PII in ``UserData``. + +.. _badges-configuration-groups: + +Badge Requirement Groups +------------------------ + +Each :ref:`Badge Requirement ` has a **Group** field. +On the badge requirement detail page, you select one of the available group values from ``A`` to ``Z``. New requirements default to the next available letter. + +Requirements in the same group use OR logic - fulfilling any one of them fulfills the group. +Requirements in different groups use AND logic - all groups must be fulfilled before the badge is issued. + +Use groups when a learner can satisfy one part of a badge in multiple ways. +For example, if a learner may complete either Course A or Course B to satisfy one part of a badge, place both requirements in the same group. +If the learner must also complete Course C, put that requirement in a separate group. + +For example: + +- Group ``A`` + + - Requirement 1: pass Course A + - Requirement 2: pass Course B + +- Group ``B`` + + - Requirement 3: pass Course C + +In this configuration, the learner must fulfill either Requirement 1 or Requirement 2, and also fulfill Requirement 3. + +The screenshot below continues the requirement form and highlights the **Group** field. + +.. figure:: ../../../_static/images/badges/badges-admin-rules-group.png + :alt: Badge requirement form showing the Group field used to place multiple requirements into the same OR-logic group. + +For more grouping examples, see :ref:`Configuration examples for Badging`. + +.. _badges-configuration-data-rules: + +Data Rules +---------- + +Data rules are configured on the :ref:`Badge Requirement ` detail page. +They allow you to combine multiple conditions for a single badge requirement. +All data rules on that requirement must match (AND logic). +Data rules do not link requirements together - each rule set applies only to its own requirement's incoming event. + +To add or edit a data rule: + +#. Navigate to ``https:///admin/badges/credlybadgetemplate/`` or ``https:///admin/badges/accrediblegroup/`` and open the template or group you want to configure. +#. In the inline requirements list, use the ``Change`` link for the requirement you want to edit. +#. On the requirement detail page, find the "Data Rules" section and add a new item. + +.. figure:: ../../../_static/images/badges/badges-admin-requirement-rules.png + :alt: Badge requirement detail form opened from the inline Change link, showing where Data Rules are configured for that requirement. + +Each data rule describes a single expected payload value. +Key paths are generated from the event type of the parent requirement. + +.. figure:: ../../../_static/images/badges/badges-admin-data-rules.png + :alt: Badge requirement form showing the inline Data Rules section with numbered markers for key path, operator, and expected value fields. + +The numbered markers on the screenshot correspond to data rule fields: + +.. list-table:: + :widths: 10 20 70 + :header-rows: 1 + + * - # + - Field + - Description + * - 1 + - **Key path** + - Dot-separated path to a field in the event payload. Available key paths depend on the selected event type and come from the event structure defined in `openedx-events`_. + * - 2 + - **Operator** + - Comparison operation: ``"="`` (equals) or ``"!="`` (not equals). + * - 3 + - **Expected value** + - The expected value of that event field, for example ``true``, ``course-v1:OpenedX+DemoX+Demo_Course``, or ``ccx-v1:edX+DemoX+Demo_Course+ccx@1``. + +.. note:: + + For boolean fields, the following string values are accepted: + + - **True:** ``"true"``, ``"True"``, ``"yes"``, ``"Yes"``, ``"+"`` + - **False:** ``"false"``, ``"False"``, ``"no"``, ``"No"``, ``"-"`` + +See :ref:`Configuration examples for Badging` for some examples of how data rules can be applied to achieve specific conditions. + +.. _badges-configuration-penalties: + +Badge Penalties +--------------- + +Badge penalties are configured in the inline penalties section of the :ref:`Badge Template ` detail page. +They reset learner progress when a specific event occurs. +Use them for cases where previously earned progress should no longer count, for example when a passing grade later changes to failing. +For details on how this leads to badge revocation during processing, see :ref:`badges-processing`. + +Penalties are optional. A badge template can have zero or more penalties. + +A penalty is configured with an :ref:`event type `, its own :ref:`data rules `, and one or more linked :ref:`badge requirements `. +When an incoming event matches all of the penalty's data rules, the linked requirements are reset for that learner. + +.. figure:: ../../../_static/images/badges/badges-admin-penalty-rules.png + :alt: Badge penalty form showing the event trigger, linked requirements, and data rules used to reset learner progress. + +For example, the penalty shown in the screenshot above could listen for a ``course.passing.status.updated`` event where ``is_passing`` equals ``false``. +If that event occurs, the learner's progress for the linked requirements is reset. + +Examples +-------- + +Use :ref:`Configuration examples for Badging` for complete requirement and data rule configurations for common badge setups. + +.. _badges-configuration-activation: + +Activation and Deactivation +--------------------------- + +Use the badge template or group detail page to activate or deactivate badge processing for a template. + +#. Navigate to ``https:///admin/badges/credlybadgetemplate/`` or ``https:///admin/badges/accrediblegroup/``. + + .. figure:: ../../../_static/images/badges/badges-admin-credly-templates-list.png + :alt: Badge templates list page in the Credentials admin. + +#. Open the badge template or group detail page and set the ``Is active`` checkbox as needed. + + .. figure:: ../../../_static/images/badges/badges-admin-activation.png + :alt: Badge template detail page showing the Is active checkbox. + +#. Click **Save** at the bottom of the page to save and activate or deactivate the configuration. + +.. important:: + + After you activate a badge template, matching incoming events can fulfill its requirements, update learner progress, and trigger badge issuance when all required conditions are met. + + Deactivating a badge template stops future processing for that template. Already issued badges are retained. + Inactive badge templates are ignored during event processing. + +.. _openedx-events: https://github.com/openedx/openedx-events diff --git a/docs/sharing/badges/index.rst b/docs/sharing/badges/index.rst new file mode 100644 index 000000000..665f7a4c2 --- /dev/null +++ b/docs/sharing/badges/index.rst @@ -0,0 +1,63 @@ +Digital Badges +============== + +A digital badge is a credential that embeds metadata (issuer, criteria, +evidence) following the `Open Badges`_ standard. Badges can represent +individual achievements such as completing a course or passing an exam. + +Badge processing is driven by configured Open edX platform events +(such as course completion). The Badges feature issues badges through +external providers. Built-in support includes `Credly (by Pearson)`_ +and `Accredible`_. + +See :ref:`badges-settings` for the full list of supported events and +:ref:`badges-processing` for how events are handled. + +Key concepts +------------ + +**Badge template** + Defines a badge's design, name, and awarding rules. Called "group" in + Accredible. For configuration details, see :ref:`badges-configuration`. + +**Badge** + The credential a learner earns when they fulfill all requirements of a + badge template. For processing details, see :ref:`badges-processing`. + +**Requirement** + A condition tied to a specific event type (e.g. course completion) that + must be met to earn a badge. For requirement fields and behavior, see :ref:`badges-configuration-requirements`. + +**Data rule** + A filter on a requirement's event payload that narrows when the + requirement counts as fulfilled + (e.g. ``course.course_key equals course-v1:OpenedX+DemoX+Demo_Course``). + For configuration details, see :ref:`badges-configuration-data-rules`. + +**Group** + A way to organize requirements. Requirements in the same group use OR + logic (any one fulfills the group). Requirements in different groups use + AND logic (all groups must be fulfilled). + For grouping behavior, see :ref:`badges-configuration-requirements`. + +**Penalty** + A rule that resets specific requirement progress when a triggering event + occurs (e.g. grade drops below passing). + For penalty setup, see :ref:`badges-configuration-penalties`. + +---- + +To get started, follow the :ref:`badges-quickstart` guide. + +.. toctree:: + :maxdepth: 1 + + quickstart + settings + configuration/index + processing + management + +.. _Open Badges: https://openbadges.org/ +.. _Credly (by Pearson): https://info.credly.com/ +.. _Accredible: https://www.accredible.com/ diff --git a/docs/sharing/badges/management.rst b/docs/sharing/badges/management.rst new file mode 100644 index 000000000..00f1de874 --- /dev/null +++ b/docs/sharing/badges/management.rst @@ -0,0 +1,114 @@ +Managing Badges +=============== + +Creating Provider-Side Badge Definitions +---------------------------------------- + +Before you can synchronize or activate badges in Open edX Credentials, you must create the provider-side badge definitions in Credly or Accredible. + +For **Credly**: + +- Create and publish badge templates in your Credly organization first. For provider-side setup details, see `Credly Knowledge Base `_. +- Then configure the organization in Open edX Credentials and synchronize templates. See :ref:`badges-credly-configuration`. + +For **Accredible**: + +- Create groups in Accredible first. For provider-side setup details, see `Accredible Help Center `_. +- Then configure the API connection in Open edX Credentials and synchronize groups. See :ref:`badges-accredible-configuration`. + +Synchronizing Badge Templates +----------------------------- + +Badge templates (Credly) and groups (Accredible) are created on the provider's side and then pulled into Open edX Credentials through a sync action in the admin panel. + +For **Credly**: + +#. Navigate to ``https:///admin/badges/credlyorganization/`` and select one or more organizations. +#. Run the ``Sync organization badge templates`` action. + + .. figure:: ../../_static/images/badges/badges-admin-credly-templates-sync.png + :alt: Credly Organizations admin list showing the sync badge templates action. + +Only badge templates with ``active`` state on Credly are pulled. You can also configure Credly webhooks so template changes on the Credly side are synchronized automatically instead of waiting for the next manual sync. See :ref:`badges-credly-configuration` for webhook setup and full sync details. + +For **Accredible**: + +#. Navigate to ``https:///admin/badges/accredibleapiconfig/`` and select one or more configurations. +#. Run the ``Sync groups`` action. + + .. figure:: ../../_static/images/badges/badges-admin-groups-sync.png + :alt: Accredible API Configs admin list showing the sync groups action. + +See :ref:`badges-accredible-configuration` for full sync details. + +.. note:: + + Synchronized templates and groups are created **inactive** by + default. Configure requirements and activate them before they + take effect. See :ref:`badges-configuration-activation`. + +Badge Progress +-------------- + +Current badge progress is visible at ``https:///admin/badges/badgeprogress/`` in the Credentials admin. + +Badge templates can have more than one requirement, so there can +be partially completed badges. See :ref:`badges-processing` for +details on how progress is tracked. + +Awarded Credentials +------------------- + +Earned badges are listed at ``https:///admin/badges/credlybadge/`` for Credly and ``https:///admin/badges/accrediblebadge/`` for Accredible. + +Once badge progress is complete (all requirements are *fulfilled*), +the system awards the badge. See :ref:`badges-processing` for the +full awarding pipeline. + +The system: + +#. Creates an internal user credential record for the learner. +#. Emits a public signal about the badge award. +#. Sends an API request to the badge provider to issue the badge externally. + +Issued Badges +------------- + +After a badge is awarded internally, the system sends an API request to +the badge provider to issue the badge on their platform. + +On successful issuing, the badge record in ``https:///admin/badges/credlybadge/`` or ``https:///admin/badges/accrediblebadge/`` is updated with: + +#. **External identifier** - the identifier assigned by the provider (UUID for Credly, integer ID for Accredible). +#. **External state** - the badge status on the provider's side (e.g. ``accepted``). + +The issued badge then appears in the provider's dashboard and is visible +to the learner. + +Deactivation +------------ + +Deactivating a badge template stops future processing for that template. Already issued badges are retained. + +Deactivate a badge template by opening the record from ``https:///admin/badges/credlybadgetemplate/`` or ``https:///admin/badges/accrediblegroup/``, unchecking ``Is active``, and clicking **Save**. + +Inactive badge templates are ignored during event processing. To reactivate, check ``Is active`` again and save - processing resumes for new events immediately. + +See :ref:`badges-configuration-activation` for activation details. + +.. seealso:: + + `Credly Knowledge Base `_ + Provider-side setup and management for Credly badge templates. + + `Accredible Help Center `_ + Provider-side setup and management for Accredible groups. + + :ref:`badges-configuration` + Configure badge templates, requirements, and data rules. + + :ref:`badges-settings` + Feature switches and integration settings. + + :ref:`badges-processing` + How incoming events are processed and badges are awarded. diff --git a/docs/sharing/badges/processing.rst b/docs/sharing/badges/processing.rst new file mode 100644 index 000000000..ea1fcdac6 --- /dev/null +++ b/docs/sharing/badges/processing.rst @@ -0,0 +1,87 @@ +.. _badges-processing: + +Badges Processing +================== + +Incoming events are processed asynchronously in a separate event bus consumer process. +See :ref:`badges-event-bus-configuration` for setup details. + +This page explains how badge-related events are evaluated, how learner progress is tracked, and how badges are awarded or revoked. +The flowchart below gives a high-level view of that process. + +.. figure:: ../../_static/images/badges/badges-processing-flow.png + :alt: Flowchart showing badge event processing, progress updates, badge awarding, and penalty-based revocation. + + An incoming event can either fulfill badge requirements and move a learner toward badge issuance, or match a penalty and reset previously earned progress. + +Supported events +---------------- + +Only explicitly configured `event types`_ take part in the processing. +See :ref:`badges-settings` for the default set of supported events. +Any public signal from the `openedx-events`_ library can extend this set, +provided its payload includes learner PII (``UserData`` object). + + +Learner identification +---------------------- + +The system identifies a learner by the ``UserData`` object in the event payload. +If ``UserData`` is absent from the payload, the event is dropped. +If the learner does not yet exist in the Credentials service, the system creates a local user record automatically. + + +Requirement matching +-------------------- + +Each badge requirement is configured with a single :ref:`event type `. +For an incoming event, the system selects requirements configured for that event type and belonging to active badge templates. +The system then checks each requirement's rules against the event payload. +If any rule does not match, that requirement is skipped. + + +Progress tracking +----------------- + +Current learner badge progress is stored in ``Badge Progress`` records. +Badge templates can have more than one requirement, so the system tracks intermediate progress before a badge is issued. +You can review progress records in the Credentials admin at ``https:///admin/badges/badgeprogress/``. + +When a requirement's rules match the incoming event, the system ensures there is a badge progress record for the learner and marks that requirement as fulfilled. + +.. figure:: ../../_static/images/badges/badges-admin-progress-records.png + :alt: Django admin list of badge progress records, showing learner progress tracked before a badge is awarded. + +Use this admin view to confirm whether incoming events are advancing learner progress or whether penalties are resetting it. + +If all requirements for a badge template are fulfilled, the system starts the awarding process. + + +Badge awarding +-------------- + +When badge progress is complete, the system creates an internal badge record for the learner, emits a public badge-awarded signal, and then tries to issue the badge through the provider API. + +Provider-specific badge records (``CredlyBadge`` and ``AccredibleBadge``) store the external issuing state. +Once a badge is successfully issued, the corresponding record is updated with its external identifier and state. + +.. _event types: https://docs.openedx.org/projects/openedx-events/en/latest/ +.. _openedx-events: https://github.com/openedx/openedx-events + +Badge revocation +---------------- + +Penalties can reset badge progress when a specific event occurs. +Each penalty listens for its own event type and has its own data rules - it fires when all of its rules match an incoming event, not when a requirement becomes unfulfilled. + +A penalty targets one or more requirements (many-to-many relationship). +When a penalty fires, the system resets the learner's progress for all linked requirements. +See the :ref:`badges-configuration-penalties` section for penalty setup. + +When a badge is revoked, the system updates its internal records. +For Credly, status changes from ``awarded`` to ``revoked``. +For Accredible, status changes from ``awarded`` to ``expired``. + +.. warning:: + + Once a badge has been revoked, it cannot be awarded again through badge processing. diff --git a/docs/sharing/badges/quickstart.rst b/docs/sharing/badges/quickstart.rst new file mode 100644 index 000000000..1b60622ef --- /dev/null +++ b/docs/sharing/badges/quickstart.rst @@ -0,0 +1,236 @@ +.. _badges-quickstart: + +Quick Start +=========== + +Set up badge issuing for your Open edX instance with Credly or Accredible. By the end of this guide you will have a working badge template that awards badges to learners automatically. + +.. contents:: Steps + :local: + :class: no-bullets + +1. Prerequisites and installation +--------------------------------- + +The Credentials service must be installed and running on your Open edX instance. + +Option A: Using Tutor (recommended) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +#. Install the `tutor-credentials`_ plugin (provides the Credentials service): + + .. code-block:: bash + + pip install tutor-credentials + +#. Install the `tutor-contrib-badges`_ plugin (configures badge settings, event bus, and feature flags automatically): + + .. code-block:: bash + + pip install git+https://github.com/raccoongang/tutor-contrib-badges@main + + See the `tutor-contrib-badges README `_ for additional details, including a sample Pipfile and manual service commands. + +#. Enable the necessary plugins: + + .. code-block:: bash + + tutor plugins enable discovery mfe credentials badges + +#. Rebuild images and launch: + + .. code-block:: bash + + tutor images build openedx discovery credentials + tutor local launch + +The plugin automatically enables badge feature flags, configures the event bus, and registers the following consumer services: + +- ``credentials-eventbus-consumer`` +- ``credentials-certificates-eventbus-consumer`` +- ``lms-eventbus-consumer`` +- ``cms-eventbus-consumer`` + + +.. _tutor-credentials: https://github.com/overhangio/tutor-credentials +.. _tutor-contrib-badges: https://github.com/raccoongang/tutor-contrib-badges + +Option B: Other installations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +#. Install the Credentials service following the `Getting Started `_ guide. + +#. Enable badges in both services: + + .. code-block:: python + + # openedx-platform (LMS) settings: + FEATURES["BADGES_ENABLED"] = True + + # Credentials service settings: + BADGES_ENABLED = True + +#. Configure the event bus and consumer processes. See :ref:`badges-settings` for the full reference: + + - :ref:`badges-event-bus-configuration` - producer signals for LMS and Credentials. + - :ref:`badges-consumer-setup` - running the ``consume_events`` management command. + +.. _quickstart-configure-integration: + +2. Configure integration +------------------------ + +Set up your provider account and connect it to the Credentials admin panel for your instance. + +For **Credly**: + +#. Register on `Credly `_ and create your organization. +#. Create at least one badge template and publish it. +#. Retrieve your organization UUID and `API key `_. +#. In the Credentials admin panel, navigate to ``https:///admin/badges/credlyorganization/`` and add a new organization. + + a. Set the **UUID** to your Credly organization identifier. + b. Set the **API key** used to authenticate with the Credly organization. + + .. figure:: ../../_static/images/badges/badges-admin-credly-organization.png + :alt: Add Credly organization form showing the Uuid and Api key fields. + +#. Verify the system pulls the organization's data and updates its name. + + +For **Accredible**: + +#. Register on `Accredible `_ and create your account. +#. Create at least one group. +#. Retrieve your `API key `_ from account settings. +#. In the Credentials admin panel, navigate to ``https:///admin/badges/accredibleapiconfig/`` and add a new configuration. + + a. Set the **API key** from your Accredible account. + b. Set a **name** for the configuration. + + .. figure:: ../../_static/images/badges/badges-admin-accredible-api-config.png + :alt: Add Accredible API config form showing the Name and Api key fields. + + +.. seealso:: + + **Credly** + + :ref:`badges-credly-configuration` + Full Credly setup, webhooks, and synchronization details. + + `Credly Authentication Methods `_ + How to authenticate with the Credly API. + + `Auth Tokens for Authorization `_ + How to generate and manage Credly auth tokens. + + **Accredible** + + :ref:`badges-accredible-configuration` + Full Accredible setup and synchronization details. + + `How Do I Find My Integration API Key? `_ + Finding your Accredible API key for integration setup. + +3. Synchronize badge templates +------------------------------ + +Synchronization imports badge templates from your provider into the Credentials service. + +For **Credly**: + +#. Navigate to ``https:///admin/badges/credlyorganization/`` and select the organization(s) you want to use. +#. Run the ``Sync organization badge templates`` action. + + .. figure:: ../../_static/images/badges/badges-admin-credly-templates-sync.png + :alt: Credly Organizations admin list showing the sync badge templates action. + +#. Navigate to ``https:///admin/badges/credlybadgetemplate/`` and verify the newly created templates. + +See :ref:`badges-credly-configuration` for details on template synchronization and webhook setup. + +For **Accredible**: + +#. Navigate to ``https:///admin/badges/accredibleapiconfig/`` and select the configuration(s) you want to use. +#. Run the ``Sync groups`` action. + + .. figure:: ../../_static/images/badges/badges-admin-groups-sync.png + :alt: Accredible API Configs admin list showing the sync groups action. + +#. Navigate to ``https:///admin/badges/accrediblegroup/`` and verify the newly created groups. + +See :ref:`badges-accredible-configuration` for details on group synchronization. + +4. Set up badge requirements +---------------------------- + +Requirements define what must happen for a learner to earn a badge. At least one requirement must be associated with a badge template. + +In the Credentials admin panel, open the badge template or group record you want to configure from ``https:///admin/badges/credlybadgetemplate/`` or ``https:///admin/badges/accrediblegroup/``: + +.. figure:: ../../_static/images/badges/badges-admin-template-requirements.png + :alt: Badge template detail page showing the inline list of badge requirements. + +#. Find the "Badge Requirements" section. +#. Add a new item and select an event type (what is expected to happen). + + - Optionally, add a description. + +#. Save and navigate to the requirement detail page by using the ``Change`` link in the inline requirements list. Requirement detail pages use the admin URL pattern ``https:///admin/badges/badgerequirement//change/``. + + - Optionally, specify data rules in the "Data Rules" section: + + #. Select a key path (specific data element). + #. Select an operator (how to compare the value). + #. Enter a value (expected parameter's value). + +.. figure:: ../../_static/images/badges/badges-admin-data-rules.png + :alt: Badge requirement form showing the inline Data Rules section. + +A badge template can have more than one requirement. For example, a badge +template issued on a specific course completion: + +- Requirement 1: + - event type: ``org.openedx.learning.course.passing.status.updated.v1`` + - description: ``On the Demo course completion.`` +- Data rule 1: + - key path: ``course.course_key`` + - operator: ``"=" (equals)`` + - value: ``course-v1:OpenedX+DemoX+Demo_Course`` +- Data rule 2: + - key path: ``is_passing`` + - operator: ``"=" (equals)`` + - value: ``true`` + +.. seealso:: + + :ref:`badges-configuration-requirements` + Full reference for badge requirements. + + :ref:`badges-configuration-data-rules` + Full reference for data rules. + +5. Activate badge templates +--------------------------- + +#. Navigate to ``https:///admin/badges/credlybadgetemplate/`` or ``https:///admin/badges/accrediblegroup/``. + + .. figure:: ../../_static/images/badges/badges-admin-credly-templates-list.png + :alt: Badge templates list page in the Credentials admin. + +#. Open the badge template or group detail page and check the ``Is active`` checkbox. + + .. figure:: ../../_static/images/badges/badges-admin-activation.png + :alt: Badge template detail page showing the Is active checkbox. + +#. Click **Save** at the bottom of the page to save and activate the configuration. + +.. warning:: + + Changing configuration of active badge templates may cause inconsistent learner experience. + +.. seealso:: + + :ref:`badges-configuration-activation` + Full reference for badge template activation. diff --git a/docs/sharing/badges/settings.rst b/docs/sharing/badges/settings.rst new file mode 100644 index 000000000..546037037 --- /dev/null +++ b/docs/sharing/badges/settings.rst @@ -0,0 +1,248 @@ +.. _badges-settings: + +Badging Settings +================= + +These settings control the Badges feature: availability, event subscriptions, and provider integration (Credly, Accredible). + +.. note:: + + If you are using Tutor, the `tutor-contrib-badges`_ plugin configures all required settings automatically. See :ref:`badges-quickstart` for installation steps and the `tutor-contrib-badges README `_ for plugin-specific configuration options. + + You can usually skip the rest of this page for a standard Tutor installation. Come back to it for manual overrides, troubleshooting, or custom event-bus and provider configuration. + + If you need help with a customized setup, use the plugin documentation above and ask on the `Open edX discussion forum `_. + +.. _tutor-contrib-badges: https://github.com/raccoongang/tutor-contrib-badges + + +Feature Switch +-------------- + +The Badges feature is disabled by default. Enable it in both services. + +.. code-block:: python + + # openedx-platform (LMS) settings: + FEATURES["BADGES_ENABLED"] = True + + # Credentials service settings: + BADGES_ENABLED = True + +In the LMS, ``BADGES_ENABLED`` gates **sending** badge-related events to the event bus. +In the Credentials service, ``BADGES_ENABLED`` gates **receiving** and processing those events. +Both must be enabled for badges to work. + + +``BADGES_CONFIG`` Reference +---------------------------- + +``BADGES_CONFIG`` is the main configuration dictionary for the Credentials service. + +.. code-block:: python + + BADGES_CONFIG = { + "events": [ + "org.openedx.learning.course.passing.status.updated.v1", + "org.openedx.learning.ccx.course.passing.status.updated.v1", + ], + "credly": { + "CREDLY_BASE_URL": "https://credly.com/", + "CREDLY_API_BASE_URL": "https://api.credly.com/v1/", + "CREDLY_SANDBOX_BASE_URL": "https://sandbox.credly.com/", + "CREDLY_SANDBOX_API_BASE_URL": "https://sandbox-api.credly.com/v1/", + "USE_SANDBOX": False, + }, + "accredible": { + "ACCREDIBLE_BASE_URL": "https://dashboard.accredible.com/", + "ACCREDIBLE_API_BASE_URL": "https://api.accredible.com/v1/", + "ACCREDIBLE_SANDBOX_BASE_URL": "https://sandbox.dashboard.accredible.com/", + "ACCREDIBLE_SANDBOX_API_BASE_URL": "https://sandbox.api.accredible.com/v1/", + "USE_SANDBOX": False, + }, + "rules": { + "ignored_keypaths": [ + "user.id", + "user.is_active", + "user.pii.username", + "user.pii.email", + "user.pii.name", + "course.display_name", + "course.start", + "course.end", + ], + }, + } + +Top-level keys +~~~~~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Key + - Description + * - ``events`` + - Event bus signals available for requirements and penalties. Only events whose payload includes learner PII (``UserData``) are applicable. See `openedx-events`_ for the public event definitions used by Open edX. + * - ``credly`` + - Credly provider URLs and sandbox toggle (see below). + * - ``accredible`` + - Accredible provider URLs and sandbox toggle (see below). + * - ``rules.ignored_keypaths`` + - Event payload paths excluded from data rule options in the admin UI (see :ref:`badges-configuration`). + +Credly Settings +~~~~~~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :widths: 35 65 + + * - Setting + - Description + * - ``USE_SANDBOX`` + - Use Credly sandbox environment for development and testing. + * - ``CREDLY_BASE_URL`` + - Credly production host URL. + * - ``CREDLY_API_BASE_URL`` + - Credly production API URL. + * - ``CREDLY_SANDBOX_BASE_URL`` + - Credly sandbox host URL. + * - ``CREDLY_SANDBOX_API_BASE_URL`` + - Credly sandbox API URL. + +Accredible Settings +~~~~~~~~~~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :widths: 35 65 + + * - Setting + - Description + * - ``USE_SANDBOX`` + - Use Accredible sandbox environment for development and testing. + * - ``ACCREDIBLE_BASE_URL`` + - Accredible production host URL. + * - ``ACCREDIBLE_API_BASE_URL`` + - Accredible production API URL. + * - ``ACCREDIBLE_SANDBOX_BASE_URL`` + - Accredible sandbox host URL. + * - ``ACCREDIBLE_SANDBOX_API_BASE_URL`` + - Accredible sandbox API URL. + + +.. _badges-event-bus-configuration: + +Event Bus Configuration +----------------------- + +As noted above, the `tutor-contrib-badges`_ plugin handles this configuration automatically. + +All badge-related events use the ``learning-badges-lifecycle`` topic. + +Source Signals (LMS) +~~~~~~~~~~~~~~~~~~~~ + +By default, badge processing is configured to use these two LMS signals. + +.. list-table:: + :header-rows: 1 + :widths: 55 45 + + * - Signal + - Purpose + * - ``org.openedx.learning.course.passing.status.updated.v1`` + - Course grade updated - enables course completion recognition. + * - ``org.openedx.learning.ccx.course.passing.status.updated.v1`` + - CCX course grade updated - enables CCX course completion recognition. + +.. code-block:: python + + # openedx-platform (LMS) settings: + EVENT_BUS_PRODUCER_CONFIG = { + ... + "org.openedx.learning.course.passing.status.updated.v1": { + "learning-badges-lifecycle": { + "event_key_field": "course_passing_status.course.course_key", + "enabled": _should_send_learning_badge_events, + }, + }, + "org.openedx.learning.ccx.course.passing.status.updated.v1": { + "learning-badges-lifecycle": { + "event_key_field": "course_passing_status.course.ccx_course_key", + "enabled": _should_send_learning_badge_events, + }, + }, + } + +Emitted Signals (Credentials) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The Credentials service emits two signals after badge processing completes. + +.. list-table:: + :header-rows: 1 + :widths: 55 45 + + * - Signal + - Purpose + * - ``org.openedx.learning.badge.awarded.v1`` + - A badge was awarded to a learner. + * - ``org.openedx.learning.badge.revoked.v1`` + - A badge was revoked from a learner. + +.. code-block:: python + + # Credentials service settings: + EVENT_BUS_PRODUCER_CONFIG = { + ... + "org.openedx.learning.badge.awarded.v1": { + "learning-badges-lifecycle": { + "event_key_field": "badge.uuid", + "enabled": BADGES_ENABLED, + }, + }, + "org.openedx.learning.badge.revoked.v1": { + "learning-badges-lifecycle": { + "event_key_field": "badge.uuid", + "enabled": BADGES_ENABLED, + }, + }, + } + +These signals are only produced when ``BADGES_ENABLED`` is ``True``. + +.. _badges-consumer-setup: + +Consumer Setup +~~~~~~~~~~~~~~ + +The consumer implementation depends on your event bus backend (Redis Streams, Kafka, etc.). + +Both the Credentials and LMS services **produce** messages to the event stream. A separate **consumer** process pulls and handles those messages. + +**Redis Streams** - uses the event-bus-redis_ package, which provides a Django management command. + +.. code-block:: bash + + # Run in the Credentials service (required for badge processing): + ./manage.py consume_events \ + -t learning-badges-lifecycle \ + -g credentials_dev \ + --extra='{"consumer_name": "credentials_dev.consumer1"}' + + # Run in the openedx-platform (LMS) (optional - only if LMS needs badge award/revoke notifications): + ./manage.py lms consume_events \ + -t learning-badges-lifecycle \ + -g lms_dev \ + --extra='{"consumer_name": "lms_dev.consumer1"}' + +.. important:: + + The **Credentials consumer** must be running for badges to work. The **LMS consumer** is optional and only needed if LMS should react to badge award or revocation signals. + + +.. _openedx-events: https://github.com/openedx/openedx-events +.. _event-bus-redis: https://github.com/openedx/event-bus-redis diff --git a/docs/sharing/index.rst b/docs/sharing/index.rst new file mode 100644 index 000000000..ad33ade6b --- /dev/null +++ b/docs/sharing/index.rst @@ -0,0 +1,53 @@ +Credential Sharing +################## + +Open edX Credentials service supports multiple ways to share and +recognize learner achievements beyond traditional certificates. +Learners and institutions can distribute verified credentials to +third-party platforms, professional networks, and digital wallets. + +This section covers two sharing mechanisms. + +- **Digital Badges** - issue digital badges through providers like + `Credly `_ and + `Accredible `_. Badges recognize + specific achievements like course completions or skill milestones + and can be displayed on LinkedIn, personal websites, and other + platforms. +- **Verifiable Credentials** - issue W3C-compliant verifiable + credentials that learners store in digital wallets. These + credentials are cryptographically signed and independently + verifiable without contacting the issuer. + +Architecture +************ + +Three roles interact with the credential sharing system: **Site Admins** +configure badge templates and VC issuing, **Learners** complete courses and +earn credentials, and **Verifiers** (employers, institutions) check credential +revocation status. Credentials flow to external Digital Wallets and Digital +Badge Platforms. + +.. figure:: ../_static/images/sharing/credential_sharing_system_context.png + :alt: System context for credential sharing. Site admins configure credentials in Open edX Credentials, learners earn credentials through Open edX, verifiers check revocation status, and credentials flow to external digital wallets and badge platforms. + +The system context diagram shows which actors stay inside Open edX and which interactions cross into external wallet and badge-provider systems. + +Inside the platform, the Open edX Platform (LMS) publishes certificate and +course-passing events to the Event Bus. The Credentials service consumes these +events, stores achievement data in its database, issues and revokes badges on +external platforms via REST API, and sends signed verifiable credentials to +learner wallets. + +.. figure:: ../_static/images/sharing/credential_sharing_containers.png + :alt: Container view of credential sharing. The LMS publishes events to the event bus, the Credentials service consumes them, stores data in MySQL, issues badges to external platforms, and sends verifiable credentials to learner wallets. + +The container diagram shows the event-driven path from course activity in the LMS to credential issuance in the Credentials service. + +Start with the Quick Start guide in each section for step-by-step setup instructions. + +.. toctree:: + :maxdepth: 1 + + badges/index + verifiable_credentials/overview diff --git a/docs/verifiable_credentials/_puml/verifiable_credentials-issuance-sequence.puml b/docs/sharing/verifiable_credentials/_puml/verifiable_credentials-issuance-sequence.puml similarity index 100% rename from docs/verifiable_credentials/_puml/verifiable_credentials-issuance-sequence.puml rename to docs/sharing/verifiable_credentials/_puml/verifiable_credentials-issuance-sequence.puml diff --git a/docs/sharing/verifiable_credentials/api_reference.rst b/docs/sharing/verifiable_credentials/api_reference.rst new file mode 100644 index 000000000..56db383c7 --- /dev/null +++ b/docs/sharing/verifiable_credentials/api_reference.rst @@ -0,0 +1,169 @@ +.. _vc-api-reference: + +API Reference +============= + +.. Maintainership note: + Consider replacing this manually maintained page with autogenerated API documentation in a follow-up PR. + If you do that, update ``docs/credentials_api.rst`` at the same time so credential API references stay consistent. + +All endpoints are prefixed with ``/verifiable_credentials/api/v1/``. + +.. _vc-api-credentials-list: + +GET /credentials/ +----------------- + +List all credentials issued to the authenticated user. Supports filtering by credential type. + +**Authentication:** JWT or Session (required) + +**Query parameters:** + +.. list-table:: + :header-rows: 1 + :widths: 20 15 65 + + * - Parameter + - Type + - Description + * - ``types`` + - string + - Comma-separated credential types to filter. Valid values: ``programcertificate``, ``coursecertificate``. + Omit to return all types. + +**Example request:** + +.. code-block:: sh + + GET /verifiable_credentials/api/v1/credentials/?types=coursecertificate,programcertificate + +**Example response:** + +.. code-block:: json + + { + "program_credentials": [ + { + "uuid": "4a665745d1ba4dfd8f54b58e822b6585", + "status": "awarded", + "username": "staff", + "credential_id": 1, + "credential_uuid": "525756b010aa4c788881141acca72538", + "credential_title": "Title of a program", + "credential_org": "", + "modified_date": "2024-12-18" + } + ], + "course_credentials": [ + { + "uuid": "5135e99ef1d14bca9135972270ef887b", + "status": "awarded", + "username": "staff", + "credential_id": 1, + "credential_uuid": "course-v1:rg+program_course+2024", + "credential_title": "Course cert configuration", + "credential_org": "rg", + "modified_date": "2024-12-18" + } + ] + } + +.. _vc-api-credentials-init: + +POST /credentials/init/ +----------------------- + +Initialize a verifiable credential issuance. Creates an ``IssuanceLine`` and returns a deeplink and QR code for the +learner to complete the flow with their wallet app. + +**Authentication:** JWT or Session (required) + +**Request body:** + +.. list-table:: + :header-rows: 1 + :widths: 25 15 60 + + * - Field + - Type + - Description + * - ``credential_uuid`` + - string (UUID) + - The ``UserCredential`` UUID to issue a VC for. Required. + * - ``storage_id`` + - string + - The storage backend (wallet) identifier. Required. + +**Example response:** + +.. code-block:: json + + { + "deeplink": "dccrequest://request?issuer=did:key:z6Mk...&vc_request_url=...&auth_type=bearer&challenge=...&vp_version=1.1", + "qrcode": "", + "app_link_android": "https://play.google.com/store/apps/details?id=...", + "app_link_ios": "https://apps.apple.com/app/..." + } + +The response includes ``app_link_android`` and ``app_link_ios`` for mobile storage backends, or ``"redirect": true`` +for web-based storage backends. + +.. _vc-api-credentials-issue: + +POST /credentials/issue// +------------------------------- + +Issue a verifiable credential for the given ``IssuanceLine``. The wallet app calls this endpoint after receiving the +deeplink. + +**Authentication:** JWT or Session, **or** a Verifiable Presentation (VP) with ``proofPurpose: "authentication"`` +and a ``challenge`` matching the ``IssuanceLine`` UUID. + +**Returns:** A signed verifiable credential (``201 Created``). + +.. _vc-api-storages: + +GET /storages/ +-------------- + +List all available storage backends (digital wallets). + +**Authentication:** JWT or Session (required) + +**Example response:** + +.. code-block:: json + + [ + { + "id": "credentials.apps.verifiable_credentials.storages.learner_credential_wallet.LCWallet", + "name": "Learner Credential Wallet" + } + ] + +.. _vc-api-status-list: + +GET /status-list/2021/v1// +------------------------------------- + +Retrieve the Status List 2021 credential for a given issuer. Relying parties use this endpoint to verify whether a +credential has been revoked. + +**Authentication:** None (public endpoint, ``AllowAny``). + +**Path parameters:** + +.. list-table:: + :header-rows: 1 + :widths: 20 15 65 + + * - Parameter + - Type + - Description + * - ``issuer_id`` + - string + - The issuer's decentralized identifier (DID), e.g. ``did:key:z6Mk...`` + +**Returns:** A signed Status List 2021 verifiable credential. See :ref:`vc-status-list-api` for the full response +structure. diff --git a/docs/sharing/verifiable_credentials/components.rst b/docs/sharing/verifiable_credentials/components.rst new file mode 100644 index 000000000..4fb57ee7b --- /dev/null +++ b/docs/sharing/verifiable_credentials/components.rst @@ -0,0 +1,214 @@ +.. _vc-components: + +Components +========== + +This page explains the main Open edX components involved in verifiable credential issuance, delivery, and verification. + +The diagram below provides a C4 component view of how the verifiable credentials feature fits into the broader Credentials service and learner-facing flow. + +.. figure:: ../../_static/images/sharing/credential_sharing_components.png + :alt: Component view of the Credentials service showing the credentials core, digital badges issuer, verifiable credentials issuer, and learner record MFE. + +The Verifiable Credentials feature includes the following parts: + +- **Verifiable Credentials application** (``credentials.apps.verifiable_credentials`` within the Open edX Credentials IDA); +- **Learner Record MFE** (``frontend-app-learner-record`` micro-frontend); +- third-party plugins (see :ref:`vc-extensibility`); +- digital wallets (see :ref:`vc-storages-page`). + +.. _vc-application: + +Verifiable Credentials application +---------------------------------- + +The core backend logic and all related APIs are encapsulated in the `Verifiable Credentials application`_. + +Once the Verifiable Credentials feature :ref:`is enabled `, the Credentials IDA exposes additional functionality: + +1. The **Verifiable Credentials** section appears in the Django admin. +2. Verifiable credentials URLs are added to the service. +3. Verifiable credentials API endpoints become available. See :ref:`vc-api-reference`. + +.. _vc-administration-site: + +Administration site +~~~~~~~~~~~~~~~~~~~ + +In the Django admin, the **Verifiable Credentials** section includes these main pages: + +- **Issuance Configurations** at ``https:///admin/verifiable_credentials/issuanceconfiguration/`` for managing issuer records. +- **Issuance Lines** at ``https:///admin/verifiable_credentials/issuanceline/`` for reviewing individual verifiable credential issuance requests. + +.. figure:: ../../_static/images/verifiable_credentials-admin-section.png + :alt: Credentials admin section highlighting where you manage verifiable credential settings in Django admin. + +Issuance Configuration + An issuance configuration describes an Issuer - the Organization/University/School + on behalf of which verifiable credentials are created. The Issuer's ID is embedded + in each verifiable credential, and a cryptographic proof is generated using the + Issuer's private key. Each Issuer has a display name and can be deactivated via + its checkbox. Only a single Issuer configuration can be active at a time. + +.. figure:: ../../_static/images/verifiable_credentials-issuer-configuration.png + :alt: Issuer configuration form in Django admin, showing the active verifiable credential issuer record and its editable settings. + +.. note:: + The private key is a secret generated using cryptographic software. + The Issuer ID must be a `decentralized identifier`_ derived from that private key. + +Issuance Line + Each request for a verifiable credential initiates a separate Issuance Line. + It tracks the verifiable credential processing lifecycle and maintains a link + to the source Open edX user achievement. + +.. figure:: ../../_static/images/verifiable_credentials-issuance-lines.png + :alt: Issuance line records in Django admin, showing each verifiable credential request and its processing state. + +Each issuance line has a unique identifier `UUID` and includes the following information: + +1. **User Credential** - related Open edX achievement (e.g. "Program Certificate" or "Course Certificate") +2. **Issuer ID** - issuer which signs this verifiable credential +3. **Storage ID** - a storage backend (digital wallet) which will keep a verifiable credential +4. **Processing status** - if a verifiable credential was successfully uploaded to storage +5. **Status list info** - indicates if a verifiable credential is still valid and unique status index within an Issuer's status list + +Additionally every issuance line stores the following fields for debug purposes: + +- **Subject ID** - verifiable credential subject DID +- **Data model ID** - verifiable credential specification to use +- **Expiration date** - optional expiration timestamp for the verifiable credential + +.. _vc-status-list-api: + +Status List API +~~~~~~~~~~~~~~~ + +There are several reasons a verifiable credential may already be invalid, inactive, or disposed: + +- revocation +- implicit expiration +- other status changes + +Open edX maintains status for internal credentials ("awarded", "revoked"). + +The public Status List API allows instant verifiable credential checks. This endpoint +is intentionally public (unauthenticated) so that relying parties can verify credential +status without credentials of their own. Each issuer maintains its own status sequence, +and every issued verifiable credential occupies a unique position in that sequence. For +more details, see :ref:`vc-status-list-api`, :ref:`vc-tech-details`, and the +:ref:`generate_status_list management command `. + +.. code-block:: sh + + # Status List API endpoint: + GET https:///verifiable_credentials/api/v1/status-list/2021/v1// + + # Example: + https://credentials.example.com/verifiable_credentials/api/v1/status-list/2021/v1/did:key:z6MkkePoGJV8CQJJULSHHUEv71okD9PsrqXnZpNQuoUfb3id/ + +Each verifiable credential includes the information needed to locate the issuer's +Status List API endpoint and identify the credential's exact position in that issuer's +status sequence. For privacy implications of the Status List 2021 approach, see +`Privacy Considerations`_. + +Status List example +................... + +Status List itself is a verifiable credential. But it serves a different purpose. + +.. code-block:: sh + + # specific Issuer's status list: + + { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://w3id.org/security/suites/ed25519-2020/v1", + "https://w3id.org/vc/status-list/2021/v1" + ], + "id": "https://credentials.example.com/verifiable_credentials/api/v1/status-list/2021/v1/did:key:z6MkkePoGJV8CQJJULSHHUEv71okD9PsrqXnZpNQuoUfb3id/", + "type": [ + "VerifiableCredential", + "StatusList2021Credential" + ], + "credentialSubject": { + "id": "https://credentials.example.com/verifiable_credentials/api/v1/status-list/2021/v1/did:key:z6MkkePoGJV8CQJJULSHHUEv71okD9PsrqXnZpNQuoUfb3id/#list", + "type": "StatusList2021", + "encodedList": "H4sIAJzSq2QC/+3BAQ0AAADCoPdPbQ43oAAAAAAAAAAAAODfAC7KO00QJwAA", + "statusPurpose": "revocation" + }, + "issuer": { + "id": "did:key:z6MkkePoGJV8CQJJULSHHUEv71okD9PsrqXnZpNQuoUfb3id" + }, + "issuanceDate": "2023-05-16T20:33:39Z", + "proof": { + "type": "Ed25519Signature2020", + "proofPurpose": "assertionMethod", + "proofValue": "z2qgpEUHecAxtRNuRXqPavaLwq2cfTzLSykFa8FPEVxvuPxBkfHdqo17XTpA2q9wR7CYwBjsfDBXT2amXAZbRqdPz", + "verificationMethod": "did:key:z6MkkePoGJV8CQJJULSHHUEv71okD9PsrqXnZpNQuoUfb3id#z6MkkePoGJV8CQJJULSHHUEv71okD9PsrqXnZpNQuoUfb3id", + "created": "2023-07-10T09:42:52.259Z" + }, + "issued": "2023-05-16T20:33:39Z", + "validFrom": "2023-05-16T20:33:39Z" + } + +Status Entry example +.................... + +Every verifiable credential carries its status list "registration" info. + +.. code-block:: sh + + # specific verifiable credential status section: + + "credentialStatus": { + "id": "https://credentials.example.com/verifiable_credentials/api/v1/status-list/2021/v1/did:key:z6MkkePoGJV8CQJJULSHHUEv71okD9PsrqXnZpNQuoUfb3id/#15", + "type": "StatusList2021Entry", + "statusListCredential": "https://credentials.example.com/verifiable_credentials/api/v1/status-list/2021/v1/did:key:z6MkkePoGJV8CQJJULSHHUEv71okD9PsrqXnZpNQuoUfb3id/", + "statusPurpose": "revocation", + "statusListIndex": "15" + }, + +For debugging and verification, see the :ref:`generate_status_list management command `. + +.. _vc-learner-record-mfe: + +Learner Record Microfrontend +---------------------------- + +The Verifiable Credentials feature extends the `Learner Record MFE`_ with additional +UI. An extra "Verifiable Credentials" page (tab) becomes available. + +.. figure:: ../../_static/images/verifiable_credentials-learner-record-mfe.png + :alt: Learner Record page with the Verifiable Credentials tab, listed achievements, and create actions for requesting a credential. + +The numbered markers on the screenshot correspond to UI elements: + +1. **Verifiable Credentials tab** - appears once the feature :ref:`is enabled `. +2. **Credential list** - all learner's Open edX credentials (both course and program certificates). +3. **Create action** - lets the learner request a verifiable credential for the corresponding achievement. +4. **Storage options** (experimental). + +.. note:: + Currently, a single (built-in) storage backend is available out of the box + (`Learner Credential Wallet`_). Because only one storage option exists by + default, the "Create" button does not show a dropdown. Additional storages + appear under a "Create with" dropdown automatically once configured. + +.. seealso:: + + :ref:`vc-managing` + Managing issuers, issuance lines, and revocation behavior. + + :ref:`vc-configuration` + Feature flags, issuer settings, and management commands. + + :ref:`vc-tech-details` + Internal implementation details for debugging and customization. + +.. _Verifiable Credentials application: https://github.com/openedx/credentials/tree/master/credentials/apps/verifiable_credentials +.. _Learner Record MFE: https://github.com/openedx/frontend-app-learner-record +.. _decentralized identifier: https://en.wikipedia.org/wiki/Decentralized_identifier +.. _Learner Credential Wallet: https://lcw.app/ +.. _Privacy Considerations: https://www.w3.org/community/reports/credentials/CG-FINAL-vc-status-list-2021-20230102/#privacy-considerations diff --git a/docs/sharing/verifiable_credentials/composition.rst b/docs/sharing/verifiable_credentials/composition.rst new file mode 100644 index 000000000..7cfca8cc0 --- /dev/null +++ b/docs/sharing/verifiable_credentials/composition.rst @@ -0,0 +1,193 @@ +.. _vc-credential-composition: + +Credential Composition +====================== + +Each verifiable credential is assembled from an ``IssuanceLine`` record and +its related ``UserCredential``. The composition process maps Open edX data +into the structure required by the chosen :ref:`data model `. + +Common fields +------------- + +All data models share these root-level fields: + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Field + - Source + * - ``id`` + - ``urn:uuid:{IssuanceLine.uuid}`` + * - ``issuer.id`` + - Active ``IssuanceConfiguration`` DID + * - ``issuer.name`` + - Active ``IssuanceConfiguration`` name + * - ``issuanceDate`` / ``issued`` / ``validFrom`` + - ``IssuanceLine.modified`` timestamp + * - ``validUntil`` + - ``IssuanceLine.expiration_date`` (optional) + * - ``credentialStatus`` + - Status List 2021 entry (see :ref:`vc-status-list-api`) + * - ``credentialSubject.id`` + - Subject DID provided by the wallet during issuance + +Subject DID +----------- + +The ``credentialSubject.id`` (the learner's decentralized identifier) is not +generated by Open edX. It is provided by the wallet application during the +issuance request. When the wallet POSTs to the issuance endpoint, the +storage backend's request serializer extracts and validates the subject DID, +then stores it on the ``IssuanceLine``. + +Achievement text generation +--------------------------- + +The ``IssuanceLine`` model builds human-readable text from the underlying +Open edX credential. Three text fields are generated: **name**, +**description**, and **narrative**. Each uses template variables resolved +from the database at issuance time. + +Template variables +~~~~~~~~~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :widths: 22 48 30 + + * - Variable + - Source + - Fallback + * - ``credential_type`` + - Mapped from credential class: ``"program certificate"`` or + ``"course certificate"`` + - -- + * - ``program_title`` + - ``Program.title`` + - ``""`` + * - ``course_title`` + - ``Course.title`` (looked up via ``course_id``) + - ``""`` + * - ``organizations`` + - ``Program.authoring_organizations`` names, comma-joined + - ``""`` + * - ``organization`` + - ``course_key.org`` from the course credential + - ``""`` + * - ``platform_name`` + - ``Site.siteconfiguration.platform_name`` + - ``""`` + * - ``recipient_name`` + - ``User.full_name`` (by ``UserCredential.username``) + - ``"recipient"`` + * - ``course_count`` + - ``Program.course_runs.count()`` + - ``0`` + * - ``hours_of_effort`` + - ``Program.total_hours_of_effort`` + - omitted if not set + +Course credential templates +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Name:** the course's configured title; if absent: ``"Course certificate"``. + +**Description:** + +.. code-block:: text + + {credential_type} is granted on course {course_title} completion + offered by {organization}, in collaboration with {platform_name} + +**Narrative** (placed into the achievement ``criteria`` field): + +.. code-block:: text + + {recipient_name} successfully completed a course and received + a passing grade for a Course Certificate in {course_title} + a course offered by {organization}, in collaboration with + {platform_name}. + +Program credential templates +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Name:** the program's configured title; if absent, generated as: + +.. code-block:: text + + Program certificate for passing a program {program_title} + +**Description:** + +.. code-block:: text + + {credential_type} is granted on program {program_title} completion + offered by {organizations}, in collaboration with {platform_name}. + The {program_title} program includes {course_count} course(s). + +If ``total_hours_of_effort`` is set, the description appends: + +.. code-block:: text + + , with total {hours_of_effort} Hours of effort required to complete it + +**Narrative** (placed into the achievement ``criteria`` field): + +.. code-block:: text + + {recipient_name} successfully completed all courses and received + passing grades for a Professional Certificate in {program_title} + a program offered by {organizations}, in collaboration with + {platform_name}. + +Data model differences +---------------------- + +.. list-table:: + :header-rows: 1 + :widths: 25 38 37 + + * - Aspect + - Open Badges v3.0 + - VC Data Model v1.1 + * - Extra context + - ``purl.imsglobal.org/.../ob/v3p0`` + - ``schema.org`` + * - Credential type + - ``OpenBadgeCredential`` + - ``EducationalOccupationalCredential`` + * - Subject type + - ``AchievementSubject`` + - (schema.org structures) + * - Achievement + - Nested ``achievement`` object with ``criteria.narrative`` + - ``hasCredential`` relationship + * - Top-level ``name`` + - Yes (credential name) + - No + +Open Badges v3.0.1 extends v3.0 with minor context additions but uses the +same structure. + +Status index assignment +----------------------- + +Each ``IssuanceLine`` receives a monotonically increasing ``status_index`` +scoped to its issuer. The index starts at 0 and increments with each new +issuance. This index determines the credential's position in the issuer's +Status List bitstring. When a credential is revoked, the bit at that index +is flipped to 1 and the Status List is regenerated (gzip-compressed, then +base64url-encoded). + +.. seealso:: + + :ref:`vc-data-models` + Available data model specifications and how to extend them. + + `Open Badges Specification v3.0 `_ + The default data model specification. + + `W3C Verifiable Credentials Data Model v1.1 `_ + The base specification for verifiable credential structure. diff --git a/docs/sharing/verifiable_credentials/configuration.rst b/docs/sharing/verifiable_credentials/configuration.rst new file mode 100644 index 000000000..d867773ad --- /dev/null +++ b/docs/sharing/verifiable_credentials/configuration.rst @@ -0,0 +1,218 @@ +.. _vc-configuration: + +Configuration +============= + +The Verifiable Credentials feature is optional. It is disabled by default. + +.. note:: + + If you are using Tutor, start with :ref:`vc-quickstart` for installation and setup. The quick start covers the ``tutor-credentials`` and ``tutor-contrib-badges`` plugins, feature flags, and the initial issuer setup flow. + + Use this page for manual configuration, overrides, and detailed settings reference. + +.. _vc-activation: + +Conditional activation +---------------------- + +The ``verifiable_credentials`` app is always in ``INSTALLED_APPS``, but its URL routes, signals, and system checks +only activate when ``ENABLE_VERIFIABLE_CREDENTIALS`` is set to ``True``. After changing this setting, restart the +Credentials service for the change to take effect. + +Learner Record MFE settings +--------------------------- + +The `Learner Record MFE `_ uses environment variables configured in its ``.env`` file. + +.. note:: + + In Tutor deployments, the Learner Record MFE is typically provided by the ``tutor-mfe`` plugin, and the Credentials service is provided by the ``tutor-credentials`` plugin. + If you are using ``tutor-contrib-badges``, it configures the required verifiable credentials feature flags automatically as part of the setup described in :ref:`vc-quickstart`. + +``ENABLE_VERIFIABLE_CREDENTIALS`` - enables the verifiable credentials UI routes. + +``SUPPORT_URL_VERIFIABLE_CREDENTIALS`` - footer support link on verifiable credentials pages. + +Credentials service settings +----------------------------- + +``ENABLE_VERIFIABLE_CREDENTIALS`` (boolean) - main feature flag for the backend. + +The feature introduces its own set of default settings, namespaced under the +``VERIFIABLE_CREDENTIALS`` setting: + +.. code-block:: python + + VERIFIABLE_CREDENTIALS = { + 'DEFAULT_DATA_MODELS': [ + "credentials.apps.verifiable_credentials.composition.open_badges.OpenBadgesDataModel", + ], + "STATUS_LIST_LENGTH": 50000, + "DEFAULT_ISSUER": { + "NAME": "The University of the Digital Future", + "KEY": '{"kty":"OKP","crv":"Ed25519","x":"IGUT8E_aRNzLqouWO4zdeZ6l4CEXsVmJDOpOQS69m7o","d":"vn8xgdO5Ki3zlvRNc2nUqcj50Ise1Vl1tlbs9DUL"}', + "ID": "did:key:z6MkgdiV7pVPCapM8oUwfhxBwYZgh8dXkHkJykSAc4DHKD7X", + }, + } + +This configuration overrides the corresponding built-in settings: + +1. Data models list narrowed down to a single specification. +2. Status list length extended to 50K positions. +3. Default issuer configured with concrete credentials. + +Default settings +---------------- + +All settings are defined under the ``VERIFIABLE_CREDENTIALS`` dictionary +(see ``verifiable_credentials/settings.py`` for source). + +.. list-table:: + :header-rows: 1 + :widths: 30 70 + + * - Setting + - Description / Default + * - ``DEFAULT_DATA_MODELS`` + - Dotted paths to :ref:`data model ` classes. At least one must be available, and every configured storage must reference an available data model. + + **Default:** ``["credentials.apps.verifiable_credentials.composition.verifiable_credentials.VerifiableCredentialsDataModel", "credentials.apps.verifiable_credentials.composition.open_badges.OpenBadgesDataModel"]`` + * - ``DEFAULT_STORAGES`` + - Dotted paths to :ref:`storage ` classes. At least one must be available. + + **Default:** ``["credentials.apps.verifiable_credentials.storages.learner_credential_wallet.LCWallet"]`` + * - ``STATUS_LIST_LENGTH`` + - Per-issuer credential cap. Each issuer has a monotonically increasing status index capped by this value (``unique_together`` constraint). Increase it or create additional issuers to issue more credentials. For details see the `Status List 2021 specification `_. + + **Default:** ``10000`` (16 KB) + * - ``STATUS_LIST_STORAGE`` + - Storage class for the status list implementation. + + **Default:** ``"credentials.apps.verifiable_credentials.storages.status_list.StatusList2021"`` + * - ``STATUS_LIST_DATA_MODEL`` + - Data model class for the status list implementation. + + **Default:** ``"credentials.apps.verifiable_credentials.composition.status_list.StatusListDataModel"`` + * - ``DEFAULT_ISSUANCE_REQUEST_SERIALIZER`` + - Serializer for incoming issuance requests. + + **Default:** ``"credentials.apps.verifiable_credentials.issuance.serializers.IssuanceLineSerializer"`` + * - ``DEFAULT_RENDERER`` + - Renderer for outgoing verifiable credential responses. + + **Default:** ``"credentials.apps.verifiable_credentials.issuance.renderers.JSONLDRenderer"`` + +DEFAULT_ISSUER +~~~~~~~~~~~~~~ + +Issuer identity used during the first deployment data migration. +Multiple ``IssuanceConfiguration`` records can exist in the database, but +only the last enabled record is the active issuer for all verifiable +credentials. + +.. important:: + The admin interface prevents disabling the last enabled configuration. + Use ``remove_issuance_configuration`` to delete one entirely. + +.. list-table:: + :header-rows: 1 + :widths: 20 80 + + * - Key + - Description / Default + * - ``NAME`` + - Verbose issuer name embedded in each verifiable credential. + + **Default:** ``"Default (system-wide)"`` + * - ``KEY`` + - Private JWK used for signing. Use your own key or generate one with the ``generate_issuer_credentials`` command below. + + **Default:** placeholder (must be replaced) + * - ``ID`` + - Decentralized Identifier (DID) derived from the private key. + + **Default:** placeholder (must be replaced) + +.. _vc-management-commands: + +Management commands +------------------- + +All commands below run in the **Credentials service**. + +.. _vc-issuer-credentials-helper: + +``generate_issuer_credentials`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Generates a new private key (JWK) and a decentralized identifier (DID) for an +issuer. + +.. code-block:: sh + + ./manage.py generate_issuer_credentials + +Use the generated values as follows: + +- Set **Issuer id** to the generated ``did`` value. +- Set **Issuer key** to the generated ``private_key`` value. + +.. warning:: + + Treat ``private_key`` as a secret. Store it securely, do not commit it to version control, and do not expose it in logs or screenshots. + +``create_default_issuer`` +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Creates an Issuance Configuration from ``VERIFIABLE_CREDENTIALS[DEFAULT_ISSUER]`` +settings at ``https:///admin/verifiable_credentials/issuanceconfiguration/``. +A default configuration is created automatically during the first +deployment via data migration. Use this command to re-create it if needed. + +This command creates a new issuer configuration record from the current ``DEFAULT_ISSUER`` settings. + +.. code-block:: sh + + ./manage.py create_default_issuer + +``remove_issuance_configuration`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Removes an issuer configuration by its DID. The admin interface only allows +deactivation, not deletion. + +This command permanently deletes the matching ``IssuanceConfiguration`` record. + +.. code-block:: sh + + ./manage.py remove_issuance_configuration did:key: + +.. _vc-status-list-helper: + +``generate_status_list`` +~~~~~~~~~~~~~~~~~~~~~~~~ + +Generates a signed Status List 2021 credential for a given issuer. Useful for +debugging revocation status or verifying the status list is correctly formed. + +This command prints the signed Status List 2021 credential for the specified issuer. + +.. code-block:: sh + + ./manage.py generate_status_list did:key: + +.. seealso:: + + :ref:`vc-quickstart` + Step-by-step setup including issuer credential generation (step 2) and configuration (step 3). + + `W3C Verifiable Credentials Data Model v1.1 `_ + The specification that defines the verifiable credential structure and lifecycle. + + `W3C Decentralized Identifiers (DIDs) v1.0 `_ + The specification for issuer and holder identifiers. + + `Status List 2021 `_ + The specification for credential revocation tracking. + diff --git a/docs/sharing/verifiable_credentials/extensibility.rst b/docs/sharing/verifiable_credentials/extensibility.rst new file mode 100644 index 000000000..7af1b7b15 --- /dev/null +++ b/docs/sharing/verifiable_credentials/extensibility.rst @@ -0,0 +1,78 @@ +.. _vc-extensibility: + +Extensibility +============= + +Both :ref:`data models ` and :ref:`storages ` may be implemented as installable pluggable applications for the Credentials IDA. + +.. _vc-storages: + +Storages +-------- + +Storage backend classes describe a destination for issued verifiable credentials. +Storages represent wallet integrations (mobile or web applications). + +See available options on the :ref:`Storages page `. + +.. note:: + + For a storage plugin example intended for development purposes, see the `openedx-wallet`_ dummy internal storage (by `Raccoon Gang`_). + +.. _vc-data-models: + +Data Models +----------- + +Data model classes are `DRF`_ serializers that compose verifiable credentials +according to different specifications. + +Credentials data models +~~~~~~~~~~~~~~~~~~~~~~~ + +There are 3 specifications included by default: + +- `Open Badges Specification v3.0`_ (see `OB3.0 model`_) +- `Open Badges Specification v3.0.1`_ (see `OB3.0.1 model`_) +- `Verifiable Credentials Data Model v1.1`_ (see `VC1.1 model`_) - experimental + +Additional specifications may be implemented as separate plugins. + +Credentials status information +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:ref:`Status List v2021 ` is a special kind of verifiable +credential. It serves as a verification mechanism for issued verifiable +credentials (meaning, it does not carry achievement information itself but +acts as a registry of statuses for all created achievement-related verifiable +credentials). Status information allows instant checks to determine whether +a presented verifiable credential is still valid. The credential issuer can +invalidate a verifiable credential by updating its indexed record in the +status list. + +See full specification in the `Verifiable Credential Status List v2021`_ community report. + + + +.. _Verifiable Credentials Data Model v1.1: https://www.w3.org/TR/vc-data-model-1.1/ +.. _Open Badges Specification v3.0: https://1edtech.github.io/openbadges-specification/ob_v3p0.html +.. _Open Badges Specification v3.0.1: https://www.imsglobal.org/spec/ob/v3p0/impl/ +.. _Verifiable Credential Status List v2021: https://www.w3.org/community/reports/credentials/CG-FINAL-vc-status-list-2021-20230102/ +.. _Raccoon Gang: https://raccoongang.com +.. _Learner Credential Wallet: https://lcw.app +.. _DRF: https://www.django-rest-framework.org/ +.. _VC1.1 model: https://github.com/openedx/credentials/blob/master/credentials/apps/verifiable_credentials/composition/verifiable_credentials.py +.. _OB3.0 model: https://github.com/openedx/credentials/blob/master/credentials/apps/verifiable_credentials/composition/open_badges.py +.. _OB3.0.1 model: https://github.com/openedx/credentials/blob/master/credentials/apps/verifiable_credentials/composition/open_badges.py +.. seealso:: + + `Open Badges Specification v3.0 `_ + The default data model specification for educational achievements. + + `W3C Verifiable Credentials Data Model v1.1 `_ + The base specification for verifiable credential structure. + + `Status List 2021 `_ + The specification for credential revocation tracking via bitstring status lists. + +.. _openedx-wallet: https://github.com/raccoongang/openedx-wallet diff --git a/docs/sharing/verifiable_credentials/managing.rst b/docs/sharing/verifiable_credentials/managing.rst new file mode 100644 index 000000000..14fc4ea87 --- /dev/null +++ b/docs/sharing/verifiable_credentials/managing.rst @@ -0,0 +1,37 @@ +.. _vc-managing: + +Managing Verifiable Credentials +=============================== + +Monitoring issuance lines +------------------------- + +Track issuance activity at ``https:///admin/verifiable_credentials/issuanceline/``. Each record shows the processing status, storage backend, and linked Open edX credential. + +Filter by processing status to identify failed issuances that may need investigation. + +Managing issuers +---------------- + +Multiple ``IssuanceConfiguration`` records can exist at ``https:///admin/verifiable_credentials/issuanceconfiguration/``, but only the last enabled record is the active issuer. + +- To rotate issuer credentials, create a new configuration with updated keys and enable it. +- The admin interface prevents disabling the last enabled configuration. Use the ``remove_issuance_configuration`` management command to delete one entirely. See :ref:`vc-management-commands`. + +Revoking credentials +-------------------- + +When an Open edX credential (course or program certificate) is revoked, all verifiable credentials issued from that achievement are automatically revoked via a Django ``post_save`` signal. The revocation is reflected in the issuer's :ref:`Status List `, allowing relying parties to detect revoked credentials during verification. + +There is no manual revocation interface. Revocation flows from the underlying Open edX credential status. + +.. seealso:: + + :ref:`vc-configuration` + Feature flags, issuer settings, and management commands. + + :ref:`vc-quickstart` + Step-by-step initial setup guide. + + :ref:`vc-tech-details` + Internal implementation details for debugging and customization. diff --git a/docs/sharing/verifiable_credentials/overview.rst b/docs/sharing/verifiable_credentials/overview.rst new file mode 100644 index 000000000..fc62f9f68 --- /dev/null +++ b/docs/sharing/verifiable_credentials/overview.rst @@ -0,0 +1,122 @@ +Verifiable Credentials +====================== + +Traditional certificates (PDFs, images) are easy to forge and hard to verify. +Employers and institutions that receive them must contact the issuing organization +to confirm authenticity - a slow, manual process that doesn't scale. + +`Verifiable Credentials`_ (VCs) solve this problem. A VC is a digitally signed, +tamper-proof data object that any party can verify instantly, without contacting +the issuer. The `W3C Verifiable Credentials Data Model`_ and related +specifications define the standard. + +If you want to install and configure this feature, start with the :ref:`Quick Start ` guide. +If you want to understand the main concepts and architecture first, continue with this overview and the linked reference pages. + +Credentials ecosystem +--------------------- + +Three roles participate in the learner credentials ecosystem. For a broader standards-based description, see the `W3C VC ecosystem overview `_. + +- **Learner** - holds portable, privacy-preserving proof of achievements + in a digital wallet and shares them with employers, institutions, or + professional networks. For supported wallets, see :ref:`vc-storages-page`. +- **Issuer** - creates and signs credentials. The cryptographic signature + ties each credential back to the issuing organization, making + authenticity independently verifiable. For issuer setup, see :ref:`vc-configuration`. +- **Verifier** - validates a credential's signature and revocation status + without contacting the issuer directly, using a public + :ref:`Status List `. + + +Verifiable credentials lifecycle +-------------------------------- + +The W3C VC specification defines a standard lifecycle with three participants: + +- **Issuer** (``did:web:domain.university.org``) - creates and signs + verifiable credentials, can revoke them. +- **Holder** (``did:key:[unique-id]``) - receives, stores, and transfers + VCs. Presents a VC or a Verifiable Presentation (VP) to verifiers. +- **Verifier** - checks the credential's signature and consults a + Verifiable Data Registry (e.g. the issuer's Status List) to confirm the + credential has not been revoked or expired. + +.. figure:: ../../_static/images/sharing/vc_lifecycle.png + :alt: Verifiable credentials lifecycle showing an issuer creating and revoking credentials, holders storing and presenting them, and verifiers checking status through the issuer's public registry. + +This lifecycle highlights the three core phases: issuance to the holder, presentation to a verifier, and independent status checking after issuance. + +Decentralized identifiers (DIDs) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Both issuers and holders are identified by +`Decentralized Identifiers (DIDs) `_. +A DID follows the format ``did:[method]:[unique-uri]``. Common methods include: + +- ``did:key`` - self-contained, no external resolution needed. Used for learner (holder) identifiers. +- ``did:web`` - resolved via the issuer's domain over HTTPS. Used for institutional issuers. +- ``did:ethr`` - resolved via Ethereum blockchain. + +A DID resolves to a **DID Document** containing the public key material needed to verify signatures. For implementation details on how Open edX uses DIDs, see :ref:`vc-tech-details`. + +How It Works in Open edX +------------------------ + +The Verifiable Credentials feature is optional. Once enabled, it extends the +Credentials service and Learner Record micro-frontend. + +Open edX Credentials provides the issuance mechanism: it prepares the credential, +signs it with the configured issuer key, and exposes the APIs needed by the +wallet flow. The issuer itself is the organization or entity represented by the +configured issuer DID and issuer name. + +A single Open edX achievement can be used as a source for multiple verifiable +credentials, each using a different data model if needed. The typical flow +looks like this. + +#. A learner earns an Open edX credential (course or program certificate). +#. The learner visits the Learner Record page and requests a verifiable + credential. The platform generates a deep link or QR code. +#. The learner scans the QR code or follows the deep link to open their + digital wallet app. +#. The digital wallet sends an issuance request back to the platform. The + platform signs the credential using the configured issuer's private key + and returns it to the wallet. +#. The learner can now present the VC to any relying party. +#. The relying party verifies the signature and checks the issuer's public + status list to confirm the credential is still valid (not expired or + revoked). + +See :ref:`vc-components` for the main system components, :ref:`vc-status-list-api` for status verification, and :ref:`vc-storages-page` for wallet behavior and learner flow. + +The feature supports multiple verifiable credential specifications. For supported data formats and their extensibility model, see :ref:`vc-extensibility`. The built-in production wallet integration is LCWallet. For storage details, including the development wallet, see :ref:`vc-storages-page`. + +.. seealso:: + + :ref:`vc-quickstart` + Installation and first-time setup for verifiable credentials. + + `W3C Verifiable Credentials Overview `_ + Standards background for the VC ecosystem, lifecycle, and trust model. + + `W3C Decentralized Identifiers (DID) v1.0 `_ + Core specification for decentralized identifiers and DID documents. + +---- + +.. toctree:: + :maxdepth: 1 + + quickstart + components + configuration + managing + extensibility + composition + storages + tech_details + api_reference + +.. _Verifiable Credentials: https://en.wikipedia.org/wiki/Verifiable_credentials +.. _W3C Verifiable Credentials Data Model: https://www.w3.org/TR/vc-data-model-1.1/ diff --git a/docs/sharing/verifiable_credentials/quickstart.rst b/docs/sharing/verifiable_credentials/quickstart.rst new file mode 100644 index 000000000..3a85d550c --- /dev/null +++ b/docs/sharing/verifiable_credentials/quickstart.rst @@ -0,0 +1,186 @@ +.. _vc-quickstart: + +Quick Start +=========== + +Set up Verifiable Credentials issuing for your Open edX instance. By the end of this guide you will have a working issuance configuration that lets learners receive and store verifiable credentials. + +.. contents:: Steps + :local: + :class: no-bullets + +1. Prerequisites and installation +--------------------------------- + +The Credentials service must be installed and running on your Open edX instance. + +Option A: Using Tutor (recommended) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +#. Install the `tutor-credentials`_ plugin (provides the Credentials service): + + .. code-block:: bash + + pip install tutor-credentials + +#. Install the `tutor-contrib-badges`_ plugin (enables verifiable credentials feature flags, configures the event bus, and sets up certificate synchronization): + + .. code-block:: bash + + pip install git+https://github.com/raccoongang/tutor-contrib-badges@main + + See the `tutor-contrib-badges README `_ for additional details. + +#. Enable the necessary plugins: + + .. code-block:: bash + + tutor plugins enable discovery mfe credentials badges + +#. Rebuild images and launch: + + .. code-block:: bash + + tutor images build openedx discovery credentials + tutor local launch + +The plugin automatically enables ``ENABLE_VERIFIABLE_CREDENTIALS`` for both the Credentials service and Learner Record MFE, and configures event bus consumers for certificate lifecycle events. + +.. _tutor-credentials: https://github.com/overhangio/tutor-credentials +.. _tutor-contrib-badges: https://github.com/raccoongang/tutor-contrib-badges + +Option B: Other installations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +#. Install the Credentials service following the `Getting Started `_ guide. + +#. Enable verifiable credentials in the Credentials service settings: + + .. code-block:: python + + ENABLE_VERIFIABLE_CREDENTIALS = True + +#. Enable verifiable credentials in the Learner Record MFE ``.env`` file: + + .. code-block:: text + + ENABLE_VERIFIABLE_CREDENTIALS=true + +For all available settings, see :ref:`vc-configuration`. + +2. Generate issuer credentials +------------------------------ + +Each issuer_ must have its own decentralized identifier (DID) and private key. +Unless you already have them, generate a new pair by using the management command provided by the Credentials service. + +If you are using Tutor: + +.. code-block:: bash + + tutor local exec credentials ./manage.py generate_issuer_credentials + +For other installations, run the command directly in the Credentials service: + +.. code-block:: bash + + ./manage.py generate_issuer_credentials + +Example output: + +.. code-block:: text + + { + 'did': 'did:key:z6MkgdiV7pVPCapM8oUwfhxBwYZgh8dXkHkJykSAc4DHKD7X', + 'private_key': '{"kty":"OKP","crv":"Ed25519","x":"IGUT8E_aRNzLqouWO4zdeZ6l4CEXsVmJDOpOQS69m7o","d":"vn8xgdO5Ki3zlvRNc2nUqcj50Ise1Vl1tlbs9DUL"}' + } + +.. list-table:: Output fields + :widths: 20 80 + :header-rows: 1 + + * - Field + - Description + * - ``did`` + - Unique issuer decentralized identifier (DID). Used as the **Issuer id** in the admin configuration. + * - ``private_key`` + - Issuer private key in JWK format (stringified JSON). Used as the **Issuer key** in the admin configuration. + +.. warning:: + + Treat the ``private_key`` value as a secret. Store it securely, do not commit it to version control, and do not expose it in logs, screenshots, or shared configuration examples. + +For additional management commands, see :ref:`vc-management-commands`. + +3. Configure issuer credentials +------------------------------- + +Use the generated credentials to replace the stub values in the auto-created +Issuance Configuration. + +#. In the Credentials admin panel, navigate to ``https:///admin/verifiable_credentials/issuanceconfiguration/``. +#. Open the auto-created Issuance Configuration entry. + + .. figure:: ../../_static/images/verifiable_credentials-issuer-configuration.png + :alt: Issuer configuration form in Django admin showing the Issuer id, Issuer key, and Issuer name fields. + + a. Set the **Issuer id** to the generated ``did`` value. + b. Set the **Issuer key** to the generated ``private_key`` value. + c. Set the **Issuer name** to a verbose name for your issuer. + + .. note:: + + The **Issuer key** must be a stringified JSON value, that is, an escaped JSON string rather than a raw JSON object. The ``generate_issuer_credentials`` command outputs it in the correct format. + +#. Make sure the configuration is enabled, then click **Save** at the bottom of the page to save the issuer configuration. + +For full admin panel reference, see :ref:`vc-administration-site`. + +4. Verify status list accessibility +----------------------------------- + +The Status List API endpoint is crucial for the feature. Once everything is +configured correctly, it must be publicly available: + +.. code:: + + # each issuer maintains its own Status List; is the ``did`` value from step 1: + https:///verifiable_credentials/api/v1/status-list/2021/v1// + +For endpoint details and response format, see :ref:`vc-status-list-api`. + +5. Register the issuer for Learner Credential Wallet +---------------------------------------------------- + +The built-in storage backend is the `Learner Credential Wallet `_ (LCWallet), which is a mobile app by the Digital Credentials Consortium. LCWallet only accepts credentials from allow-listed issuers. + +To register your issuer, open a pull request in the `community issuer registry`_ adding your issuer's DID (the ``did`` value from step 1) to ``registry.json``, matching the format of existing entries. Once the registry maintainers merge your PR, LCWallet will accept credentials from your instance. + +For development and testing, use the `Sandbox Registry`_ and submit a PR there with the same format. + +For more information about LCWallet, including learner flow and usage details, see :ref:`vc-storages-page`. + +.. seealso:: + + :ref:`vc-configuration` + Feature flags, issuer settings, and management commands. + + :ref:`vc-management-commands` + Additional commands for issuer and status list management. + + :ref:`vc-administration-site` + Django admin pages for issuer configuration and issuance lines. + + :ref:`vc-status-list-api` + Status List API endpoint details and response examples. + + :ref:`vc-storages-page` + Learner Credential Wallet details, learner flow, and storage behavior. + + :ref:`vc-components` + Components, admin pages, and Status List API details. + +.. _community issuer registry: https://github.com/digitalcredentials/community-registry +.. _Sandbox Registry: https://github.com/digitalcredentials/sandbox-registry + +.. _issuer: https://www.w3.org/TR/vc-data-model-1.1/#dfn-issuers diff --git a/docs/sharing/verifiable_credentials/storages.rst b/docs/sharing/verifiable_credentials/storages.rst new file mode 100644 index 000000000..bf6d76c77 --- /dev/null +++ b/docs/sharing/verifiable_credentials/storages.rst @@ -0,0 +1,202 @@ +.. _vc-storages-page: + +Storages +======== + +The built-in production storage backend is the Learner Credential Wallet (LCWallet). Open edX also includes the ``openedx-wallet`` development wallet for debugging and onboarding. Additional wallets can be added through plugins - see :ref:`vc-extensibility`. + +Learner Credential Wallet +------------------------- + +`Official website`_: + + Learner Credential Wallet is an open source mobile wallet developed by the + Digital Credentials Consortium, a network of leading international + universities designing an open infrastructure for academic credentials. + +Learner Credential Wallet (LCWallet) is a mobile app available for Android +and iOS devices. + +.. _vc-usage-prerequisites: + +Usage prerequisites +~~~~~~~~~~~~~~~~~~~ + +The LCWallet maintainer (`Digital Credentials Consortium`_) requires the +verifiable credentials issuer to be allow-listed (included in the trusted +issuers list - `community issuer registry`_). + +.. note:: + + For development and testing, a `Sandbox Registry`_ is available. To be added to the Sandbox Registry, open a pull request directly against that repository and match the format of existing issuers in ``registry.json``. + +Learner experience +~~~~~~~~~~~~~~~~~~ + +#. Learners download and install the official application (Google Play or App + Store; the Android version is used for examples below). + +#. Once installed, there is an initial one-time setup guide. + + .. image:: ../../_static/images/verifiable_credentials-lcw-setup1.png + :alt: Learner Credential Wallet welcome screen prompting the learner to begin wallet setup. + :width: 30% + .. image:: ../../_static/images/verifiable_credentials-lcw-setup2.png + :alt: Learner Credential Wallet setup screen explaining how credentials are stored and verified in the app. + :width: 30% + .. image:: ../../_static/images/verifiable_credentials-lcw-setup3.png + :alt: Learner Credential Wallet final setup screen confirming the learner can finish onboarding and open the wallet. + :width: 30% + +#. Learners navigate to the Learner Record MFE interface + (:ref:`Verifiable Credentials tab `) and request a + verifiable credential by clicking the :guilabel:`Create` button. + +#. Learners are then asked to scan a QR code - this is where the LCWallet app + starts its flow. Learners use the :guilabel:`Scan QR code` option in the + mobile application. + + .. image:: ../../_static/images/verifiable_credentials-lcw-home-empty.png + :alt: Learner Credential Wallet home screen with no saved credentials yet. + :width: 30% + .. image:: ../../_static/images/verifiable_credentials-lcw-add-credential.png + :alt: Learner Credential Wallet add-credential screen where the learner chooses to scan a QR code. + :width: 30% + .. image:: ../../_static/images/verifiable_credentials-lcw-qrcode-scanner.png + :alt: Wallet QR-code scanner view used to scan the credential issuance link from Open edX. + :width: 30% + +#. LCWallet processes the QR code, communicates with the Open edX platform, + and retrieves the new verifiable credential. If everything is correct, the + digital wallet now holds the verifiable credential for the given Open edX + credential (course or program certificate). + + .. image:: ../../_static/images/verifiable_credentials-lcw-accept-credential.png + :alt: Learner Credential Wallet review screen asking the learner to accept the incoming credential. + :width: 30% + .. image:: ../../_static/images/verifiable_credentials-lcw-credential-preview.png + :alt: Learner Credential Wallet credential detail screen previewing the stored credential contents. + :width: 30% + .. image:: ../../_static/images/verifiable_credentials-lcw-verification-status.png + :alt: Learner Credential Wallet status screen showing the stored credential as successfully verified. + :width: 30% + +#. From this point, learners are free to share their achievements in different + ways. + + .. image:: ../../_static/images/verifiable_credentials-lcw-share.png + :alt: Learner Credential Wallet sharing menu for a stored credential. + :width: 30% + .. image:: ../../_static/images/verifiable_credentials-lcw-share-public-link.png + :alt: Learner Credential Wallet public-link sharing screen for the selected credential. + :width: 30% + .. image:: ../../_static/images/verifiable_credentials-lcw-share-public-link-created.png + :alt: Wallet confirmation screen showing that a public sharing link has been created for the selected credential. + :width: 30% + +.. _vc-wallet-deeplink-protocol: + +Deeplink protocol +~~~~~~~~~~~~~~~~~ + +The LCWallet storage backend constructs deeplinks using the ``dccrequest://`` +scheme. The full deeplink format is: + +.. code-block:: text + + dccrequest://request?issuer={id}&vc_request_url={url}&auth_type=bearer&challenge={uuid}&vp_version=1.1 + +The end-to-end flow works as follows. + +#. The learner clicks :guilabel:`Create` in the Learner Record MFE. +#. The backend creates an ``IssuanceLine`` and returns a deeplink URL and + QR code. +#. The learner scans the QR code or clicks the deeplink, which opens the + wallet app. +#. The wallet constructs a Verifiable Presentation (VP) using the + ``challenge`` parameter as proof of authorization. +#. The wallet POSTs the VP to ``/credentials/issue//``. +#. The backend verifies the VP, signs the credential, and returns it to + the wallet. + +.. note:: + The issuance endpoint accepts dual authentication: standard JWT/Session + auth or a Verifiable Presentation with + ``proofPurpose: "authentication"`` and a ``challenge`` matching the + ``IssuanceLine.uuid``. The VP signature is verified via ``didkit``. + +Example verifiable presentation: + +.. code:: + + { + "@context": [ + "https://www.w3.org/2018/credentials/v1" + ], + "type": [ + "VerifiablePresentation" + ], + "verifiableCredential": [ + { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://w3id.org/security/suites/ed25519-2020/v1", + "https://w3id.org/vc/status-list/2021/v1", + "https://purl.imsglobal.org/spec/ob/v3p0/context.json" + ], + "id": "urn:uuid:7e33f82c-474b-4331-9cb7-71d2ace136e4", + "type": [ + "VerifiableCredential", + "OpenBadgeCredential" + ], + "credentialSubject": { + "id": "did:key:z6MkoXpRTvd9KhEdbjaieR2XCs6XewVyW32dyKjG1GoPGNww", + "name": "demo", + "achievement": { + "criteria": { + "narrative": "Demo successfully completed all courses and received passing grades for a Professional Certificate in dcc program a program offered by , in collaboration with Open edX." + }, + "description": "Program certificate is granted on program dcc program completion offered by , in collaboration with Open edX. The dcc program program includes 1 course(s).", + "id": "31187856-01ac-4abc-9b77-4add9cf7c50b", + "name": "Program certificate for passing a program dcc program", + "type": "Achievement" + }, + "type": "AchievementSubject" + }, + "issuer": { + "id": "did:key:z6MkkePoGJV8CQJJULSHHUEv71okD9PsrqXnZpNQuoUfb3id", + "type": "Profile", + "name": "Default verifiable credentials issuer" + }, + "issuanceDate": "2023-07-10T15:25:41Z", + "proof": { + "type": "Ed25519Signature2020", + "proofPurpose": "assertionMethod", + "proofValue": "z5HRVyz1ZHUY7f8m6ttUS7JViKqwhFBWt2caEnauEAKmWs69ud93ok6AMrmfjZe1bLdrLcPusVNtNXCzwHXLaFJmJ", + "verificationMethod": "did:key:z6MkkePoGJV8CQJJULSHHUEv71okD9PsrqXnZpNQuoUfb3id#z6MkkePoGJV8CQJJULSHHUEv71okD9PsrqXnZpNQuoUfb3id", + "created": "2023-07-10T15:25:41.581Z" + }, + "credentialStatus": { + "id": "https://credentials.example.com/verifiable_credentials/api/v1/status-list/2021/v1/did:key:z6MkkePoGJV8CQJJULSHHUEv71okD9PsrqXnZpNQuoUfb3id/#6", + "type": "StatusList2021Entry", + "statusPurpose": "revocation", + "statusListIndex": "6", + "statusListCredential": "https://credentials.example.com/verifiable_credentials/api/v1/status-list/2021/v1/did:key:z6MkkePoGJV8CQJJULSHHUEv71okD9PsrqXnZpNQuoUfb3id/" + }, + "name": "Program certificate for passing a program dcc program", + "issued": "2023-07-10T15:25:41Z", + "validFrom": "2023-07-10T15:25:41Z" + } + ] + } + +Development wallet +------------------ + +The `openedx-wallet`_ is a proof-of-concept wallet for debugging, investigation, and onboarding. It is not recommended for production deployment. + +.. _Official website: https://lcw.app/ +.. _Digital Credentials Consortium: https://digitalcredentials.mit.edu/ +.. _community issuer registry: https://github.com/digitalcredentials/community-registry +.. _`Sandbox Registry`: https://github.com/digitalcredentials/sandbox-registry +.. _openedx-wallet: https://github.com/raccoongang/openedx-wallet diff --git a/docs/sharing/verifiable_credentials/tech_details.rst b/docs/sharing/verifiable_credentials/tech_details.rst new file mode 100644 index 000000000..52b029dc0 --- /dev/null +++ b/docs/sharing/verifiable_credentials/tech_details.rst @@ -0,0 +1,90 @@ +.. _vc-tech-details: + +Implementation Details +====================== + +This section covers internal details that may help with debugging, +customization, or deeper understanding of the feature. + +Events flow +----------- + +The following diagram illustrates the end-to-end issuance sequence. + +.. figure:: ../../_static/images/verifiable_credentials-issuance-sequence.png + :alt: End-to-end verifiable credential issuance sequence, from the learner starting in Learner Record to the wallet requesting, receiving, and verifying the signed credential. + +- 1 - Learner navigates to the Learner Record MFE, enters the Verifiable Credentials page. +- 2,3 - Frontend fetches all Learner's credentials (program certificates). +- 4,5 - Frontend fetches configured storages list. +- Learner chooses their credential (program certificate) to issue verifiable credential for. +- 6,7 - Learner initiates an issuance (standard case: single storage, experimental case: many storages). +- 8 - Issuance Line is created with given context (storage + program certificate). +- 9 - all pre-requisites are evaluated and deep-link/QR code generated. +- Learner sees a modal dialog with deep-link/QR code to proceed with a mobile wallet app. +- 10,11 - Learner interacts with a dialog data (clicks/scans). +- 12 - Learner navigates to a mobile wallet app. +- 13 - mobile wallet app requests verifiable credential from an issuance API endpoint (on behalf of a Learner). +- verifiable_credentials application processes Issuance Line data (collects required data, composes it into a desired shape, evaluates status list data, adds signature). +- 14 - well-formed verifiable credential returned to a mobile wallet app. +- Mobile app verifies given verifiable credential (validates structure, signature, status info). + +Credential signing +------------------ + +All credentials are signed using the **Ed25519Signature2020** proof suite exclusively. + +VP authentication +----------------- + +The ``IssueCredentialView`` accepts dual authentication: standard JWT/Session auth **or** a Verifiable Presentation +with ``proofPurpose: "authentication"`` and a ``challenge`` matching the ``IssuanceLine.uuid``. The VP signature is +verified via ``didkit``. + +Signal-based status sync +------------------------ + +When a ``UserCredential`` status changes (e.g. revocation), all related ``IssuanceLine`` records are automatically +updated via a Django ``post_save`` signal. This ensures verifiable credentials reflect the current status of the +underlying Open edX achievement. In the case of revocation, the updated status is reflected in the issuer's +:ref:`Status List `, allowing relying parties to detect revoked credentials during +verification. + +Synchronous didkit operations +----------------------------- + +All ``didkit`` cryptographic operations are async functions wrapped with ``async_to_sync``. Each issuance blocks a +Django worker thread during signing. Consider this when sizing your deployment for high-volume issuance. + +Technology choices +------------------ + +openedx-didkit +~~~~~~~~~~~~~~ + +The cryptographic core is `openedx-didkit`_, a fork of the original `DidKit`_ library by SpruceID with added +Verifiable Credentials v2 support. It is Rust-based and integrated into Python via PyO3 bindings. + +.. _openedx-didkit: https://github.com/openedx/openedx-didkit +.. _DidKit: https://github.com/spruceid/didkit + +Status List 2021 +~~~~~~~~~~~~~~~~ + +Revocation tracking uses the `Status List 2021`_ specification - a simple bitstring where each issued +credential occupies one bit position. This approach was chosen over blockchain-based solutions for its +simplicity and because the status list is served as a standard API endpoint from the Credentials service +(see :ref:`vc-status-list-api`). + +.. _Status List 2021: https://www.w3.org/TR/2023/WD-vc-status-list-20230427/ + +OpenBadges v3.0 +~~~~~~~~~~~~~~~ + +The default data model is `Open Badges v3.0`_, a specification designed specifically for educational +achievements. It aligns with both VC Data Model v1.1 and v2.0, making credentials interoperable with +the broader verifiable credentials ecosystem while retaining education-specific semantics (achievements, +criteria, evidence). + +.. _Open Badges v3.0: https://www.imsglobal.org/spec/ob/v3p0/ + diff --git a/docs/verifiable_credentials/components.rst b/docs/verifiable_credentials/components.rst deleted file mode 100644 index 0fe40e16d..000000000 --- a/docs/verifiable_credentials/components.rst +++ /dev/null @@ -1,174 +0,0 @@ -Components -========== - -The Verifiable Credentials feature includes the following parts: - -- **Verifiable Credentials application** (`credentials.apps.verifiable_credentials` within the Open edX Credentials IDA); -- **Learner Record MFE** (`frontend-app-learner-record` micro-frontend); -- third-party plugins (see `Extensibility`_) -- digital wallets (see `Storages`_) - -Verifiable Credentials application ----------------------------------- - -The core backend logic and all related API are encapsulated in the `Verifiable Credentials application`_. - -Once the Verifiable Credentials feature `is enabled `__: - -1. Admin site "Verifiable Credentials" section becomes available in the Credentials IDA. -2. Extra urls become available in the Credentials IDA. -3. Extra API endpoints become available within the Credentials IDA. - -Administration site -~~~~~~~~~~~~~~~~~~~ - -Application section includes: - -- a list of available issuers -- a list of initiated issuance lines - -.. image:: ../_static/images/verifiable_credentials-admin-section.png - :alt: Admin section - -Currently, only a single Issuer configuration can be active in a moment of time: - -.. image:: ../_static/images/verifiable_credentials-issuer-configuration.png - :alt: Issuance Configurations - -Issuance configuration describes an Issuer - Organization/University/School on behalf of which verifiable credentials are created. Issuer's ID becomes a part of a verifiable credential and a cryptographic proof is generated with the help of Issuer's private key. Each Issuer has a verbose name. It can be deactivated (checkbox). - -.. note:: - Private key itself is a secret that is generated with the help of a cryptographic software. - Issuer ID must be a `decentralized identifier`_ created based on a private key. - -Issuance Line - Each request for a verifiable credential issuance initiates a separate Issuance Line. It tracks verifiable credential processing life cycle and keeps a connection with a source Open edX user achievement. - -.. image:: ../_static/images/verifiable_credentials-issuance-lines.png - :alt: Issuance Lines - -Issuance line has its unique identifier and additionally includes this information: - -1. **User Credential** - related Open edX achievement (e.g. "Program Certificate") -2. **Issuer ID** - issuer's which signs this verifiable credential -3. **Storage ID** - a storage backend (digital wallet) which will keep a verifiable credential -4. **Processing status** - if a verifiable credential was successfully uploaded to storage -5. **Status list info** - indicates if a verifiable credential still valid and unique status index within an Issuer's status list - -Learner Record Microfrontend ------------------------------ - -The Verifiable Credentials feature extends the `Learner Record MFE`_ with additional UI. An extra "Verifiable Credentials" page (tab) becomes available. - -.. image:: ../_static/images/verifiable_credentials-learner-record-mfe.png - :alt: Verifiable Credentials page - -1. Once the Verifiable Credentials feature `is enabled `__ tabs navigation appears -2. All learner's Open edX credentials are listed within the page -3. Achievement card has an action button that allows verifiable credential requesting based on the corresponding Open edX credential -4. Storages options (experimental) - -.. note:: - Currently, a single (built-in) storage backend is implemented out of the box (`Learner Credential Wallet`_). In this case the only storage option is available by default, so "Create" action button won't have a dropdown. Additional storages appear under the "Create with" dropdown automatically once configured. - -Status List API ---------------- - -There are a plenty of reasons verifiable credential may be already invalid, inactive or disposed: - -- revocation -- implicit expiration -- a lot of other purposes - -Open edX maintains status for internal credentials ("awarded", "revoked"). - -.. note:: - Once a Program Certificate X is revoked - **all** verifiable credentials which were issued based on that achievement must become revoked as well. - -Public Status List API allows instant verifiable credentials checks. Each issuer maintains its own statuses sequence. Every issued verifiable credential takes a unique position in that sequence. - -.. code-block:: sh - - # Status List API endpoint: - GET /verifiable_credentials/api/v1/status-list/2021/v1// - - # Example: - https://credentials.example.com/verifiable_credentials/api/v1/status-list/2021/v1/did:key:z6MkkePoGJV8CQJJULSHHUEv71okD9PsrqXnZpNQuoUfb3id/ - -A full set of status-related information is baked into a verifiable credential: - -- where to find status list API endpoint -- what's the exact status position in a sequence - -.. note:: - See Status List v2021 approach `Privacy Considerations`_ - -Status List example -~~~~~~~~~~~~~~~~~~~ - -Status List itself is a verifiable credential. But it serves a different purpose. - -.. code-block:: sh - - # specific Issuer's status list: - - { - "@context": [ - "https://www.w3.org/2018/credentials/v1", - "https://w3id.org/security/suites/ed25519-2020/v1", - "https://w3id.org/vc/status-list/2021/v1" - ], - "id": "https://credentials.example.com/verifiable_credentials/api/v1/status-list/2021/v1/did:key:z6MkkePoGJV8CQJJULSHHUEv71okD9PsrqXnZpNQuoUfb3id/", - "type": [ - "VerifiableCredential", - "StatusList2021Credential" - ], - "credentialSubject": { - "id": "https://credentials.example.com/verifiable_credentials/api/v1/status-list/2021/v1/did:key:z6MkkePoGJV8CQJJULSHHUEv71okD9PsrqXnZpNQuoUfb3id/#list", - "type": "StatusList2021", - "encodedList": "H4sIAJzSq2QC/+3BAQ0AAADCoPdPbQ43oAAAAAAAAAAAAODfAC7KO00QJwAA", - "statusPurpose": "revocation" - }, - "issuer": { - "id": "did:key:z6MkkePoGJV8CQJJULSHHUEv71okD9PsrqXnZpNQuoUfb3id" - }, - "issuanceDate": "2023-05-16T20:33:39Z", - "proof": { - "type": "Ed25519Signature2020", - "proofPurpose": "assertionMethod", - "proofValue": "z2qgpEUHecAxtRNuRXqPavaLwq2cfTzLSykFa8FPEVxvuPxBkfHdqo17XTpA2q9wR7CYwBjsfDBXT2amXAZbRqdPz", - "verificationMethod": "did:key:z6MkkePoGJV8CQJJULSHHUEv71okD9PsrqXnZpNQuoUfb3id#z6MkkePoGJV8CQJJULSHHUEv71okD9PsrqXnZpNQuoUfb3id", - "created": "2023-07-10T09:42:52.259Z" - }, - "issued": "2023-05-16T20:33:39Z", - "validFrom": "2023-05-16T20:33:39Z" - } - -Status Entry example -~~~~~~~~~~~~~~~~~~~~ - -Every verifiable credential carries its status list "registration" info. - -.. code-block:: sh - - # specific verifiable credential status section: - - "credentialStatus": { - "id": "https://credentials.example.com/verifiable_credentials/api/v1/status-list/2021/v1/did:key:z6MkkePoGJV8CQJJULSHHUEv71okD9PsrqXnZpNQuoUfb3id/#15", - "type": "StatusList2021Entry", - "statusListCredential": "https://credentials.example.com/verifiable_credentials/api/v1/status-list/2021/v1/did:key:z6MkkePoGJV8CQJJULSHHUEv71okD9PsrqXnZpNQuoUfb3id/", - "statusPurpose": "revocation", - "statusListIndex": "15" - }, - -Also see related `management command`_ - - -.. _Verifiable Credentials application: https://github.com/openedx/credentials/tree/master/credentials/apps/verifiable_credentials -.. _Learner Record MFE: https://github.com/openedx/frontend-app-learner-record -.. _Extensibility: extensibility.html -.. _decentralized identifier: https://en.wikipedia.org/wiki/Decentralized_identifier -.. _Learner Credential Wallet: https://lcw.app/ -.. _Privacy Considerations: https://w3c.github.io/vc-status-list-2021/#privacy-considerations -.. _management command: configuration.html#status-list-helper -.. _storages: storages.html \ No newline at end of file diff --git a/docs/verifiable_credentials/configuration.rst b/docs/verifiable_credentials/configuration.rst deleted file mode 100644 index 7f2c615a5..000000000 --- a/docs/verifiable_credentials/configuration.rst +++ /dev/null @@ -1,192 +0,0 @@ -Configuration -============= - -Verifiable Credentials feature is optional. It is disabled by default. - -Learner Record micro-frontend ------------------------------ - -The most of configuration is related to the Credentials IDA (`verifiable_credentials` app), but there are few UI-related settings. - -``ENABLE_VERIFIABLE_CREDENTIALS`` (boolean) - enables feature appearance (extra routes) - -``SUPPORT_URL_VERIFIABLE_CREDENTIALS`` (URL string) - footer support link - -Verifiable Credentials application ----------------------------------- - -``ENABLE_VERIFIABLE_CREDENTIALS`` (boolean) - main feature flag - -The feature introduces its own set of default settings which are namespaced in the VERIFIABLE_CREDENTIALS setting, like this: - -.. code-block:: python - - VERIFIABLE_CREDENTIALS = { - 'DEFAULT_DATA_MODELS': [ - "credentials.apps.verifiable_credentials.composition.open_badges.OpenBadgesDataModel", - ], - "STATUS_LIST_LENGTH": 50000, - "DEFAULT_ISSUER": { - "NAME": "The University of the Digital Future", - "KEY": '{"kty":"OKP","crv":"Ed25519","x":"IGUT8E_aRNzLqouWO4zdeZ6l4CEXsVmJDOpOQS69m7o","d":"vn8xgdO5Ki3zlvRNc2nUqcj50Ise1Vl1tlbs9DUL-hg"}', - "ID": "did:key:z6MkgdiV7pVPCapM8oUwfhxBwYZgh8dXkHkJykSAc4DHKD7X", - }, - } - -Such configuration overrides the corresponding built-in settings: - -1. Data models list narrowed down to a single specification -2. Status list length extended to 50K positions -3. Default issuer configured with concrete credentials - -Built-in values ---------------- - -There is a set of built-in predefined settings: - -.. code-block:: python - - # verifiable_credentials/settings.py - - DEFAULTS = { - "DEFAULT_DATA_MODELS": [ - "credentials.apps.verifiable_credentials.composition.verifiable_credentials.VerifiableCredentialsDataModel", - "credentials.apps.verifiable_credentials.composition.open_badges.OpenBadgesDataModel", - ], - "DEFAULT_STORAGES": [ - "credentials.apps.verifiable_credentials.storages.learner_credential_wallet.LCWallet", - ], - "DEFAULT_ISSUER": { - "ID": "generate-me-with-didkit-lib", - "KEY": "generate-me-with-didkit-lib", - "NAME": "Default (system-wide)", - }, - "DEFAULT_ISSUANCE_REQUEST_SERIALIZER": "credentials.apps.verifiable_credentials.issuance.serializers.IssuanceLineSerializer", - "DEFAULT_RENDERER": "credentials.apps.verifiable_credentials.issuance.renderers.JSONLDRenderer", - "STATUS_LIST_STORAGE": "credentials.apps.verifiable_credentials.storages.status_list.StatusList2021", - "STATUS_LIST_DATA_MODEL": "credentials.apps.verifiable_credentials.composition.status_list.StatusListDataModel", - "STATUS_LIST_LENGTH": 10000, - } - -Default data models -------------------- - -Deployment configuration can override `data models set`_ with the respect of the following restrictions: - -- there always must be at least 1 data model available -- each storage is pre-configured to use some data model which must be available - -Default storages ----------------- - -Deployment configuration can override `storages set`_ with the respect of the following restrictions: - -- there always must be at least 1 storage available - - -Default issuer --------------- - -.. note:: - Currently, there is only a single active issuer (system-wide) available So, all verifiable credentials are created (issued) on behalf of this Issuer. - -There is the `Issuance Configuration`_ database model, which initial record is created based on these settings. - -NAME -~~~~ - -Verbose issuer name (it is placed into each verifiable credential). - -KEY -~~~ - -A private secret key (JWK) which is used for verifiable credentials issuance (proof/digital signature generation). It can be generated with the help of the `didkit`_ Python (Rust) library. - -ID -~~ - -A unique issuer decentralized identifier (created from a private key, `example`_). - -Status List configuration -------------------------- - -Length -~~~~~~ - -``STATUS_LIST_LENGTH`` - default = 10000 (16KB) - -Possibly, the only status list settings to configure. A status sequence positions count (how many issued verifiable credentials statuses are included). See `related specs`_ for details. - -Storage -~~~~~~~ - -``STATUS_LIST_STORAGE`` - -A technical storage class (allows status list implementation override). - -Data model -~~~~~~~~~~ - -``STATUS_LIST_DATA_MODEL`` - -A data model class (allows status list implementation override). - ----- - -Other settings are available for advanced tweaks but usually are not meant to be configured: - -- Default issuance request serializer (incoming issuance request parsing) -- Default renderer (outgoing verifiable credential presentation) - -Management commands -------------------- - -There are a couple of service commands available for the verifiable_credentials application. - -Issuer credentials helper -~~~~~~~~~~~~~~~~~~~~~~~~~ - -**Generates private key for Issuer (JWK) and a decentralized identifier (DID) based on that key.** - -.. code-block:: sh - - root@credentials:/edx/app/credentials/credentials# ./manage.py generate_issuer_credentials - >> {'did': 'did:key:z6MkgdiV7pVPCapM8oUwfhxBwYZgh8dXkHkJykSAc4DHKD7X', - 'private_key': '{"kty":"OKP","crv":"Ed25519","x":"IGUT8E_aRNzLqouWO4zdeZ6l4CEXsVmJDOpOQS69m7o","d":"vn8xgdO5Ki3zlvRNc2nUqcj50Ise1Vl1tlbs9DUL-hg"}'} - -Issuer configuration helpers -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -**Create initial Issuance Configuration based on deployment issuer(s) setup.** - -.. code-block:: sh - - root@credentials:/edx/app/credentials/credentials# ./manage.py create_default_issuer - -Initial Issuance configuration is created based on VERIFIABLE_CREDENTIALS[DEFAULT_ISSUER] via data migration during the first deployment. Helper allows manually repeat that is needed (Additional configurations can be created from django admin interface). - -**Remove Issuance Configuration based on Issuer ID.** - -.. code-block:: sh - - root@credentials:/edx/app/credentials/credentials# ./manage.py remove_issuance_configuration did:key:z6MkgdiV7pVPCapM8oUwfhxBwYZgh8dXkHkJykSAc4DHKD7X - -Issuance configuration delete operation is forbidden in admin interface (only deactivation is available). This tool allows to cleanup configurations list if needed. - -Status List helper -~~~~~~~~~~~~~~~~~~ - -**Generate Status List 2021 verifiable credential** - -.. code-block:: sh - - root@credentials:/edx/app/credentials/credentials# ./manage.py generate_status_list did:key:z6MkgdiV7pVPCapM8oUwfhxBwYZgh8dXkHkJykSAc4DHKD7X - -Allows Status List verifiable credential generation (for a given Issuer ID). - -.. _data models set: extensibility.html#data-models -.. _storages set: extensibility.html#storages -.. _didkit: https://pypi.org/project/didkit/ -.. _example: https://github.com/spruceid/didkit-python/blob/main/examples/python_django/didkit_django/issue_credential.py#L12 -.. _related specs : https://w3c.github.io/vc-status-list-2021/#revocation-bitstring-length -.. _Issuance Configuration: components.html#administration-site \ No newline at end of file diff --git a/docs/verifiable_credentials/extensibility.rst b/docs/verifiable_credentials/extensibility.rst deleted file mode 100644 index 9c1c2dc96..000000000 --- a/docs/verifiable_credentials/extensibility.rst +++ /dev/null @@ -1,64 +0,0 @@ -Extensibility -============= - -Storages --------- - -Storage backend classes describe a destination for issued verifiable credentials. Basically, storages are wallets (mobile or web applications). - -See available options on `Storages page`_. - -Data Models ------------ - -Data model classes are `DRF`_ serializers which compose verifiable credentials of different specifications. - -Credentials data models -~~~~~~~~~~~~~~~~~~~~~~~ - -There are 2 specifications included by default: - -- `Open Badges Specification v3.0`_ (see `OB3.0 model`_) -- `Verifiable Credentials Data Model v1.1`_ (see `VC1.1 model`_) - experimental - -Additional specifications may be implemented as separate `plugins`_. - -Credentials status information -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. note:: - - Status information allows instant checks to figure out if the presented verifiable credential is still valid. The credential issuer can invalidate a verifiable credential by updating its indexed record in the status list. - -`Status List v2021`_ is a special kind of verifiable credential. It serves as a mechanism of verification for issued verifiable credentials (meaning, it does not carry achievement information itself but it is a registry of statuses for all created achievement-related verifiable credentials). - -- `Verifiable Credential Status List v2021`_ - -There are 2 parts of the approach: - -- status entry (becomes a part of each issued verifiable credential and carries the info "how to check status") -- status list (an Issuer-centric separate freely reachable statuses registry) - -Plugins -------- - -Both `data models`_ and `storages`_ may be implemented as Credentials IDA installable pluggable applications. - -.. note:: - - For storage plugin example, please, see the `openedx-wallet`_ training storage (by the `Raccoon Gang`_) . - -.. _Verifiable Credentials Data Model v1.1: https://www.w3.org/TR/vc-data-model-1.1/ -.. _Open Badges Specification v3.0: https://1edtech.github.io/openbadges-specification/ob_v3p0.html -.. _Verifiable Credential Status List v2021: https://w3c.github.io/vc-status-list-2021/ -.. _data models: extensibility.html#data-models -.. _storages: extensibility.html#storages -.. _storages page: storages.html -.. _plugins: extensibility.html#plugins -.. _Raccoon Gang : https://raccoongang.com -.. _Learner Credential Wallet: https://lcw.app -.. _DRF: https://www.django-rest-framework.org/ -.. _Status List v2021: components.html#status-list-api -.. _VC1.1 model: https://github.com/openedx/credentials/tree/master/credentials/apps/verifiable_credentials/composition/verifiable_credentials.py -.. _OB3.0 model: https://github.com/openedx/credentials/tree/master/credentials/apps/verifiable_credentials/composition/open_badges.py -.. _openedx-wallet: https://github.com/raccoongang/openedx-wallet \ No newline at end of file diff --git a/docs/verifiable_credentials/overview.rst b/docs/verifiable_credentials/overview.rst deleted file mode 100644 index b13182be8..000000000 --- a/docs/verifiable_credentials/overview.rst +++ /dev/null @@ -1,27 +0,0 @@ -Verifiable Credentials -====================== - -An optional feature that allows issuance of the `Verifiable Credentials`_ based on the Open edX achievements. - - *Verifiable credentials will allows us to represent our achievements in a provable, portable, sharable, privacy and autonomy preserving way.* - -Please, see `Extensibility`_ section for the list of supported: - -- verifiable credential specifications (data models) -- digital wallets (storages) - ----- - -.. toctree:: - :maxdepth: 1 - - quickstart - usage - components - configuration - extensibility - storages - tech_details - -.. _Verifiable Credentials: https://en.wikipedia.org/wiki/Verifiable_credentials -.. _Extensibility: extensibility.html \ No newline at end of file diff --git a/docs/verifiable_credentials/quickstart.rst b/docs/verifiable_credentials/quickstart.rst deleted file mode 100644 index 0755e9e53..000000000 --- a/docs/verifiable_credentials/quickstart.rst +++ /dev/null @@ -1,87 +0,0 @@ -Quick Start -=================================== - -.. contents:: Steps - :local: - :class: no-bullets - -This guide outlines initial preparations for the Verifiable Credentials feature. - -1. Feature activation ---------------------- - -Since Verifiable Credentials feature is optional, it must be enabled to be accessible. - -.. code:: - - # both Credentials service and Learner Record MFE: - ENABLE_VERIFIABLE_CREDENTIALS = true - -See Configuration_ for more details. - -2. Issuer credentials generation --------------------------------- - -Once enabled Verifiable Credentials feature has reasonable defaults. The only additional activity is needed - issuer_ credentials setup. Unless we already have appropriate issuer key and issuer ID, we have to generate those: - -.. code:: - - # use management command: - root@credentials:/edx/app/credentials/credentials# ./manage.py generate_issuer_credentials - >> { - 'did': 'did:key:z6MkgdiV7pVPCapM8oUwfhxBwYZgh8dXkHkJykSAc4DHKD7X', - 'private_key': '{"kty":"OKP","crv":"Ed25519","x":"IGUT8E_aRNzLqouWO4zdeZ6l4CEXsVmJDOpOQS69m7o","d":"vn8xgdO5Ki3zlvRNc2nUqcj50Ise1Vl1tlbs9DUL"}' - } - -Here: - - - "did" - unique Issuer decentralized identifier - - "private_key" - Issuer private JWK - -See `Management commands`_ for more details. - -3. Issuer credentials setup ---------------------------- - -Generated issuer credentials we'll use to update automatically generated with stub values Issuance Configuration. - -Enter Credentials Administration interface and find "VERIFIABLE CREDENTIALS" section (`/admin/verifiable_credentials/issuanceconfiguration/`). - -.. code:: - - Issuer id: use "did" - Issuer key: use "private_key" - Issuer name: will be used as issuer's verbose name - -.. note:: - :class: dropdown - - Make sure the configuration is enabled. - -See `Administration site`_ for more details. - -4. Ensure status list is accessible ------------------------------------ - -Status List API endpoint is crucial for the feature. Once everything is configured correctly it must be publicly available: - -.. code:: - - # each Issuer maintains its own Status List: - https://credentials.example.com/verifiable_credentials/api/v1/status-list/2021/v1// - -See `Status List API`_ for more details. - -5. Issuer registration (Learner Credential Wallet) --------------------------------------------------- - -This step is specific for the Learner Credential Wallet storage. - -See Learner Credential Wallet `usage prerequisites`_. - -.. _issuer: https://www.w3.org/TR/vc-data-model-1.1/#dfn-issuers -.. _configuration: configuration.html#configuration -.. _management commands: configuration.html#management-commands -.. _administration site: components.html#administration-site -.. _status list API: components.html#status-list-api -.. _usage prerequisites: storages.html#usage-prerequisites \ No newline at end of file diff --git a/docs/verifiable_credentials/storages.rst b/docs/verifiable_credentials/storages.rst deleted file mode 100644 index 83f202b5d..000000000 --- a/docs/verifiable_credentials/storages.rst +++ /dev/null @@ -1,155 +0,0 @@ -Storages -======== - -Currently there is the only digital wallet is supported for production. - -Learner Credential Wallet -------------------------- - -`Official web-site`_: - - Learner Credential Wallet is an open source mobile wallet developed by the Digital Credentials Consortium, a network of leading international universities designing an open infrastructure for academic credentials. - -Learner Credential Wallet (LCWallet) is a mobile app available for Android and IOS devices. - -Usage prerequisites -~~~~~~~~~~~~~~~~~~~ - -LCWallet maintainer (`Digital Credentials Consortium`_) requires verifiable credentials issuer to be allow-listed (included to the trusted issuers list - `community issuer registry`_). - -.. note:: - - For development/testing purposes a `Sandbox Registry`_ is available. If you would like to be added to the Sandbox Registry, please open a pull requests directly against that repository, matching the format for existing issuers in `registry.json` - -Learner experience -~~~~~~~~~~~~~~~~~~ - -This explains a generic usage flow for learners. - -#. Learners have to download and install the official application (Google Play or App Store, we'll use Android version for examples). - -#. Once installed there is initial one-time setup guide. - - .. image:: ../_static/images/verifiable_credentials-lcw-setup1.png - :alt: Learner Credential Wallet setup step 1 - :width: 30% - .. image:: ../_static/images/verifiable_credentials-lcw-setup2.png - :alt: Learner Credential Wallet setup step 2 - :width: 30% - .. image:: ../_static/images/verifiable_credentials-lcw-setup3.png - :alt: Learner Credential Wallet setup step 3 - :width: 30% - -#. Learners navigate Learner Record MFE interface (`Verifiable Credentials tab`_) and claim for a verifiable credential issuance (clicking a :guilabel:`Create` button). - -#. On the next step learners are asked for QR code scanning - that's where the LCWallet app starts its flow. Learners use :guilabel:`Scan QR code` option in the mobile application. - - .. image:: ../_static/images/verifiable_credentials-lcw-home-empty.png - :alt: Learner Credential Wallet empty - :width: 30% - .. image:: ../_static/images/verifiable_credentials-lcw-add-credential.png - :alt: Learner Credential Wallet add credential - :width: 30% - .. image:: ../_static/images/verifiable_credentials-lcw-qrcode-scanner.png - :alt: Learner Credential Wallet QR code scanner - :width: 30% - -#. LCWallet processes QR code, communicates with the Open edX Platform and gets new verifiable credential. If everything is correct, now digital wallet holds the verifiable credential for the given Open edX credential (program certificate). - - .. image:: ../_static/images/verifiable_credentials-lcw-accept-credential.png - :alt: Learner Credential Wallet accept credential - :width: 30% - .. image:: ../_static/images/verifiable_credentials-lcw-credential-preview.png - :alt: Learner Credential Wallet credential preview - :width: 30% - .. image:: ../_static/images/verifiable_credentials-lcw-verification-status.png - :alt: Learner Credential Wallet credential status - :width: 30% - -#. From this point learners are free to share their achievements in different ways - - .. image:: ../_static/images/verifiable_credentials-lcw-share.png - :alt: Learner Credential Wallet share credential - :width: 30% - .. image:: ../_static/images/verifiable_credentials-lcw-share-public-link.png - :alt: Learner Credential Wallet share credential with public link - :width: 30% - .. image:: ../_static/images/verifiable_credentials-lcw-share-public-link-created.png - :alt: Learner Credential Wallet shared with public link credential - :width: 30% - -.. code:: - - # an example of a verifiable presentation being shared: - { - "@context": [ - "https://www.w3.org/2018/credentials/v1" - ], - "type": [ - "VerifiablePresentation" - ], - "verifiableCredential": [ - { - "@context": [ - "https://www.w3.org/2018/credentials/v1", - "https://w3id.org/security/suites/ed25519-2020/v1", - "https://w3id.org/vc/status-list/2021/v1", - "https://purl.imsglobal.org/spec/ob/v3p0/context.json" - ], - "id": "urn:uuid:7e33f82c-474b-4331-9cb7-71d2ace136e4", - "type": [ - "VerifiableCredential", - "OpenBadgeCredential" - ], - "credentialSubject": { - "id": "did:key:z6MkoXpRTvd9KhEdbjaieR2XCs6XewVyW32dyKjG1GoPGNww", - "name": "demo", - "achievement": { - "criteria": { - "narrative": "Demo successfully completed all courses and received passing grades for a Professional Certificate in dcc program a program offered by , in collaboration with Open edX." - }, - "description": "Program certificate is granted on program dcc program completion offered by , in collaboration with Open edX. The dcc program program includes 1 course(s).", - "id": "31187856-01ac-4abc-9b77-4add9cf7c50b", - "name": "Program certificate for passing a program dcc program", - "type": "Achievement" - }, - "type": "AchievementSubject" - }, - "issuer": { - "id": "did:key:z6MkkePoGJV8CQJJULSHHUEv71okD9PsrqXnZpNQuoUfb3id", - "type": "Profile", - "name": "Default verifiable credentials issuer" - }, - "issuanceDate": "2023-07-10T15:25:41Z", - "proof": { - "type": "Ed25519Signature2020", - "proofPurpose": "assertionMethod", - "proofValue": "z5HRVyz1ZHUY7f8m6ttUS7JViKqwhFBWt2caEnauEAKmWs69ud93ok6AMrmfjZe1bLdrLcPusVNtNXCzwHXLaFJmJ", - "verificationMethod": "did:key:z6MkkePoGJV8CQJJULSHHUEv71okD9PsrqXnZpNQuoUfb3id#z6MkkePoGJV8CQJJULSHHUEv71okD9PsrqXnZpNQuoUfb3id", - "created": "2023-07-10T15:25:41.581Z" - }, - "credentialStatus": { - "id": "https://credentials.example.com/verifiable_credentials/api/v1/status-list/2021/v1/did:key:z6MkkePoGJV8CQJJULSHHUEv71okD9PsrqXnZpNQuoUfb3id/#6", - "type": "StatusList2021Entry", - "statusPurpose": "revocation", - "statusListIndex": "6", - "statusListCredential": "https://credentials.example.com/verifiable_credentials/api/v1/status-list/2021/v1/did:key:z6MkkePoGJV8CQJJULSHHUEv71okD9PsrqXnZpNQuoUfb3id/" - }, - "name": "Program certificate for passing a program dcc program", - "issued": "2023-07-10T15:25:41Z", - "validFrom": "2023-07-10T15:25:41Z" - } - ] - } - -Other options -------------- - -Additionally, you can install the `openedx-wallet`_ POC for investigation/onboarding purposes. This wallet is not recommended for production deployment. - -.. _Official web-site: https://lcw.app/ -.. _Digital Credentials Consortium: https://digitalcredentials.mit.edu/ -.. _community issuer registry: https://github.com/digitalcredentials/community-registry -.. _`Sandbox Registry`: https://github.com/digitalcredentials/sandbox-registry -.. _`Verifiable Credentials tab`: components.html#learner-record-microfrontend -.. _openedx-wallet: https://github.com/raccoongang/openedx-wallet \ No newline at end of file diff --git a/docs/verifiable_credentials/tech_details.rst b/docs/verifiable_credentials/tech_details.rst deleted file mode 100644 index 1dab77d6a..000000000 --- a/docs/verifiable_credentials/tech_details.rst +++ /dev/null @@ -1,57 +0,0 @@ -Implementation Details -====================== - -The following may clarify implicit internal details. - -Prerequisites -------------- - -Required initial activities. - -1. Before the main feature flag (settings) is enabled the verifiable_credentials app won't register its urlconf, admin. -2. Default built-in configuration is almost self-contained - the only required step is to configure Issuer's credentials (see `management command helper`_). If Issuer is configured in deployment environment from the start, those settings are used during the app data migration, otherwise manual Issuance Configuration edit is needed (Credentials admin site). -3. There can be a list of Issuance Configuration records, but only the last enabled is taken into account in current implementation. - -Events flow ------------ - -Here is how everything happens. - -.. image:: ../_static/images/verifiable_credentials-issuance-sequence.png - :alt: Verifiable Credentials issuance sequence diagram - -- 1 - Learner navigates to the Learner Record MFE, enters the Verifiable Credentials page. -- 2,3 - Frontend fetches all Learner's credentials (program certificates). -- 4,5 - Frontend fetches configured storages list. -- Learner chooses theirs credential (program certificate) to issue verifiable credential for. -- 6,7 - Learner initiates an issuance (standard case: single storage, experimental case: many storages). -- 8 - Issuance Line is created with given context (storage + program certificate). -- 9 - all pre-requisites are evaluated and deep-link/QR-code generated. -- Learner is present modal dialog with deep-link/QR-code to proceed with a mobile wallet app. -- 10,11 - Learner interacts with a dialog data (clicks/scans). -- 12 - Learner navigates to a mobile wallet app. -- 13 - mobile wallet app requests verifiable credential from an issuance API endpoint (on behalf of a Learner). -- verifiable_credentials application processes Issuance Line data (collects required data, composes it into a desired shape, evaluates status list data, adds signature). -- 14 - well-formed verifiable credential returned to a mobile wallet app. -- Mobile app verifies given verifiable credential (validates structure, signature, status info). - -New dependencies ----------------- - -Verifiable Credentials feature has introduced a couple of extra packages. - -didkit-python -~~~~~~~~~~~~~ - -``didkit==0.3.2`` - -A tool for verifiable credentials operations (issuance, verification, signing, validation). - -qrcode -~~~~~~ - -``qrcode==7.4.2`` - -We generate mobile deep-link QR-codes on a backend. - -.. _management command helper: configuration.html#issuer-credentials-helper diff --git a/docs/verifiable_credentials/usage.rst b/docs/verifiable_credentials/usage.rst deleted file mode 100644 index bc194262c..000000000 --- a/docs/verifiable_credentials/usage.rst +++ /dev/null @@ -1,61 +0,0 @@ -Usage -===== - -The Open edX platform allows students to earn credentials (e.g. course certificates, program certificates). Based on such credentials learners are able to create a digital cryptographically proven piece of data - a verifiable credential. - -.. note:: - Verifiable credentials are intended for machines. - -A single Open edX achievement can be used as a source for numerous verifiable credentials (identical or different data models). - -Verifiable credential includes data about: - -- who has achieved it (subject) - - student's unique decentralized identifier (DID); - - student's arbitrary personal data (optional); -- what exactly was achieved (credential) - - type (program or course certificate); - - title (program or course name, possibly courses list); -- when it happened (timestamp) - - date and time verifiable credential was created (issued); - - expiration moment (optionally); -- who proves it (issuer) - - there is always at least one issuer - organization/university/etc. who "confirms" credential's data is the Truth; -- how to check if it is still valid (status) - - there are different status check methods; - - there are different reasons for status update (source achievement revocation, for example); - -**All that data is signed, so it can't be tampered in any way - that's the point.** - -Learners --------- - -The general usage flow is the following: - -- **Student** finishes a course/program and **earns an achievement/credential** (e.g. Program Certificate X); -- **Student requests a verifiable credential** that confirms Program Certificate X exists (additional background can be included as well - e.g. average/total grade, etc.); -- The **Open edX platform creates (issues)** a verifiable credential on behalf of related Issuer (Organization/University/School); -- **Verifiable credential is uploaded** to some Learner's storage (verifiable credentials wallet, a mobile/web app); -- **Student presents** a verifiable credential to any Interested Party (another Org/University/School); -- **Interested Party verifies** a verifiable credential's status - checks if it wasn't tampered in any way; checks if it still has valid status (not expired, not revoked); - -.. note:: - Please, see the `Learner Record micro-frontend`_ for details. - -Administrators --------------- - -The Open edX users with administrator rights are able to manage/monitor the Verifiable Credentials application within the Credentials IDA admin site. - -.. note:: - Please, see the `Verifiable Credentials application`_ for details. - -Relying Parties ---------------- - -Third-parties whom a verifiable credential is presented want to ensure the current status of such artifact. That's where the `Status List`_ mechanism comes into play. - - -.. _Learner Record micro-frontend: components.html#learner-record-microfrontend -.. _Verifiable Credentials application: components.html#verifiable-credentials-application -.. _Status List: components.html#status-list-api \ No newline at end of file